c# – 如何在UWP MVVM模型中使我的构造函数异步? (MVVM Lighttoolkit)

我有一个想要读取StorageFolder VideosLibrary的UWP项目,并在带缩略图的Views中显示mp4文件列表.

使用MVVM ligth工具包,我已经使用xaml设置了这4只苍蝇.
Xaml正在使用UWP社区工具箱包装面板.

1)viewmodelLocator.cs

namespace UWP.viewmodels
{
/// <summary>
/// This class contains static reference to all the view models in the 
/// application and provides an entry point for the bindings.
/// </summary>

class viewmodelLocator
{
    /// <summary>
    /// Initializes a new instance of the viewmodelLocator class.
    /// </summary>
    public viewmodelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        if (viewmodelBase.IsInDesignModeStatic)
        {
            // Create  design time view services and models
        }
        else
        {
            // Create run Time view services and models
        }
        //Register services used here

        SimpleIoc.Default.Register<VideoListModel>();
    }


    public VideoListModel VideoListModel
    {
        get { 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 for the 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>

我想在我的VideoListModel中为构造函数执行类似下面的操作.

public async Mainviewmodel()
{
   VideoItems = new ObservableCollection<MainMenuItem>(await GetVideoItem());

}

如何以异步方式完成此初始化?
为了获得缩略图,我创建了GetVideoItem()的方法,
但我找不到在构造函数中异步调用GetVideoItem的方法.
有谁知道如何解决这个任务?

解决方法

我建议使用异步任务通知程序,如我在 async MVVM data binding上的文章中所述.

例如,使用this helper library的NotifyTask:

public NotifyTask<List<VideoListItem>> VideoItems { get; }

public VideoListModel(IKNownFolderReader kNownFolder)
{
  _kNownFolder = kNownFolder;
  VideoItems = NotifyTask.Create(() => _kNownFolder.GetData());
}

然后,您的数据绑定将从ItemsSource =“{Binding VideoItems}”更改为ItemsSource =“{Binding VideoItems.Result}”.此外,VideoItems还有其他几个属性,如IsNotCompleted和IsFaulted,因此您的数据绑定可以根据任务的状态显示/隐藏元素.

这种方法避免了细微的problems with Resultproblems with ContinueWith.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...