c# - UWP 缩略图与带有 x :bind 的图像绑定(bind)

标签 c# xaml gridview mvvm binding

我正在尝试通过带有 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 项目不显示图像和持续时间,有时持续时间显示和图像永远不会显示:

为什么没有图?

为什么没有持续时间?

enter image description here

更新

我检查了断点,项目的所有属性都显示为空,除了标题之外,除了标题之外的所有属性都是异步检索的,也许这就是原因?

最佳答案

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;
}

上面的代码是我为了异步加载缓存的缩略图所做的。

来源:
  • Dramatically Increase Performance when Users Interact with Large Amounts of Data in GridView and ListView
  • ContainerContentChanging Event
  • Update ListView and GridView items progressively
  • 关于c# - UWP 缩略图与带有 x :bind 的图像绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44055945/

    相关文章:

    android - Xamarin Visual Studio 2017 预览器不工作

    wpf - 在 WPF 应用程序中使用 XAML 矢量图形

    c# - "Enum as immutable rich-object": is this an anti-pattern?

    c# - C# 中的 java.lang.Void?

    c# - 学习WP7编程有哪些好书?

    html - 如何跨越两个父 div 的子 div

    android - 从Gridview动态切换到Listview

    jquery - 使用jquery从gridview获取选定的索引

    c# - 字节 [] 的 Varbinary 文本表示

    c# - 发送 http header 后服务器无法设置状态