Reputation: 85
I'm quite new to threads in c# (WPF) and since I've implemented some label and progressbar update successfully, I do not understand Why when I try to add items to the treeView of my GUI from another class called in a separate thread I get an exception:
An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
Additional information: The calling thread cannot access this object because a different thread owns it.
My update treeview code is this:
private void updateTreeView(TreeView tree, List<TreeViewItem> items, Boolean clear) {
tree.Dispatcher.Invoke(new Action(() => {
if (clear) {
tree.Items.Clear();
}
ItemCollection treeitems = tree.Items;
foreach (TreeViewItem item in items) {
treeitems.Dispatcher.Invoke(new Action(() => {
treeitems.Add(item);
}));
}
tree.ItemsSource = treeitems;
}));
}
And the exception points at the line:
treeitems.Add(item);
Thanks in advance.
Upvotes: 1
Views: 3659
Reputation: 327
This is a really old question but I figured I would answer it. You have two dispatchers in your sample. You have a treeview that you are getting its thread and a list that seems to be created in a different thread.
But the code should look more like this. Sorry about the VB in this case I'm using a delegate inside the invoke.
tree.Dispatcher.BeginInvoke(Sub()
Dim node = new TreeViewItem() With {.Header = "Header"}
tree.items.add(node)
End Sub)
I am not jumping out of the UI thread to add the node like in the original question.
Upvotes: 0
Reputation: 936
you can use the following :
delegate void DUpdateTreeView(TreeView tree, List<TreeViewItem> items, Boolean clear);
private void UpdataTreeView(TreeView tree, List<TreeViewItem> items, Boolean clear)
{
if (tree.InvokeRequired)
{
DUpdateTreeView d = new DUpdateTreeView(UpdataTreeView);
// replace this by the main form object if the function doesn't in the main form class
this.Invoke(d, new object[] { tree, items, clear });
}
else
{
if (clear)
{
tree.Items.Clear();
}
else
{
// Here you can add the items to the treeView
/***
ItemCollection treeitems = tree.Items;
foreach (TreeViewItem item in items)
{
treeitems.Dispatcher.Invoke(new Action(() =>
{
treeitems.Add(item);
}));
}
tree.ItemsSource = treeitems;
***/
}
}
}
Upvotes: 1