好的我会尝试一步一步地解释我的问题以及代码
当我只是简单地将新项目添加到我的可观察集合中时,这些文件的名称没有获取缩略图并且放置一个简单的图片而不是来自资产的缩略图,那么它就像它应该的那样工作,但我得到资产pic而不是我的缩略图。请帮忙,下面是我的代码生病评论它解释得更好。提前谢谢..
//this is the xaml code of the gridview.
<GridView ItemsSource="{x:Bind VideoGridItems}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:VideoGridItem">
<StackPanel>
<Image Source="{x:Bind i}" Width="190" Height="130"/>
<TextBlock Text="{x:Bind Name}" FontSize="24"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
//这是我在xaml.cs文件背后的全部代码
public sealed partial class HistoryV : Page
{
public HistoryV()
{
this.InitializeComponent();
VideoGridItems = new ObservableCollection<VideoGridItem>();
LoadHistory();
}
public ObservableCollection<VideoGridItem> VideoGridItems { get; set; }
private async void LoadHistory()
{
var files = new List<StorageFile>();
var TextFile = await Current.LocalFolder.CreateFileAsync("VideoHistory.txt", CreationCollisionOption.OpenIfExists);
var Lines = await FileIO.ReadLinesAsync(TextFile);
int i = Lines.Count - 1;
for (; i>-1; i--)
{
files.Add(await StorageApplicationPermissions.FutureAccessList.GetFileAsync(Lines[i]));
}
//I simply take each file and add new items with its name and
asset picture as image on gridview, this method works, but not what I want
foreach (var item in files)
{
VideoGridItems.Add(new VideoGridItem { Name = item.DisplayName, i = new BitmapImage(new Uri("ms-appx:///Assets//StoreLogo.png")) });
}
//below the is code line i have commented because it is not working
this is the actual method which should work.
//VideoGridItems = await GetVideoItems(files);
}
}
下面是我用GetVideoItems方法创建的两个类,以便获得可以绑定到gridview的ObservableCollection
public class VideoGridItem
{
public BitmapImage i { get; set; }
public string Name { get; set; }
}
class VideoGridItemManager
{
public static async Task<ObservableCollection<VideoGridItem>> GetVideoItems(List<StorageFile> files)
{
var newlist = new ObservableCollection<VideoGridItem>();
foreach (var file in files)
{
var b = new BitmapImage();
var thumb =await GetThumbnail(file);
if (thumb == null) { b = new BitmapImage(new Uri("ms-appx:///Assets//Square150x150Logo.scale-200.png")); }
else
{
if (thumb.ContentType == "image/bmp")
{
b = new BitmapImage(new Uri("ms-appx:///Assets//Square150x150Logo.scale-200.png"));
}
else
{
await b.SetSourceAsync(thumb);
}
}
newlist.Add(new VideoGridItem { Name = file.DisplayName, i=b });
}
return newlist;
}
private static async Task<StorageItemThumbnail> GetThumbnail(StorageFile file)
{
var thumb = await file.GetThumbnailAsync(ThumbnailMode.VideosView, 190, ThumbnailOptions.UseCurrentScale);
return thumb;
}
}
答案 0 :(得分:3)
x:bind
的数据模板是正确的,可以使用异步方法。这里的问题与ObservableCollection
有关。在您的代码中,您使用VideoGridItems = await GetVideoItems(files);
更新了GridView
,但替换此类ObservableCollection
不会引发任何通知,GridView
仍然绑定旧版本。解决此问题的一种简单方法是使用Add
方法通知更改,如下所示:
VideoGridItems.Clear();
foreach (var item in await VideoGridItemManager.GetVideoItems(files))
{
VideoGridItems.Add(item);
}
我使用KnownFolders.PicturesLibrary
作为我身边的一个简单测试:
private async void LoadHistory()
{
var files = await KnownFolders.PicturesLibrary.GetFilesAsync();
VideoGridItems.Clear();
foreach (var item in await VideoGridItemManager.GetVideoItems(files))
{
VideoGridItems.Add(item);
}
}
效果很好。
<强> [更新] 强>
使用绑定时,如果您希望在数据源更改后更新UI,则需要引发PropertyChanged
事件。如果将全新的可观察集合分配给现有集合,则不会引发任何PropertyChanged
事件,因此您的GridView将不会更新。但是,如果您使用“添加”方法,则会引发PropertyChanged
事件。您可以在ObservableCollection
的{{3}}中找到这个。
protected override void InsertItem(int index, T item)
{
CheckReentrancy();
base.InsertItem(index, item);
OnPropertyChanged(CountString);
OnPropertyChanged(IndexerName);
OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
}
如果您希望在将全新的可观察集合分配给VideoGridItems
后进行UI更新,则可以触发PropertyChanged事件以通知视图集合已被替换。
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<VideoGridItem> _videoGridItems;
public ObservableCollection<VideoGridItem> VideoGridItems
{
get
{
return _videoGridItems;
}
set
{
_videoGridItems = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("VideoGridItems"));
}
}
}
public MainPage()
{
this.InitializeComponent();
VideoGridItems = new ObservableCollection<VideoGridItem>();
LoadHistory();
}
...
}
在您的XAML中,您需要使用ItemsSource="{x:Bind VideoGridItems, Mode=OneWay}"
,因为@gregkalapos说。