我正在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保持响应状态?
答案 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));