2013-05-31 27 views
-1

我已經在wpf中找到了多個有關多線程的主題,並且獲得了大部分與dispatch一起工作的內容,但還有一件事我還沒弄清楚。 我有一個名爲「stackpanel1」的堆棧面板,我在其中添加了一個名爲「stackrow」的堆棧面板(在另一個線程中)作爲孩子。 (的foreach循環)從另一個線程向stackpanel添加堆棧面板(使用dispatch?)

stackPanel1.Dispatcher.Invoke(new Action(() => stackPanel1.Children.Add(stackrow))); 

其類似於這樣的問題: WPF C# - Editing a listbox from another thread

,除了我的 「新項目」 是一個UI元素(stackrow),我收到以下錯誤: InvalidOperationException異常是未處理的。 調用線程不能訪問此對象,因爲不同的線程擁有它。

如何在這一行發送「堆棧」?

編輯: stackrow在foreach循環創建

mainthread(創建新線程) 線程t =新主題(()=> addstackrows()); t.SetApartmentState(ApartmentState.STA); t.Start();

方法addstackrows()

private void addstackrows() 
{ 

    Dispatcher stackpaneldispatcher = stackPanel1.Dispatcher;     
    stackPanel1.Dispatcher.Invoke(new Action(() => 
    stackPanel1.Children.Clear())); 
    stackPanel1.Dispatcher.Invoke(new Action(() => 
    stackPanel1.Orientation = Orientation.Vertical)); 

    foreach (var randomelement in elementcollection) 
    { 
     StackPanel stackrow = new StackPanel(); 
     Dispatcher stackrowdp = stackrow.Dispatcher; 

     stackrow.Dispatcher.Invoke(new Action(() => 
     stackrow.Orientation = Orientation.Horizontal)); 
     stackPanel1.Dispatcher.Invoke(new Action(() => 
     stackPanel1.Children.Add(stackrow))); 

    } 

} 
+0

'stackrow'在哪裏創建? – ChrisF

+0

1您無法從後臺線程處理UI元素。 2 - 你甚至不應該在WPF的程序代碼中操縱UI元素。這是一個起源於一些恐龍技術無法正常使用數據綁定的糟糕做法。發佈你需要的截圖,我可以告訴你在WPF中實現它的正確方法。 –

+0

@ChrisF stackrow在新線程中創建。 – morrismoss

回答

0

您應該創建在同一線程中所有的UI對象:

private void addstackrows() 
{ 

    Dispatcher stackpaneldispatcher = stackPanel1.Dispatcher; 
    stackPanel1.Dispatcher.Invoke(new Action(() => 
    { 
     stackPanel1.Children.Clear(); 
     stackPanel1.Orientation = Orientation.Vertical; 
    })); 

    foreach (var randomelement in elementcollection) 
    { 
     stackPanel1.Dispatcher.Invoke(new Action(() => 
     { 
      StackPanel stackrow = new StackPanel(); 
      stackrow.Orientation = Orientation.Horizontal; 
      stackPanel1.Children.Add(stackrow); 
     })); 
    } 
} 

另外,我組你所有的Dispatcher電話。每次您撥打Invoke時都會有性能開銷。所以,除非你在循環中做了耗時的操作,否則把整個函數放在Invoke內可能會更好。