2016-03-21 65 views
2

我有一個多線程應用程序,我需要從另一個線程添加對象到樹視圖。但我不斷收到異常如何從另一個線程在treeview中添加對象

正在對此控件執行的操作是由錯誤的線程調用的。使用Control.Invoke或Control.BeginInvoke對正確的線程進行編組來執行此操作。

這裏是我的代碼

ThreadPool.QueueUserWorkItem(new WaitCallback(GetFiles), entryPoint); 

private void GetFiles(object entryPoint) 
{ 
     var localData = entryPoint as EntryPoint; 
     this.GetFiles(localData.DirectoryInfo, localData.TreeNode); 
     localData.ManualEvent.Set(); 
} 

private void GetFiles(DirectoryInfo directory, TreeNode tree) 
{ 
    for (int i = 0; i < allFiles.GetLength(0); i++) 
    { 
     tree.Nodes.Add(allFiles[i].Name); 
    } 
} 
+1

這是一個標準消息,您不能修改由非UI線程的UI線程創建的元素。將BeginInvoke()與您的線程的mainform中的匿名委託或常​​用委託一起使用。我認爲,lambda和linq甚至提供更好的方法。 – icbytes

+0

我在委託的幫助下做的,但仍然收到一個異常public delegate void MyDelagate(TreeNode tree,string value); public MyDelagate TreeViewDelegate; TreeViewDelegate =委託(TreeNode樹,字符串s) { tree.Nodes.Add(s); }; TreeViewDelegate.Invoke(tree,allFiles [i] .Name); – Ilia

+0

恕我直言,你根本不需要使用'ThreadPool'。只需在UI線程中調用該方法即可。你的方法沒有做任何重要的工作。 –

回答

2

由於錯誤狀態,你需要在UI線程上執行UI相關的操作。爲了做到這一點,您可以使用控制器本身的BeginInvoke

private void GetFiles(DirectoryInfo directory, TreeNode tree) 
{ 
    if (TreeViewControl.InvokeRequired) 
    { 
     TreeViewControl.BeginInvoke((MethodInvoker)delegate 
     { 
      for (int i = 0; i < allFiles.GetLength(0); i++) 
      { 
       tree.Nodes.Add(allFiles[i].Name); 
      } 
     }); 
    } 
} 

你可以找到更多的信息here

+0

如何在WinForms應用程序中使用Dispatcher? – Ilia

+0

這是WinForms嗎?你的標籤聲明WPF。 –

+0

對不起,我的錯 – Ilia

4

我認爲你需要做的是:

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => GetFiles(directory, tree))); 
+0

歡迎來到Stack Overflow!雖然這段代碼可能會回答這個問題,但最好包含一些_context_,解釋它的工作原理和_when_使用它。從長遠來看,僅有代碼的答案是沒有用的。 –

+0

Windows窗體中沒有'Dispatcher'! – Enigmativity

+0

@Enigmativity當這個答案發布時,問題被標記爲[tag:wpf]。 –

相關問題