.UpdateLayout() 从 RunWorkerCompleted 方法抛出异常
本文关键字:方法 抛出异常 RunWorkerCompleted UpdateLayout | 更新日期: 2023-09-27 18:36:41
我正在开发一个应用程序,其中我正在使用BackgroundWorker从RunWorkerComplete方法将项目添加到列表视图中。从 RunWorkerCompleted 方法中,我正在添加列表视图项,我正在设置 .内容和 .背景。
但是,在设置 .后台属性并调用 .ListView 类的 UpdateLayout() 方法,我得到一个异常:"无法使用与其父级 Freezable 属于不同线程的依赖对象。
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
if (e.Cancelled == true)
{
System.Windows.MessageBox.Show("Something..cancelled");
}
else if (e.Error != null)
{
System.Windows.MessageBox.Show("Something..error " + e.Error.Message);
}
else
{
workLoad_listView.Items.Clear();
workLoad_listView.Height = 23;
foreach (Workload.workload element in Workload.Get())
{
System.Windows.Controls.ListViewItem item = new System.Windows.Controls.ListViewItem();
item.Content = (string)element.name;
item.Background = element.brush; // if I outcomment this line, no exception is thrown!
workLoad_listView.Items.Add(item);
}
workLoad_listView.UpdateLayout(); //exception is thrown here!
while (FindVisualChild<ScrollViewer>(workLoad_listView).ComputedVerticalScrollBarVisibility == Visibility.Visible)
{
workLoad_listView.Height += 1;
workLoad_listView.UpdateLayout();
}
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(string.Format("An exception was thrown!'n{0}", ex), "Exception caught", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
这是工作负载类:
public static class Workload
{
public struct workload
{
public string name;
public System.Windows.Media.SolidColorBrush brush;
}
private static List<workload> workload_list = new List<workload>();
public static void Add(string name, int colorNumber)
{
workload tmp_workload = new workload();
tmp_workload.name = name;
System.Drawing.Color color = System.Drawing.ColorTranslator.FromWin32(colorNumber);
tmp_workload.brush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, (byte)color.R, (byte)color.G, (byte)color.B));
workload_list.Add(tmp_workload);
}
public static void Clear()
{
workload_list.Clear();
}
public static List<workload> Get()
{
return workload_list;
}
}
任何建议将不胜感激:)
此致敬意。
System.Windows.Media.SolidColorBrush
类型派生自 DependencyObject
。DependencyObject
类型具有线程亲和力;也就是说,它只能在创建它的线程中使用。
您尚未显示完整的代码示例;特别是,从示例中不清楚调用Workload.Add()
方法的位置。但是考虑到错误消息,您很可能是从BackgroundWorker
的DoWork
事件处理程序调用此消息的。当然,此处理程序在与执行 RunWorkerCompleted
事件处理程序的 UI 线程不同的线程中运行,因此 brush 对象是在与您希望实际使用它的线程不同的线程中创建的。
基本上:这是框架禁止的。
同样,如果没有完整的代码示例,很难确定最佳解决方案是什么。但是,根据此处显示的代码,在我看来,您应该将 brush 的System.Windows.Media.Color
值存储在 workload
结构中而不是 Brush
值中,然后在 RunWorkerCompleted
事件处理程序中创建Brush
本身。
我还建议更改类型名称,以便您不会同时拥有Workload
类和workload
结构。有两个类型名称仅在第一个字母的情况下不同,这可能会让其他可能想要阅读代码的人(或者在你忘记如何实现它几个月后对你自己)感到非常困惑。