我如何显示将项目添加到ListView时将其一一添加到ListView的项目?

时间:2019-07-03 00:43:56

标签: c# wpf

我正在WPF中使用ListView显示一些图像,这是通过用Image对象填充ObservableCollection并将该列表设置为ItemsSource来完成的。我的实现如下所示:

[default]
aws_access_key_id = A*******Z
aws_secret_access_key = A*******/***xyz

我的意图是,随着可观察列表的填充,foreach循环的每次迭代都会更新一次UI。但是,foreach循环会在将控件返回到UI之前完全填满列表,然后UI会同时显示所有图片。由于大约有100张图片,因此该程序滞后了几秒钟。

有什么办法可以使程序一次更新UI的一个元素,并且还可以使UI保持响应状态?

1 个答案:

答案 0 :(得分:1)

听起来像您需要以asnyc方式加载图像

private async void loadImages(object sender, RoutedEventArgs e)
{
    await Task.Run(() =>
    {
        var filePaths = Directory.EnumerateFiles(@"C:\SomeImages");

        foreach (string filePath in filePaths)
        {
            var bimage = new BitmapImage();
            bimage.BeginInit();
            bimage.CacheOption = BitmapCacheOption.OnLoad;
            bimage.UriSource = new Uri(filePath, UriKind.Absolute);
            bimage.EndInit();
            bimage.Freeze();

            Dispatcher.Invoke(() => imageList.Add(new Image { Source = bimage }));
        }
    });
}

但是您不应在后面的代码中创建UI元素。将Image元素移到ListBox的ItemTemplate:

<ListBox x:Name="ImageView">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

将后面的代码更改为此:

private readonly ObservableCollection<ImageSource> imageList
    = new ObservableCollection<ImageSource>();

public MainWindow()
{
    InitializeComponent();
    ImageView.ItemsSource = imageList;
}

并将BitmapImages直接添加到列表中:

Dispatcher.Invoke(() => imageList.Add(bimage));