2017-02-03 62 views
0

我試圖找到一種方法將一個winform線程的父項更改回GUI線程。現在,我必須從另一個線程創建表單,但是從具有引用的主窗體訪問變得不可能。更改窗體的父線程

這裏我有什麼

public partial class MainForm : Form 
{ 
    // local instance of the sub form 
    private ViewForm SubForm { get; set;} = null; 

    public MainForm() 
    { 
     InitializeComponent(); 

     Task.Run(() => 
     { 
      // set the sub form    
      SubForm = new ViewForm(); 
     } 

     // call the rest of the initialization of main form 
     InitializeCustomControls(); 
    } 

    private void OpenViewWindow_Click(object sender, EventArgs e) 
    { 
     // if the window is instanciated 
     if (SubForm != null) 
     { 
      SubForm.Show();     
     } 
    }   
} 

ViewForm窗口的樣本是不是Form對象。這是一個自定義的第三方窗口。它有很多控制和模板混合主題。對一個新的空構造函數的唯一調用可能需要7秒,因此爲什麼我需要在另一個線程上創建它,而我繼續加載我的主窗口。

現在,我可以調用窗口中除.Show()之外的任何方法,因爲線程創建限制,它總是失敗。我想遠離創建線程作爲一個無盡的運行線程,將等待並閱讀一些對象,告訴他何時顯示和隱藏窗口。

的是.Show()錯誤:

Cross-thread operation not valid: Control 'ViewForm' accessed from a thread other than the thread it was created on.

我曾嘗試,而不是下面的,但它仍然凍結我的界面:

Task.Run(() => 
{ 
    // set the sub form 
    this.Invoke(new MethodInvoker(delegate 
    { 
     SubForm = new ViewForm(); 
    })); 
} 

我想什麼是像火,忘記GUI對象的實例化。

+0

我沒有讀過你的整篇文章,但是你的問題的標題和第一句話很突出。答案是:你不應該在主線程之外的其他任何地方運行UI代碼。這是UI編程中的一條金科玉律。所以,如果你遵循這一點,那麼你就不會有這個問題。 –

+2

如果你有第三方表單在啓動時將UI線程凍結7秒,那麼它有一個主要的bug。要麼不要使用錯誤的第三方表格,要麼讓他們修復錯誤。 – Servy

+0

@ rory.ap雖然這是我的第一個反應,但是多了一部分的代碼顯然是在第三方代碼中,所以OP不是強制執行的規則。 – Servy

回答

0

Here's使用的溶液BackGroundWorker

​​

創建測試兩種形式,在MainForm非常像一個你的樣品和SubView形式在構造一個Threading.Sleep(10000)

+0

這工作完美,我不需要有m顯示爲@Gusman技巧。這將是非常有用的,因爲我有幾個這樣的窗口預加載以在需要時做好準備。 – Franck