将光标移到/点击文章中的句子上,可以查看译文。      显示繁体中文内容    显示简体中文内容

Update label through another class
通过其他类更新标签

I'm trying to call method Run in script1.then from script1 call method alert or wait and try to update statusLabel in Form1.but this code has an error.


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

This code will only work in Form1.because this return error in another classes.maybe it is not correct and you know better solution.

P.S. i know how to solve this problem (see below"Not the best solution"), but the code will be ~ 10 -30 new lines.

Project

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 (Frequently used functions )


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... it is about 30 mini programs )


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

not the best solution

remove in 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... it is about 30 mini programs )


public class script1
{

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

时间: 作者:

The statusLabel object is owned by, and should be encapsulated and hidden by, the Form1 class.to ensure good decoupling of your classes, as well as proper data hiding, only the Form1 class should be directly accessing it.and it should (by default) be able to access it via a field named statusLabel (i.e.no need to call this.Controls.Find() (nor should that even work from the function class, since that class also is not the owner of the object, nor of a Controls property).

The correct way to do this is for the script1 class to expose a StatusText property, and an event that is raised when the property value changes.there are two canonical ways to implement the event :

  1. Implement an event named StatusTextChanged
  2. Implement the INotifyPropertyChanged interface

Note that in your example, #2 is not an option because you are using static classes to implement your scripts.IMHO this is inadvisable for a variety of reasons, but since #1 is a perfectly fine solution i won't belabor that point.: )

The first looks like this :


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

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

Note in the above, each scriptX class has to reimplement the event.you could instead make a base class that each of the scriptX classes inherits, and which contains the event in question.then the Form1 class need only subscribe to the one base class event.it would also address, or at least minimize the hassle of, the issue of leaving event handlers subscribed to 30 different events.

Of course, in this case then the Form1 class won't know which script is updating the text, but maybe that doesn't matter in your case.

Also note that if you did make the scriptX classes non-static, you might then again run into the issue of having to subscribe multiple times.but that is much more easily handled, since it seems certain in that case you'd use a base class, and so it would be easy to generalize the"subscribe, run script, unsubscribe"logic into a helper method.

原作者:
...