我试图通过x:Bind的数据模板将我的视频StorageFile的缩略图绑定到Image XAML元素。我正在使用MVVM方法,并且我已经使用相同的方法来实现这一点,但我不知道为什么它现在不起作用。
我使用实时属性资源管理器,Image的源代码为0.其他属性(如视频标题)工作正常,但图像无效。但问题是即使持续时间也会出现,有时持续时间会显示出来,有时也会出现问题,这很奇怪:/
我在下面提供我的代码。 感谢提前
模型
public class VideoItem : LibraryItem
{
#region Props
public string Views { get; set; }
public string Duration { get; set; }
public BitmapImage Display { get; set; }
public VideoProperties MyVideoProperties { get; set; }
public StorageFile MyVideoFile { get; set; }
#endregion
public VideoItem(StorageFile File)
{
MyVideoFile = File;
Initialize();
}
#region PrivateMethods
private async void Initialize()
{
Title = MyVideoFile.DisplayName;
MyVideoProperties = await MyVideoFile.Properties.GetVideoPropertiesAsync();
var dur = MyVideoProperties.Duration;
Duration = $"{dur.Hours.ToString()} : {dur.Minutes.ToString()} : {dur.Seconds.ToString()}";
Display = await GetDisplay();
Views = MyVideoProperties.Rating.ToString();
}
private async Task<BitmapImage> GetDisplay()
{
var bitm = new BitmapImage();
using (var imgSource = await MyVideoFile.GetScaledImageAsThumbnailAsync(ThumbnailMode.VideosView))
{
if (imgSource != null) { bitm.SetSource(imgSource); }
else
{
var storelogoFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
var storageLogoFile = await storelogoFolder.GetFileAsync("StoreLogo.png");
bitm.UriSource = new Uri(storageLogoFile.Path);
}
}
return bitm;
}
#endregion
}
public class LibraryItem
{
public string Title { get; set; }
}
视图模型
public class VideoLibraryViewModel
{
#region Constructor
public VideoLibraryViewModel(StorageFolder mainFolder)
{
VideoItems = new ObservableCollection<VideoItem>();
MainFolder = mainFolder;
Initialize();
}
#endregion
#region Props
public ObservableCollection<VideoItem> VideoItems { get; set; }
#endregion
#region PrivateFields
private StorageFolder MainFolder;
private IEnumerable<StorageFile> Videos;
private char[] sep = new char[] { '/' };
#endregion
#region PrivateMethods
private async void Initialize()
{
Videos = await MainFolder.GetFilesAsync();
Videos = Videos.Where(a => a.ContentType.Split(sep)[0] == "video");
FillUp();
}
private void FillUp()
{
foreach (var file in Videos)
{
VideoItems.Add(new VideoItem(file));
}
}
#endregion
}
查看
<controls:AdaptiveGridView Name="VideosLibraryGridView" Grid.Row="1"
Header="Videos"
Style="{StaticResource MainGridView}"
ItemClick="VideosLibraryGridView_ItemClicked"
ItemsSource="{x:Bind VideoLibraryVM.VideoItems, Mode=OneWay}">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:VideoItem">
<StackPanel Margin="4" >
<Grid>
<Image Source="{x:Bind Display, Mode=OneWay}" Style="{StaticResource GridViewImage}"/>
<Border Style="{StaticResource TimeBorder}">
<TextBlock Text="{x:Bind Duration, Mode=OneWay}" Foreground="White"/>
</Border>
</Grid>
<TextBlock Text="{x:Bind Title,Mode=OneWay}" Style="{StaticResource GridViewVideoName}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock Text="{x:Bind Views,Mode=OneWay}" Style="{StaticResource GridViewViews}"/>
<TextBlock Text="Views" HorizontalAlignment="Right"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
图片样式
<Style TargetType="Image" x:Key="GridViewImage">
<Setter Property="Stretch" Value="UniformToFill"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
在应用中输出,您可以看到gridview项目显示没有图像,没有持续时间,有时持续时间显示和图像永远不会显示
为什么没有形象?
为什么没有持续时间?
更新
我已经检查过断点,项目的所有属性都显示为空,除了标题之外,所有属性除了标题都是异步检索的,也许这就是原因?
答案 0 :(得分:0)
项目的所有属性都显示为空,除了标题,所有与标题无关的属性都是异步检索的
这是因为UI只是渲染具有所有可用属性的网格项目,而没有等待异步方法的任何结果,因此为什么有时您会显示一些带有正确的loaded
文本的项目,而有时却没有。
因此,逻辑解决方案是在gridview加载这些项目后后运行异步方法,对吧?
但是如何?将其放在datatemplate内的ContainerContentChanging
事件下不会改变任何内容,因为它只会再次发生相同的问题。
好吧,由于该事件本身的工作原理,您可以通过滥用Gridview控件中的<controls:AdaptiveGridView
Name="VideosLibraryGridView" Grid.Row="1
ContainerContentChanging="VideosLibraryGridView_ContainerContentChanging"
Header="Videos"
Style="{StaticResource MainGridView}"
ItemClick="VideosLibraryGridView_ItemClicked"
ItemsSource="{x:Bind VideoLibraryVM.VideoItems, Mode=OneWay}">
<!--something something-->
</controls:AdaptiveGridView>
事件来实现此目的。
Page.xaml
private void VideosLibraryGridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args
{
args.RegisterUpdateCallback(LoadImage);
}
private async void LoadImage(ListViewBase sender, ContainerContentChangingEventArgs args)
{
var templateRoot = args.ItemContainer.ContentTemplateRoot as Grid;
var imageurl = (args.Item as model).ThumbnailUri;
var cache = await getimagefromfileasync(imageurl);
//check your image location based on your template first.
var image = templateRoot.Children[0] as Image;
image.Source = new BitmapImage()
{
UriSource = new Uri(cache.Path)
};
image.Opacity = 1;
}
Page.xaml.cs
{{1}}
上面的代码是我为了异步加载缓存的缩略图所做的。
来源: