另一种方法是让 Class1 引发一个 Event,其中包含标签的名称和将其更改为的字符串。您的表单将接收事件,找到标签本身,并更新值。这样 Class1 永远不需要对 Form1 或任何标签的引用。这仍然是一个糟糕的设计,因为您需要知道标签的名称,但无论如何这就是您要走的方向。
这是 Class1 的样子:
public class Class1
{
public delegate void dlgChangeLabel(string lblName, string newValue);
public event dlgChangeLabel ChangeLabel;
public void ChangeLabelText()
{
if (ChangeLabel != null)
{
ChangeLabel("label2", "SurName");
}
}
}
回到 Form1,我们需要在创建 Class1 实例时订阅 ChangeLabel() 事件:
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
Class1 change = new Class1();
change.ChangeLabel += Change_ChangeLabel;
change.ChangeLabelText();
}
private void Change_ChangeLabel(string lblName, string newValue)
{
// see if we have a Label with the desired name:
Control[] matches = this.Controls.Find(lblName, true);
if (matches.Length > 0 && matches[0] is Label)
{
Label lbl = (Label)matches[0];
ChangeLabel(newValue, lbl); // update it in a thread safe way
}
}
private void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
}
显示 Class1 的创建和在 Form Load() 期间连接其事件的替代版本,因此它不附加到按钮处理程序:
public partial class Form1 : Form
{
private Class1 change = new Class1();
private void Form1_Load(object sender, EventArgs e)
{
change.ChangeLabel += Change_ChangeLabel;
}
private void Change_ChangeLabel(string lblName, string newValue)
{
Control[] matches = this.Controls.Find(lblName, true);
if (matches.Length > 0 && matches[0] is Label)
{
Label lbl = (Label)matches[0];
ChangeLabel(newValue, lbl);
}
}
private void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
}
现在您只需以某种方式在 Class1 中引发该事件。在你提出之前确保它有一个订阅者(不为空):
// in Class1
private void Foo()
{
if (ChangeLabel != null)
{
ChangeLabel("label2", "SurName");
}
}