2011-07-23 78 views
2

我希望標題和這個簡單的例子能說明一切。從另一個類訪問表單組件

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public void UpdateLabel(string str) 
    { 
     label1.Text = str; 
     MessageBox.Show("Hello"); 
    } 

    private void buttonIn_Click(object sender, EventArgs e) 
    { 
     UpdateLabel("inside"); 
    } 

    private void buttonOut_Click(object sender, EventArgs e) 
    { 
     MyClass Outside = new MyClass(); 
     Outside.MyMethod(); 
    } 
} 

public class MyClass 
{ 
    public void MyMethod() 
    { 
     Form1 MyForm1 = new Form1(); 
     MyForm1.UpdateLabel("outside"); 
    } 
} 

當我試圖改變lable1MyClass的它什麼都不做。但是我可以從外部獲得UpdateLable方法,它向我表示你好,它不會更改標籤。

+2

瞭解類和類的實例之間的區別。這是「狗」和「我的狗菲多」之間的區別。 –

+0

好吧,我明白了,我的代碼完全錯了。那麼如何從課堂上更改該標籤? – cozzy

+0

你不想改變'Class'關鍵字(我假設這就是'label'的意思)。也許只是告訴我們你想要做什麼(更多背景),我們可以幫助你。 –

回答

6

使用委託用於設置標籤

public class MyClass { 
    Action<String> labelSetter; 

    public MyClass(Action<String> labelSetter) { 
     this.labelSetter = labelSetter; 
    } 

    public void MyMethod() { 
     labelSetter("outside"); 
    } 
} 

public void buttonOut_Click(object sender, EventArgs e) { 
    var outside = new MyClass(UpdateLabel); 
    outside.MyMethod(); 
} 
+0

比我的事件例子更優雅。 +1 –

2

有點不確定,因爲實際例子留下一些位不清......但這裏是一個嘗試:

public class MyClass 
{ 
    public void MyMethod(Form1 F) 
    { 
     F.UpdateLabel("outside"); 
    } 
} 

這個只要可以作爲MyClass的是不是在不同的線程運行 - 否則調用UpdataLabel必須與UI線程同步...

編輯:

private void buttonOut_Click(object sender, EventArgs e) 
{ 
    MyClass Outside = new MyClass(); 
    Outside.MyMethod(this); 
} 
+0

thr ref實際上並不需要......你是對的...... – Yahia

+0

它不起作用。 – cozzy

+0

什麼不行?是否有異常/錯誤消息...? – Yahia

3

無論用Yahia's方式(已更新,並能正常工作)去,或嘗試ŧ他追隨(可能矯枉過正,你試圖做什麼......無論如何)。

UPDATE:

基於對這個問題的評論,你也做不同的線程在MyClass的工作。代碼更改如下。

public partial class Form1 : Form 
{ 
    // keep a reference to a MyClass object for your Form's lifetime 
    private MyClass _myClass; 

    public Form1() 
    { 
     InitializeComponent(); 

     // Intstantiate your MyClass object so you can use it. 
     _myClass = new MyClass(); 

     // Register to the MyClass event called UpdateLabel. 
     // Anytime MyClass raises the event, your form will respond 
     // by running the UpdateLabelFromMyClass method. 
     _myClass.UpdateLabel += UpdateLabelFromMyClass; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     // Call MyMethod in your MyClass object. It will raise 
     // the UpdateLabel event. 

     // update, you are calling this on a background thread? 
     _myClass.MyMethod(); 
    } 

    void UpdateLabelFromMyClass(string message) 
    { 
     // Update your label with whatever message is passed in 
     // from the MyClass.UpdateLabel event. 

     // UPDATE: If called from a background thread you'll need this: 
     this.BeginInvoke((Action) (()=> 
     { 
      label1.Text = message; 
     }));    
    } 
} 

public class MyClass 
{ 
    // An event that can be raised, allowing other classes to 
    // subscribe to it and do what they like with the message. 
    public event Action<string> UpdateLabel; 

    public void MyMethod() 
    { 
     // Raise the UpdateLabel event, passing "Outside" as 
     // the message. 
     UpdateLabel("Outside"); 
    } 
} 
+0

它的工作原理,但它給我是一種新形式。第一個的克隆 – cozzy

+0

@cozzy:如果您試圖更新包含對MyClass對象的引用的Form1對象的實例,爲什麼不嘗試在MyClass中引發一個事件並使Form1響應它呢?如果您願意,我可以發佈樣本。 –

-1

您需要使MyMethod方法和問題標籤都是靜態的。但是,如果你這樣做,那麼你不能通過表單的一個新實例訪問MyMethod,而必須直接像Form1.MyMethod()那樣訪問它。但是,如果您製作標籤,靜態Visual Studio將使其成爲非靜態標籤,您可以從設計器訪問標籤,因此您必須從form1.designer.cs繼續使其成爲靜態標籤。此外,如果您確實使標籤靜態更改引用其任何屬性的每一行,那麼如果它說this.label1.Text將其更改爲label1.Text。這應該會給你想要的效果

+0

-1:不需要靜態。 –

0

在浪費了大量時間之後,應該是一個簡單的任務,並嘗試每個堆棧溢出的答案,我說,如果C#想要使它變得很難改變一個簡單的文本標籤,我會想出一個愚蠢的解決方案。

這裏是你做什麼:

  1. 在Form1或任何形式有你想要添加的標籤: 公共無效setStatus(){ lblStatus。文本=狀態; }

    public static string status; 
    
  2. 現在,一個計時器添加到Form1,並讓它運行 「setStatus();」在每個tick上

  3. 現在,在任何課堂上,只需寫: Form1.status =「將標籤更改爲此文本」;