本文介绍了为什么程序通过向列表视图添加很多图像而崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的XAML:

<ListView MouseDoubleClick="ImageList_MouseDoubleClick" Name="ImageList" Background="#353535" Grid.Row="2" Margin="0 5 0 0">
<ListView.ItemTemplate>
    <DataTemplate>
        <Grid Cursor="Hand" Width="200" Height="130" VerticalAlignment="Center" HorizontalAlignment="Left">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Image Source="{Binding ImgPath}" Grid.Row="0"/>
            <Label FontSize="14" Foreground="White" Grid.Row="1" HorizontalAlignment="Center" Content="{Binding Name}"/>
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <WrapPanel Orientation="Horizontal" Width="{Binding Path=ActualWidth, ElementName=ImageList}"/>
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

这样,我将项目添加到ListView:

And this way I add items to ListView:

String[] extensions = { "*.bmp", "*.png", "*.jpg", "*.jpeg", "*.tiff", "*.ico", "*.gif" };
List<String> images = new List<String>();
foreach (String ext in extensions)
{
    try
    {
        images = images.Concat(Directory.GetFiles(path, ext)).ToList();
    }
    catch { }
}
ObservableCollection<ImageBlock> ImageCollection = new ObservableCollection<ImageBlock>();
foreach (String img in images)
    this.ImageList.Items.Add(new ImageBlock(img, System.IO.Path.GetFileName(img)));

此代码可以很好地处理少量图片,但是当我尝试打开包含100张图片的文件夹时,程序崩溃.我做错了什么或者我可以做些什么来优化我的程序?

This code work perfectly with a little count of images, but when I try to open a folder with more than 100 pictures, my program crashes. What I do wrong or what I can do to optimize my program?

推荐答案

您可能拥有一个视图模型,该模型可以异步加载缩略图文件,还可以通过设置DecodePixelWidthDecodePixelHeight属性来限制其大小.

You could have a view model that loads thumbnail image files asynchronously, and also limits their size by setting the DecodePixelWidth or DecodePixelHeight property.

public class ImageData
{
    public string Name { get; set; }
    public ImageSource ImageSource { get; set; }
}

public class ViewModel
{
    public ObservableCollection<ImageData> Images { get; }
        = new ObservableCollection<ImageData>();

    public async Task LoadFolder(string folderName, string extension = "*.jpg")
    {
        Images.Clear();

        foreach (var path in Directory.EnumerateFiles(folderName, extension))
        {
            Images.Add(new ImageData
            {
                Name = Path.GetFileName(path),
                ImageSource = await LoadImage(path)
            });
        }
    }

    public Task<BitmapImage> LoadImage(string path)
    {
        return Task.Run(() =>
        {
            var bitmap = new BitmapImage();

            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                bitmap.BeginInit();
                bitmap.DecodePixelHeight = 100;
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.StreamSource = stream;
                bitmap.EndInit();
                bitmap.Freeze();
            }

            return bitmap;
        });
    }
}

您将绑定到这样的视图模型:

You would bind to such a view model like this:

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>
...
<ListBox ItemsSource="{Binding Images}"
            ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Width="200" Height="130">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="30"/>
                </Grid.RowDefinitions>
                <Image Source="{Binding ImageSource}"/>
                <TextBlock Grid.Row="1" Text="{Binding Name}"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

并填充它,例如在某些异步输入事件处理程序中,例如:

And populate it e.g. in some async input event handler, like:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await ((ViewModel)DataContext).LoadFolder(...);
}

这篇关于为什么程序通过向列表视图添加很多图像而崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 06:25