【问题标题】:Lazy-loading visible items in a Listview延迟加载列表视图中的可见项目
【发布时间】:2014-01-23 20:57:18
【问题描述】:

我有一个使用以下代码的列表视图:

<ListView x:Name="Display" ItemsSource="{Binding}" Background="#373737" Margin="0,0,350,0" BorderThickness="0" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Width="767" Height="88">
                    <Border Height="64" Width="64" Margin="12,12,0,12">
                        <Image Source="{Binding Path=album.albumart}" Stretch="UniformToFill"/>
                    </Border>
                    <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="0,10,0,0">
                        <TextBlock Text="{Binding Path=name}" 
                   Margin="10,0,0,0" Width="300" Height="40" 
                   TextTrimming="WordEllipsis" TextWrapping="Wrap" FontSize="16" HorizontalAlignment="Left"/>
                        <TextBlock Text="{Binding Path=album.name}" 
                   Margin="10,-15,0,0" Width="300" Height="20" 
                   TextTrimming="WordEllipsis" HorizontalAlignment="Left" 
                   FontSize="14" Opacity="0.49"/>
                        <TextBlock Text="{Binding Path=artistname}" 
                   Margin="10,2,0,0" Width="300"
                   TextTrimming="WordEllipsis" HorizontalAlignment="Left" 
                   FontSize="12" Opacity="0.49"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

我有大约 400 个带有图像的对象(这需要相当多的内存)

然后显示在每个列表视图项中。

列表视图有什么方法可以告诉项目从我拥有的缓存中加载它们的图像,基于哪些对象在列表视图中可见,而不是一直加载所有图像,如前所述,这需要相当长的时间一点记忆。

希望你们明白我在说什么,谢谢。

【问题讨论】:

  • 不幸的是,您不能按原样使用默认 ListView 执行此操作。你也许可以用 JavaScript 来完成。
  • @Jason:也许我的知识有点过时了 :D 但 javascript 真的可以在 C# WPF 应用程序中工作吗?
  • @Jason 这真的很糟糕......猜猜唯一的选择是缩小图片或将它们全部删除。不过谢谢
  • 哎呀!我的错!您仍然无法使用开箱即用的 WPF ListView 完成此操作。可能需要研究 RadControls (telerik.com/products/wpf/overview.aspx) 之类的东西。
  • @Tokfrans,album.albumart 的类型是什么?您是否尝试使用Lazy&lt;T&gt;ListView 默认使用虚拟化,这意味着它不会渲染未显示的项目

标签: c# wpf xaml data-binding lazy-loading


【解决方案1】:

我在包含 3500 多张高分辨率图片的图片文件夹中尝试了此解决方案。内存使用量达到 120MB 的峰值,剧烈滚动似乎触发了垃圾收集并将内存减少到大约 50MB。

 <ListBox ItemsSource="{Binding Images}" VirtualizingPanel.IsVirtualizing="True">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Image Height="64" Width="64">
                    <Image.Source>
                        <BitmapImage
                            DecodePixelHeight="64"
                            DecodePixelWidth="64"
                            UriSource="{Binding Path=., Mode=OneWay,UpdateSourceTrigger=Explicit}" 
                            CreateOptions="DelayCreation" 
                            CacheOption="None"  />
                    </Image.Source>
                </Image>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

视图模型:

public class ViewModel : INotifyPropertyChanged
    {
        public ICollectionView Images { get; private set; }
        public ViewModel()
        {
        }
        public void LoadImages()
        {
            var folder = @"C:\Users\lrved_000\Pictures";
            var photos = System.IO.Directory.EnumerateFiles(folder, "*.jpg",SearchOption.AllDirectories);

            Images = CollectionViewSource.GetDefaultView(photos);
            RaisePropertyChanged("Images");
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }

【讨论】:

  • 给我 InvalidOperationException,总是抱怨应该设置 UriSource 或 StreamSource(尽管您显然提供了 UriSource)。 VS2022,.Net 6.
猜你喜欢
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多