首页 > 解决方案 > WPF ListBox 加载大量图片会在 PresentationCore.dll 中发生 System.IO.IOException?

问题描述

我的 ItemTemplate 很简单,一个TextBlock显示Name,另一个Image显示Net Image:</p>

<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image VerticalAlignment="Center" Source="{Binding Url, Mode=OneWay, Converter={StaticResource cvtImage}}" Width="30" Height="30"/>
            <TextBlock Grid.Column="1" Text="{Binding Name, Mode=OneWay}" Margin="5" VerticalAlignment="Center"/>
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

这是我的图片数组:

private int[] numArr =
{
    20333581,
    65476272,
    65494751,
    67810732,
    72685857,
    73794129,
    74292128,
    78448608,
    89297529,
    109457648,
    128775798,
    136864278,
    140889893,
    155315730,
    155707244,
    158590544,
    160382605,
    162265810,
    167648987,
    170883246,
    175708510,
    181177782,
};

private List<ImageItem> imagesList = new List<ImageItem>();
private int imageCount = 22;


private void initialImageList()
{
    for (int i = 0; i < imageCount; i++)
    {
        imagesList.Add(new ImageItem {
            Name = "item " + (i + 1).ToString(),
            Url = String.Format("https://p.qlogo.cn/gh/{0}/{0}_1/40", numArr[i], numArr[i])
        });
    }
}

以上网络图片均有效。 类很简单,ImageItem有两个属性: 这是我的转换器类:NameUrl

class GcToNetImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var url = (string)value;
        Console.WriteLine("url is " + url);
        try
        {
            return new BitmapImage(new Uri(url));
        }
        catch (Exception ex)
        {
            Console.WriteLine("ex message: {0}", ex.Message);
            return new BitmapImage();
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Aftet 设置lb.ItemsSource = this.imagesList;,当你向下滑动 ListBox 时,你一定会得到IOException.

我想这与内存泄漏有关

标签: wpfwindowslistbox

解决方案


我使用此代码来捕获异常:

try 
{
    var c = new WebClient();
    var bytes = c.DownloadData(url);
    var ms = new MemoryStream(bytes);

    var bi = new BitmapImage();
    bi.BeginInit();
    bi.StreamSource = ms;
    bi.EndInit();

    return bi;  
}
catch (Exception ex)
{
    Console.WriteLine("ex message: {0}", ex.Message);
    return new BitmapImage();
}

现在我可以得到异常,但我仍然无法显示图像https://p.qlogo.cn/gh/170883246/170883246_1/40。图像可以显示在 WebBrowser 中。我不明白为什么 DotNetBitmapImage不能使用它。


推荐阅读