2010-10-31 50 views
5

你好 爲什麼我不能從靜態方法訪問我的窗體上的私有控件(例如ListBox)? 如何在這種情況下更新控制?如何從靜態方法更新控件?

編輯1.

我的代碼:

ThreadStart thrSt = new ThreadStart(GetConnected); 
     Thread thr = new Thread(thrSt); 
     thr.Start(); 

static void GetConnected() 
    { 
     //update my ListBox 
    } 

所以它必須是無效的,不PARAM和是靜態的,對不對?

EDIT 2

如果有人需要在WPF 解決方案那麼應該試試這個:

private void GetConnected() 
    { 
     myListBox.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, 
        new Action(() => 
        { 
         myListBox.Items.Add("something"); 
        } 
           ) 
       ); 
    } 
+1

插入你的代碼理解爲什麼要進行更新的靜態方法 – 2010-10-31 20:26:50

+0

爲什麼你定義爲靜態?你是否從任何其他課程訪問此方法? – 2010-10-31 21:01:59

+0

它可以有參數,你可以傳遞它的參數作爲對象數組 – 2010-10-31 21:03:48

回答

2

靜態方法不能訪問實例狀態(如非靜態控制)。無論是從方法聲明中刪除static,或傳遞給控制的引用作爲參數傳遞給方法:

private static void SomeMethod(ListBox listBox) 
{ 
    listBox.Items.Add("Some element"); 
} 

...並調用它像這樣:

SomeMethod(MyListBox); 

更新
有是在UI中執行異步事物的不同方法(現在假設爲winforms)。我建議你看看使用BackgroundWorker(在這裏搜索;大量的例子)。如果你真的想通過自己創建線程來做到這一點,這裏是做的一個方法:

private void SomeMethod() 
{ 
    string newElement = FetchNextElementToAdd(): 
    SafeUpdate(() => yourListBox.Items.Add(newElement)); 
} 

private void SafeUpdate(Action action) 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(action); 
    } 
    else 
    { 
     action(); 
    } 
} 

......並把它叫做:

Thread thread = new Thread(SomeMethod); 
thread.Start(); 

您也可以使用線程游泳池(優於創建自己的線程,因爲你不希望他們很長時間運行):

ThreadPool.QueueUserWorkItem(state => SomeMethod()); 
+0

我必須在另一個線程中調用此方法,所以AFAIK它必須是靜態的,並且必須沒有參數並且必須返回void,對吧? – Saint 2010-10-31 20:37:59

+0

@Saint_pl:我假設你的意思是你想要在一個單獨的線程上調用該方法(如'new Thread(YourMethod)')。如果是這種情況,那麼不,它不需要是靜態的。無參數並返回void是的,但不一定是靜態的。 – 2010-10-31 20:49:05

+0

嗯,這是正確的:)我不知道爲什麼早些時候它沒有工作:) – Saint 2010-10-31 20:58:43

1

你需要的控件的引用傳遞給您的靜態方法,或一些含有這些。靜態方法不能訪問非靜態字段/方法/等。不要聲明你的控件是靜態的,我甚至不知道它是否可能,但如果是這樣,它會導致你不想知道的問題。

2

我剛剛發現了一種新的,不同的方式來從靜態方法更新控件。但我們要選擇唯一的名稱爲我們的控制

foreach (Form tmp in Application.OpenForms) 
       foreach (System.Windows.Forms.Control temp in tmp.Controls) 
        if (temp.Name == "textBox1") 
         temp.Text = "it works :)"; 
10

我在網上找到了另一種答案

寫這個形式類:

static Form1 frm; 

,並在形式的構造函數:

frm = this; 

現在我們可以使用變量「frm」來訪問窗體上的所有控件。

某處一個靜態方法:

frm.myListBox.Items.Add("something"); 
+2

哇!你剛剛救了我的一天。非常感謝! – 2016-06-05 01:06:35

+1

這真棒〜!!!!! – 2017-01-20 04:47:16

0

你不能從一個靜態函數訪問主窗口「這個」,「UI」或任何功能。

爲了解決這個問題,在調用回調函數(靜態函數)之前使主窗口

Mainwindow *THIS; 

的公共指針,分配該指針本

THIS=this; 

現在,你可以使用這個而不是這個。

例如:

THIS->listBox->Items->Add("Some element");