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

时间:2014-07-31 22:47:34

标签: c# wpf xaml asynchronous listbox

我试图以异步方式为列表框中的每个项目延迟加载缩略图。

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

由于列表框是虚拟化的,因此仅当项目位于显示端口或靠近显示端口时,才会调用Thumbnail属性的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但不是将项目加载到列表框中。有没有更好的方法来延迟加载只绑定到Listbox的数据的一部分?

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

1 个答案:

答案 0 :(得分:2)

听起来虽然您的用户界面正在虚拟化,但它并不能足够快地加载新图像以跟上用户的滚动。 尝试将VirtualizationMode设置为Recycling并设置更长的CacheLength。像这样:

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

从&#34; 1,1&#34;增加CacheLength至&#34; 2,2&#34;意味着两个&#34;页面&#34; (或视图端口值项目)将在向用户显示的页面之前和之后加载到内存中。您的应用程序将占用更多内存,但用户将能够更快,更快地滚动,然后再运行未加载的图像。