我试图在Run
中调用方法script1
。然后从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 :(得分:2)
statusLabel
类拥有Form1
对象,并且应由Form1
类封装和隐藏。为了确保类的良好解耦以及正确的数据隐藏,只有statusLabel
类应该直接访问它。它应该(默认情况下)能够通过名为this.Controls.Find()
的字段访问它(即不需要调用function
(也不应该从Controls
类开始工作,因为该类也不是对象的所有者,也不是script1
属性的所有者。
执行此操作的正确方法是StatusText
类公开StatusTextChanged
属性,以及属性值更改时引发的事件。实现该事件有两种规范方法:
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);
}
}
}
INotifyPropertyChanged
界面请注意,在您的示例中,#2不是一个选项,因为您使用静态类来实现脚本。恕我直言,由于各种原因,这是不可取的,但由于#1是一个非常好的解决方案,所以我不会说明这一点。 :)
第一个看起来像这样:
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
类都继承,并且包含相关事件。然后Form1
类只需要订阅一个基类事件。它还将解决或至少减少让事件处理程序订阅30个不同事件的问题。
当然,在这种情况下,scriptX
类将不知道哪个脚本正在更新文本,但在您的情况下这可能无关紧要。
另请注意,如果 使{{1}}类非静态,则可能会再次遇到必须多次订阅的问题。但这更容易处理,因为在这种情况下你肯定会使用基类,所以很容易将“subscribe,run script,unsubscribe”逻辑推广到辅助方法中。