从另一个类访问表单组件

时间:2011-07-23 23:33:48

标签: c# forms class

我希望标题和这个简单的例子说明一切。

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

当我尝试从 MyClass 更改 lable1 时,它什么也没做。但是我可以从外面看到 UpdateLable 方法,它对我说你好,它只是不会改变标签。

5 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:3)

要么采用Yahia's方式(它已经更新并且可以正常工作)或尝试以下方法(对于你正在尝试做的事情可能有点过分......无论是什么)。

<强>更新

根据你在问题中的评论,你也在不同的线程上在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");
    }
}

答案 2 :(得分: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);
}

答案 3 :(得分:0)

在浪费了大量时间应该是一个简单的任务并尝试堆栈溢出的每一个答案后,我说,如果C#想要改变一个简单标签的文本很难愚蠢,我会上来愚蠢的修复。

以下是您的工作:

  1. 在Form1或任何具有您想要添加标签的表单中:     public void setStatus()     {         lblStatus.Text = status;     }

    public static string status;
    
  2. 现在,向Form1添加一个计时器,让它运行“setStatus();”在每个刻度

  3. 现在,在任何课程中,只需写:     Form1.status =“将标签更改为此文本”;

答案 4 :(得分:-1)

你需要将方法MyMethod和问题标签都设为静态。但是,如果您这样做,则无法通过表单的新实例访问MyMethod,而是必须直接访问它,如Form1.MyMethod()。但是,如果您确实制作了标签,静态visual studio将使其成为非静态标签,您可以从设计器访问标签,因此您必须从form1.designer.cs继续使其保持静态。此外,如果您确实使标签静态更改引用其任何属性的每一行,那么如果它说this.label1.Text将其更改为label1.Text。这应该会给你带来预期的效果