我有一个想要读取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,因此您的数据绑定可以根据任务的状态显示/隐藏元素.