c# - 在虚拟化列表框中延迟加载图像

标签 c# wpf xaml asynchronous listbox

我正在尝试异步延迟加载列表框中每个项目的缩略图。

<Image Source="{Binding Path=Thumbnail, TargetNullValue={StaticResource DefaultImage}}"/>

由于列表框是虚拟化的,因此只有当项目位于显示端口或接近该端口时,才会调用缩略图属性的 getter。

public BitmapSource Thumbnail
{
    get
    {
        TriggerLoad();
        return _thumbnail;
    }
}

我正在等待在 TriggerLoad 函数中加载 Thumbail 的昂贵操作,但 UI 的响应速度不是很好,尤其是当您尝试快速滚动大型项目列表时。

private async void TriggerLoad()
{
    if (!LoadTriggered)
    {
        LoadTriggered = true;
        var cacheItem = _cache[key] as CacheItem;

        if (cacheItem != null)
            await LoadBitmapFromCache(cacheItem); // returns a Task
        else
            await LoadBitmapFromService(Id); // returns a Task
    }
}

发现类似问题here但这与将项目加载到列表框无关。有没有更好的方法来延迟加载绑定(bind)到列表框的部分数据?

编辑:我尝试了 PriorityBinding 和 IsAsync 选项,但滚动并不比我当前的解决方案更好。

最佳答案

听起来虽然你的 UI 正在虚拟化,但它加载新图像的速度不够快,无法跟上用户的滚动。 尝试将 VirtualizationMode 设置为 Recycling 并设置更长的 CacheLength。就像这样:

<ListBox
    VirtualizingPanel.IsContainerVirtualizable="True"
    VirtualizingPanel.IsVirtualizing="True"
    VirtualizingPanel.VirtualizationMode="Recycling"
    VirtualizingPanel.CacheLengthUnit="Page"
    VirtualizingPanel.CacheLength="2,2"
    etc.../>

将 CacheLength 从“1,1”增加到“2,2”意味着两个“页面”(或相当于视口(viewport)的项目)将在向用户显示的页面之前和之后加载到内存中。您的应用将消耗更多内存,但用户将能够在遇到未加载的图像之前进一步、更快地滚动。

关于c# - 在虚拟化列表框中延迟加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25070178/

相关文章:

c# - 在 wpf 中禁用 itemscontrol 上的鼠标滚轮

c# - 在 .NET 中生成、显示和打印简单文档

c# - 使用MenuItem值作为CommandParameter

wpf - TabControl 中等宽的选项卡

c# - 如何使用两个不同版本的 Visual Studio 处理 TFS DLL

c# - 帮助我以正确的方式编写此事件

wpf - 使用 "Attached Property"是输入捕获的好习惯吗?

c# - uwp 动态创建 xaml 或新页面

c# - Left Outer Join,这两种方法有什么区别?

c# - 删除所有具有给定名称的 XML 属性