从另一个类访问表单组件

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

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时 ,它什么也不做。 但是我可以从外面findUpdateLable方法,它向我表示你好,它不会改变标签。

使用委托来设置您的标签

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

要么以Yahia的方式(它已被更新,并将正常工作)或尝试以下(可能矫枉过正你正在尝试做什么…无论如何)。

更新:

根据您对该问题的评论,您也正在另一个线程上在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"); } } 

有点不确定,因为这个例子实际上留下了一些不清楚的地方……但是这是一个尝试:

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

在浪费了大量的时间来完成一个简单的任务,并尝试每个堆栈溢出的答案之后,我说,如果C#想要改变一个简单的标签的文本变得很难,我会​​想出一个愚蠢的固定。

这是你做的:

  1. 在Form1或任何forms的标签你想要添加:public void setStatus(){lblStatus.Text = status; }

     public static string status; 
  2. 现在,向Form1添加一个计时器,并运行“setStatus();” 在每一个滴答

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

你需要使MyMethod方法和标签都是静态的。 但是,如果你这样做,你不能通过窗体的一个新的实例访问MyMethod,而是你必须直接访问它像Form1.MyMethod()。 但是如果你制作标签的话,静态的visual studio会使它成为非静态的,你可以从devise器访问标签,所以你将不得不从form1.designer.cs继续使用静态标签。 另外,如果您确实使标签静态更改引用其任何属性的每一行,如果它说this.label1.Text将其更改为label1.Text。 这应该给你想要的效果