开发者

Access form component from another class

I hope that the title and this simple example says everything.

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)
    {
        U开发者_JAVA技巧pdateLabel("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");
    }
}

When I'm trying to change lable1 from MyClass it does nothing. But I can get to the UpdateLable method from outside, it says Hello to me, it just doesn't change the label.


Use a delegate for setting your label

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();
}


a bit unsure because the example actually leaves some bits unclear... but here is a try:

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

this works as long as MyClass is NOT running on a different thread - otherwise the call to UpdataLabel must be synchronized with the UI thread...

EDIT:

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


Either go with Yahia's way (it has been updated and will work correctly) or try the following (probably overkill for what you're trying to do... whatever that is).

UPDATE:

Based on your comment in the question, you are also doing the work in MyClass on a different thread. Code change is below.

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");
    }
}


After wasting a ton of time on what should be a simple task and trying every answer on stack overflow, I said, if C# wants to make it stupid hard to change the text of a simple label, I am going to come up with a stupid fix.

Here is what you do:

  1. In Form1 or whatever form has the label you want add: public void setStatus() { lblStatus.Text = status; }

    public static string status;
    
  2. Now, add a timer to Form1 and have it run "setStatus();" on every tick

  3. Now, in any class, just write: Form1.status = "Change label to this text";


you need to make both the method MyMethod and the label in question static. But if you do then you cannot access MyMethod through a new instance of the form instead you have to access it directly like Form1.MyMethod(). But if you do make the label the static visual studio will make it non-static one you access the label from the designer so you will have to keep making it static from form1.designer.cs. Also if you do make the label static change every line that refers to any of its properties so if it says this.label1.Text change it to label1.Text. This should give you the desired effect

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜