引用其他类中的Windows窗体元素

我是Windows Form编程的新手,我遇到了一个问题。

我有一个窗体Form1 ,带有一个文本框: tbx_Log

在同一个项目的另一个类中,我想写一些东西到日志文本框,但我不能在该类中引用tbx_Log。 我怎样才能做到这一点?

访问其他类实例(对象)中的对象是错误的样式并且违反了数据封装。 向Form1添加一个方法:

 public void SetLogText(String text) { tbx_Log.Text = text; } 

这样,您可以通过使用其他控件或稍后记录到文件来更改方法的实现,而无需修改所有调用站点。 总是试着让类外的代码不要知道里面的内容。 类实现应该是外部代码的“黑盒子”。

您需要将文本框设置为公共(不推荐)或向表单类添加公共方法,该方法将字符串写入文本框(更好)。

 public class Form1 { protected Textbox tbx_Log; public void Log(string str) { tbx_Log.Text += str + Environment.NewLine; } } public class Program { private void DoStuff() { Form1 myForm = new Form1(); //Make form visible, etc... myForm.Log("Test Log"); } } 

我建议您在Form类上创建一个写入日志文本框的方法。 然后,您将该方法作为委托(回调)传递给您的非Form类。 这为您提供了更多的灵活性。 例如,如果您想从不同的类调用同一个类,并且您希望对日志信息执行不同的操作(例如将其写入文件),则可以传递不同的回调函数。

我建议至少在表单中添加一个负责执行更新的方法,而不是直接引用tbx_Log。 然后,您可以为您的类提供对Form的引用,并让您的类调用Forms日志记录function,该function又将文本添加到文本框中。

我至少说过,因为您可能希望定义一个接口并使您的Form或更高版本的更具体的日志类实现接口,并使您的类与实现定义接口的任何内容进行交互。

您可以在表单上创建一个公共方法。 并且如果从与UI线程不同的线程调用它,也使其成为线程安全的。

其他类如何访问您的方法取决于您的应用程序的工作方式以及表单类与其他类之间的关系。

 public void SetText(string text) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.tbx_Log.Text = text; } } 

有关winforms上线程安全调用的完整示例和说明,请查看MSDN ,它还说明如何使用BackgroundWorker来实现线程安全,这是执行此操作的首选方法。