运行此代码时出现错误:
tabControl1.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { tabControl1.Items.Add(tbItem); }));
tabcontrol1被硬编码到xaml中,标签项是在运行时构建的。 我收到了一个错误:
TargetInvocationException是 未处理的异常已被抛出 调用的目标。
我很想听到有关这方面的任何想法。 感谢
更新
内部异常:
{“调用线程无法访问 这个对象因为一个不同的线程 拥有它。“}
完整的方法代码:
TabItem tbItem = new TabItem();
tbItem.Header = worker;
Grid grid = new Grid();
ListBox listBox = new ListBox();
listBox.HorizontalAlignment = HorizontalAlignment.Stretch;
listBox.VerticalAlignment = VerticalAlignment.Stretch;
listBox.ItemsSource = datasource.Where(i => i.Category == worker);
grid.Children.Add(listBox);
tbItem.Content = grid;
tabControl1.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { tabControl1.Items.Add(tbItem); }));
使用以下方法调用该方法:
Thread newThread = new Thread(myMethod);
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();
另一个更新
这有效:
tabControl1.Dispatcher.Invoke(DispatcherPriority.Normal,
(Action)(() =>
{
TabItem tbItem = new TabItem();
tbItem.Header = worker;
//Grid & ListBox(within tab item)
Grid grid = new Grid();
ListBox listBox = new ListBox();
listBox.HorizontalAlignment = HorizontalAlignment.Stretch;
listBox.VerticalAlignment = VerticalAlignment.Stretch;
listBox.ItemsSource = datasource.Where(i => i.Category == worker);
grid.Children.Add(listBox);
tbItem.Content = grid;
tabControl1.Items.Add(tbItem);
}));
答案 0 :(得分:1)
你可以看到你的tbItem是在不同的线程上创建的,即使它尝试将它发送回TAbControl的主要gui线程。
为什么不提取需要更长时间的部分(你使用的是线程),一旦你得到结果,继续创建tbItem并将其添加到GUI线程中的TabControl
示例:
tabControl.Dispatcher.Invoke calls below function with dataSoruce result it gets
List<string> result = null;
tabControl.Dispatcher.Invoke((Action<IEnumerable<string>>)ProcessResult, result);
public void ProcessResult(IEnumerable<string> datasource)
{
//this is where you do creating TabItem and assigning data source to it and adding to TabControl.
}
没有编译,请检查语法
答案 1 :(得分:0)
检查InnerException
属性以找出原因。 TargetInvocationException
只是wpf运行时的包装器。你的lambda可能会抛出,但没有实际的例外,你无法分辨。
修改强>
您正在另一个线程中创建TabItem
,因此即使您使用调度程序进行实际添加,GUI线程也无法访问它。正如您已使用上一个代码段发布的那样,您必须在GUI线程中创建TabItem
。只在不同的线程中进行计算,一旦结果返回,在GUI线程中实际创建TabItem
(必要时通过Dispatcher
)。
答案 2 :(得分:0)
问题是你是在一个单独的线程上创建你的UIElements。这是不允许的。
您可以在后台线程(对datasource.Where(i => i.Category == worker);
的调用)上进行处理,但不幸的是,每个UI元素都需要在主用户界面线程上完全构建和使用。
在您的情况下,这意味着在Dispatcher调用内部的UI线程上构建ListBox和Grid。
我建议将其重写为:
// Load the data on the background...
var data = datasource.Where(i => i.Category == worker);
// Do all work on the UI thread
tabControl1.Dispatcher.Invoke(DispatcherPriority.Normal,
(Action)(() =>
{
TabItem tbItem = new TabItem();
tbItem.Header = worker;
//Grid & ListBox(within tab item)
Grid grid = new Grid();
ListBox listBox = new ListBox();
listBox.HorizontalAlignment = HorizontalAlignment.Stretch;
listBox.VerticalAlignment = VerticalAlignment.Stretch;
listBox.ItemsSource = data;
grid.Children.Add(listBox);
tbItem.Content = grid;
tabControl1.Items.Add(tbItem);
}));