我正在尝试通过带有 x:Bind 的数据模板将我的视频 StorageFile 的缩略图绑定(bind)到 Image XAML 元素。我正在使用 MVVM 方法,过去我使用相同的方法来实现这一点,但我不知道为什么它现在不起作用。
我使用实时属性资源管理器,图像来源为 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 项目不显示图像和持续时间,有时持续时间显示和图像永远不会显示:
为什么没有图?
为什么没有持续时间?
更新
我检查了断点,项目的所有属性都显示为空,除了标题之外,除了标题之外的所有属性都是异步检索的,也许这就是原因?
最佳答案
all properties of items are appearing null, apart from title, all properties apart from title are retrieved asyncronosly
这是因为 UI 只呈现具有所有可用属性的网格项,而无需等待异步方法的任何结果,因此为什么有时您会得到一些具有正确
duration
的项文本显示,有时它没有。所以,合乎逻辑的解决方案是运行异步方法之后 gridview 加载这些项目,对吧?
但是怎么做?将其置于
loaded
下datatemplate 中的事件不会改变任何东西,因为它只会再次出现同样的问题。好吧,你可以通过滥用
ContainerContentChanging
来做到这一点Gridview 控件中的事件,因为该事件本身是如何工作的。Page.xaml
<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>
页.xaml.cs
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;
}
上面的代码是我为了异步加载缓存的缩略图所做的。
来源:
关于c# - UWP 缩略图与带有 x :bind 的图像绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44055945/