从另一个类访问表单组件
我希望标题和这个简单的例子能说明一切。
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#想要改变一个简单的标签的文本变得很难,我会想出一个愚蠢的固定。
这是你做的:
-
在Form1或任何forms的标签你想要添加:public void setStatus(){lblStatus.Text = status; }
public static string status;
-
现在,向Form1添加一个计时器,并运行“setStatus();” 在每一个滴答
-
现在,在任何课堂上,只要写:Form1.status =“将标签更改为此文本”;
你需要使MyMethod方法和标签都是静态的。 但是,如果你这样做,你不能通过窗体的一个新的实例访问MyMethod,而是你必须直接访问它像Form1.MyMethod()。 但是如果你制作标签的话,静态的visual studio会使它成为非静态的,你可以从devise器访问标签,所以你将不得不从form1.designer.cs继续使用静态标签。 另外,如果您确实使标签静态更改引用其任何属性的每一行,如果它说this.label1.Text将其更改为label1.Text。 这应该给你想要的效果