c# - How to make my constructor async in UWP MVVM model? (MVVM Lighttoolkit) -
i have uwp project want reads storagefolder videoslibrary , show list of mp4 files @ views thumbnail.
with mvvm ligth toolkit have setup 4 flies xaml. xaml using uwp community toolkit wrap panel.
1)viewmodellocator.cs
namespace uwp.viewmodels { /// <summary> /// class contains static reference view models in /// application , provides entry point bindings. /// </summary> class viewmodellocator { /// <summary> /// initializes new instance of viewmodellocator class. /// </summary> public viewmodellocator() { servicelocator.setlocatorprovider(() => simpleioc.default); if (viewmodelbase.isindesignmodestatic) { // create design time view services , models } else { // create run time view services , models } //register services used here simpleioc.default.register<videolistmodel>(); } public videolistmodel videolistmodel { { return servicelocator.current.getinstance<videolistmodel>(); } } }
2) videolistitem.cs
namespace uwp.models { class videolistitem : viewmodelbase { public string videoname { get; set; } public string author { get; set; } public uri vid_url { get; set; } public bitmapimage image { get; set; } public videolistitem(string videoname,string author,uri url, bitmapimage img) { this.videoname = videoname; this.author = author; this.vid_url = url; this.image = img; } } }
3) videolistmodel.cs
namespace uwp.viewmodels { class videolistmodel : viewmodelbase { public observablecollection<videolistitem> videoitems { get; set; } private videolistitem videoitems; public videolistmodel() { } public async static task<list<videolistitem>> getvideoitem() { list<videolistitem> videoitems = new list<videolistitem>(); storagefolder videos_folder = await knownfolders.videoslibrary.createfolderasync("videos"); var queryoptions = new queryoptions(commonfilequery.defaultquery, new[] { ".mp4" }); var videos = await videos_folder.createfilequerywithoptions(queryoptions).getfilesasync(); foreach (var video in videos) { //debug.writeline(video.name); //videoitems.add(new videolistitem()); var bitmap = new bitmapimage(); var thumbnail = await video.getthumbnailasync(thumbnailmode.singleitem); await bitmap.setsourceasync(thumbnail); videoitems.add(new videolistitem(video.displayname, "", new uri(video.path),bitmap)); } //foreach(var video in videoitems) //{ // debug.writeline("name:{0} , author:{1}, uri:{2}, bitmap:{3}", video.videoname, video.author, video.vid_url, video.image.urisource); //} return videoitems; } } }
4) video.xaml
<page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:uwp.views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:microsoft.toolkit.uwp.ui.controls" x:class="uwp.views.video" mc:ignorable="d" navigationcachemode="enabled" datacontext="{binding source={staticresource viewmodellocator},path=videolistmodel}"> <!--navigationcachemode enable page state save--> <page.resources> <datatemplate x:key="videotemplate"> <grid width="{binding width}" height="{binding height}" margin="2"> <image horizontalalignment="center" stretch="uniformtofill" source="{binding image}" /> <textblock text="{binding videoname}"/> <stackpanel orientation="horizontal"> <textblock text="author" /> <textblock text="{binding author}" /> </stackpanel> </grid> </datatemplate> </page.resources> <grid background="{themeresource applicationpagebackgroundthemebrush}"> <listview name="videoslistwrappanal" itemtemplate="{staticresource videotemplate}"> <itemscontrol.itemspanel> <itemspaneltemplate> <controls:wrappanel /> </itemspaneltemplate> </itemscontrol.itemspanel> </listview> </grid> </page>
i wanted below in videolistmodel constructor.
public async mainviewmodel() { videoitems = new observablecollection<mainmenuitem>(await getvideoitem()); }
how can accomplish initialization in asynchronous way? thumbnail have created method of getvideoitem(), can't find way call getvideoitem asynchronously in constructor. know how solve task?
i recommend using asynchronous task notifier, described in article on async mvvm data binding.
e.g., using notifytask
this helper library:
public notifytask<list<videolistitem>> videoitems { get; } public videolistmodel(iknownfolderreader knownfolder) { _knownfolder = knownfolder; videoitems = notifytask.create(() => _knownfolder.getdata()); }
your data binding change itemssource="{binding videoitems}"
itemssource="{binding videoitems.result}"
. in addition, videoitems
has several other properties such isnotcompleted
, isfaulted
data binding can show/hide elements based on state of task.
this approach avoids subtle problems result
, problems continuewith
.
Comments
Post a Comment