C# 使用不同的线程更改Listbox项资源
我想在不冻结UI的情况下更改ListBox项资源。对于这个挑战,我编写了下面的代码 当用户单击按钮时 异步方法 我真的不明白我的思念。为什么我可以添加到一些字符串,但不能添加到FileListItem类。我错过了什么?我尝试过很多不同的代码,但它总是在闭合的花括号上断开,而不是在分配行上断开C# 使用不同的线程更改Listbox项资源,c#,wpf,multithreading,listbox,thread-safety,C#,Wpf,Multithreading,Listbox,Thread Safety,我想在不冻结UI的情况下更改ListBox项资源。对于这个挑战,我编写了下面的代码 当用户单击按钮时 异步方法 我真的不明白我的思念。为什么我可以添加到一些字符串,但不能添加到FileListItem类。我错过了什么?我尝试过很多不同的代码,但它总是在闭合的花括号上断开,而不是在分配行上断开 我真的需要帮助。谢谢你的回答。祝您愉快,工作愉快。您的FileListItem类具有ImageSource类型的属性 public ImageSource ItemImage { get; set; }
我真的需要帮助。谢谢你的回答。祝您愉快,工作愉快。您的FileListItem类具有ImageSource类型的属性
public ImageSource ItemImage { get; set; }
尽管您在问题中没有说明这一点,但您肯定会在GetFileFromFolder
方法中为该属性指定一个值,例如
fileList.ItemImage = new BitmapImage(new Uri(...));
除非BitmapImage
未在后台线程中冻结,否则UI线程无法访问它,因此您将获得该异常
private void DisplayFiles(IEnumerable<FileListItem> fileList)
{
foreach (FileListItem item in fileList)
{
lstFiles.Items.Add(item);
}
}
确保在BitmapImage加载位图后对其调用Freeze()
方法。请注意,在这种情况下,无法进行异步位图加载(例如,通过远程URI)。如果位图是从本地文件加载的,请执行以下操作:
var bitmap = new BitmapImage();
using (var stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
bitmap.Freeze();
}
fileList.ItemImage = bitmap;
或者,使用BitmapFrame.Create()
方法代替BitmapImage,该方法已返回冻结的BitmapFrame
(另一个子类为ImageSource
)
这个问题可能会帮助您:不幸的是,对于后台工作者,我也遇到了同样的错误。您的FileListItem类是什么样子的?它是DependcyObject吗?如果是这样,您可能必须在UI线程上创建它。如果您遇到断点问题,可能VisualStudio没有运行最新版本的代码。。。尝试清理项目并重建。您可能希望检查文件在清理之后和重建之前是否已实际消失。
public类FileListItem{public FileListItem(string itemText,ImageSource itemImage,ImageSource itemToolTip){itemText=itemText;itemImage=itemImage;ToolTipImage=itemToolTip;}公共字符串ItemText{get;set;}公共图像源ItemImage{get;set;}公共图像源工具提示图像{get;set;}}
这是我的FileListItem。。。我是从依赖对象派生出来的吗?
foreach (FileListItem item in fileList)
{
lstFiles.Items.Add("EXAMPLE");
}
public ImageSource ItemImage { get; set; }
fileList.ItemImage = new BitmapImage(new Uri(...));
var bitmap = new BitmapImage();
using (var stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
bitmap.Freeze();
}
fileList.ItemImage = bitmap;
using (var stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
{
fileList.ItemImage = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}