我想在没有UI冻结的情况下更改ListBox ItemsSource。对于这个挑战,我编写了你在下面看到的代码;
当用户点击按钮
时output =
new FileOutputStream(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filen[filen.length-1]));
异步方法
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://siebel.com/WebService">
<soapenv:Header>
<UsernameToken xmlns="http://siebel.com/webservices">XXXXXXX</UsernameToken>
<PasswordText xmlns="http://siebel.com/webservices"></PasswordText>
<SessionType xmlns="http://siebel.com/webservices">Stateless</SessionType>
</soapenv:Header>
<soapenv:Body>
<web:QuerySR_Input>
<web:SRNum>450545194</web:SRNum>
</web:QuerySR_Input>
</soapenv:Body>
</soapenv:Envelope>
更改ItemsSource
Thread th = new Thread(DisplayFilesAsync);
th.Start(new object[] { FolderPath, fdv.FileType });
在最后一个方法中,如果我直接更改ListBox的ItemSource,程序不会中断,但是当程序传递给方法的封闭大括号时,会分解并抛出必须在同一个线程上创建DependencySource DependencyObject 异常。
如果我改变了;它再次在封闭的花括号上分解,而不是在ADD方法上,并抛出相同的异常。
private void DisplayFilesAsync(object param)
{
object[] args = param as object[];
string searchText = Convert.ToString(args[0]);
FileType type = (FileType)args[1];
IEnumerable<FileListItem> list = uDirectoryHelper.GetFileFromFolder(searchText, type);
Dispatcher.BeginInvoke(new Action<IEnumerable<FileListItem>>(DisplayFiles), DispatcherPriority.Background, new object[] { list });
}
但是,如果我改变这样的代码,那就完美了,并将项目添加到我的列表框中。
private void DisplayFiles(IEnumerable<FileListItem> fileList)
{
lstFiles.ItemsSource = fileList;
}
我真的不理解我的失踪。为什么我可以添加一些字符串,但我无法添加到我的FileListItem类。我错过了什么?我已经尝试了很多不同的代码,但它总是打破封闭的花括号而不是在配置线上。
我真的需要帮助。谢谢你的回答。祝你有美好的一天,好的工作。
答案 0 :(得分:0)
您的FileListItem类具有ImageSource
类型的属性public ImageSource ItemImage { get; set; }
虽然您未在问题中显示,但您确实在GetFileFromFolder
方法中为该属性指定了一个值,例如像
fileList.ItemImage = new BitmapImage(new Uri(...));
除非BitmapImage
未在后台线程中冻结,否则UI线程无法访问它,因此您将获得该异常。
确保在加载位图后调用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
的另一个子类)。
using (var stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
{
fileList.ItemImage = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}