CSharp - 通过其他类更新标签

  显示原文与译文双语对照的内容
0 0

我正在尝试在 script1 中调用方法 Run 。 然后从 script1 调用方法 alert 或者 wait,然后尝试更新Form1中的statusLabel 。 但是这个代码有错误。


static Label status = this.Controls.Find("statusLabel", true).FirstOrDefault() as Label;

这里代码仅在 Form1 中工作。 因为 this 在另一个类中返回错误。 也许这是不正确的,你知道更好的解决方案。

P.S 我知道如何解决这个问题( 请参见下面"不是最好的解决方案"),但是代码将是 ~ 10 -30新行。

项目

Form1.cs


public partial class Form1 : Form
{
 private void statusLabel_Click(object sender, EventArgs e)
 {
 }
 private void Form1_Load(object sender, EventArgs e)
 {
 script1.Run();
. . .
 script30.Run();
 }
}

function.cs ( 常用函数)


public class function
{
 static Label statusLabel = this.Controls.Find("statusLabel", true).FirstOrDefault() as Label;

 static public void alert(string str)
 {
 statusLabel.Text = str;
 }

 static public void wait(int sec)
 {
 int i = 0;
 while (i++ <sec)
 {
 statusLabel.Text ="Wait:" + (sec+1-i).ToString();
 Thread.Sleep(1000);
 }
 }
}

script1.cs ( script1.script2.。大约是 30个小型程序)


public class script1
{
 static public void Run()
 {
 function.alert("Script1 is running");
 function.wait(5);
 function.alert("Script1 is done");
 }
}

不是最好的解决方案

在 function.cs 中删除


static Label status = this.Controls.Find("statusLabel", true).FirstOrDefault() as Label;

Form1.cs


public partial class Form1 : Form
{
 private void Form1_Load(object sender, EventArgs e)
 {
 script1.Run(this.statusLabel);
 }
}

function.cs


public class function
{
 private Label _statusLabel;

 public scriptClass(Label statusLabel)
 {
 _statusLabel = statusLabel;
 }
}

script1.cs ( script1.script2.。大约是 30个小型程序)


public class script1
{

 static public void Run(Label statusLabel)
 {
 function _function = new function(statusLabel);
 }
}

时间: 原作者:

0 0

statusLabel 对象由 Form1 类拥有,并且应该被封装和隐藏。 为了确保类的良好分离以及正确的数据隐藏,只有 Form1 类应该直接访问它。 它应该能够通过名为( 例如 )的字段访问它。 不需要调用 this.Controls.Find() ( 在 function 类中也不应该这样做,因为该类也不是对象的所有者,也不是 Controls 属性) 。

执行这里操作的正确方法是 script1 类公开 StatusText 属性,以及在属性值更改时引发的事件。 有两种实现该事件的典型方法:

  1. 实现名为 StatusTextChanged的事件
  2. 实现 INotifyPropertyChanged 命令行接口

在你的示例中,#2 不是一个选项,因为你正在使用 static 类来实现脚本。 因为不同的原因,这是不可以行的,但是由于 #1 是一个完美的解决方案,我不会。 : )

第一个看起来像这样:


class script1
{
 public static string StatusText { get; private set; }
 public static event EventHandler StatusTextChanged;

 static public void Run()
 {
 ChangeStatusText("Script1 is running");
 function.wait(5);
 ChangeStatusText("Script1 is done");
 }

 static void ChangeStatusText(string text)
 {
 StatusText = text;

 EventHandler handler = StatusTextChanged;

 if (handler!= null)
 {
 handler(null, EventArgs.Empty);
 }
 }
}

然后在 Form1 中:


public partial class Form1
{
 private void Form1_Load(object sender, EventArgs e)
 {
 script1.StatusTextChanged += (sender1, e1) => statusLabel.Text = script1.Text;
 script1.Run();
. . .
 script30.StatusTextChanged += (sender1, e1) => statusLabel.Text = script30.Text;
 script30.Run();
 }
}

注意,在上面的例子中,每个 scriptX 类必须重新。 你可以创建一个基类,它的中每个 scriptX 类都继承了一个基类,并且它包含。 那么 Form1 类只需要订阅一个基类事件。 它还将解决或者至少最小化事件处理程序订阅 30个不同事件的问题。

当然,在这种情况下,Form1 类不知道哪个脚本正在更新文本,但也许这并不重要。

同时要注意,如果你不使用 scriptX 类,那么你可能会再次遇到多次订阅的问题。 但这更容易处理,因为在那种情况下,你可以使用基类,因这里很容易将"订阅,运行脚本,取消订阅"逻辑推广。

原作者:
...