2015-06-08 78 views
3

創建UI重元素這是工作的代碼(但是UI線程):另一個線程WPF

<ContentControl 
       Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" 
       Focusable="True" 
       HorizontalAlignment="Right" 
       Content="{Binding Work}" > 
      </ContentControl> 

這是我想要做,而不是代碼,但它不工作:(代碼隱藏)

  InitializeComponent(); 

      var thread = new Thread(
       () => 
       { 
        var a = new ContentControl { Focusable = true, HorizontalAlignment = HorizontalAlignment.Right }; 
        var binding = new Binding { Path = new PropertyPath("Work"), }; 

        a.SetBinding(ContentProperty, binding); 
        MainGrid.Dispatcher.Invoke(new Action(() => { MainGrid.Children.Add(a); })); 
       }) { IsBackground = true }; 
      thread.SetApartmentState(ApartmentState.STA); 
      thread.Start(); 

我的目標是創建一個ConentControl,並將其放置在網格中,這是一個listview內有多個ContentControls)所示的方案是崩潰,因爲不同的線程擁有MainGrid。 任何人都有這個好主意? (很想做它在另一個線程,因爲ContentControl很重,像3秒以創建佈局這是它根據參數創建自己的通用視圖。)

編輯:

的主要問題在創建這些視圖的過程中,我的整個應用程序都處於掛起狀態。這是非常不想要的。我的目標是將此工作負載移到另一個(或多個)其他線程。

+1

您不能在UI線程以外的線程上創建UI元素。您可以創建在另一個線程上創建UI所需的數據。這就是你應該做的。從UI線程中獲取所有的IO。這應該使UI快速建立。 – Enigmativity

回答

4

您可以使用IsAsync屬性強制在不同的線程上執行綁定。

Content="{Binding Work, IsAsync=True}" 

這將在一個新的線程執行結合Work並且當它這樣做的內容將被填充。你不需要打擾你的代碼隱藏的東西。

你可以在行動here找到一個很好的教程。

+2

它加載異步是啊。但是我的視圖渲染仍然使用了很多時間,這使得我的整個應用程序停止了幾秒鐘。 – Illedan

+0

如果渲染是由於需要很長時間的一堆綁定導致的,那麼'IsAsync'應該有助於解決那。但是,如果你在代碼中生成視圖(你不應該這樣做),那麼你需要使用一些奇特的異步任務來渲染它。你可以在你的原始問題中發佈你的渲染器嗎?可以將其轉換爲自定義控件或用戶控件,而無需手動渲染*。 –

+0

實際上我並不確定,但我認爲這是一堆綁定。我使用另一個團隊製作的控件。我是否需要每個綁定上的「IsAsync」? – Illedan