如何访问其他类中的控件

时间:2012-03-22 23:13:50

标签: c#

我正在学习C#,我需要的是从其他类(相同的命名空间)对表单进行访问控制。

我知道这里有很多关于这个主题的帖子,但没有找到完全解决方案'愚蠢'所以我在这里写下我想出来的东西,请告诉我 - 这是正确的方法吗?

后台:我的应用中有一些“调试”表单,我需要所有其他表单才能将其活动记录到此表单中。有一些ListBox控件,其中写入了来自其他表单的所有日志。当我(或我的一个没有Visual Studio的测试人员朋友)玩app并且发生了一些不好的事情时,我可以查看调试表单以查看所有详细日志在错误时刻之前发生的事情”。

我的主要应用形式( frmMain ):

namespace myNamespace {

public partial class frmMain : Form {

private frmDebug debug;  // frmDebug is declared in other class
                         // we will hold reference to frmDebug form in 'debug'

public frmMain() {         // constructor of the main form 'frmMain'
  InitializeComponent();
  debug = new frmDebug();  // we create new instance of frmDebug immediately when
}                          // our main form is created (app started) and whole time
                           // of running this app we can access frmDebug from
                           // within frmMain through 'debug' variable


// clicking button 'btnLoggingTest', the log is written 
// in the 'frmDebug' form even if it is closed (not visible)
private void btnLoggingTest_Click(object sender, EventArgs e) {
  debug.Log("log this text for me please");
}

// Click handler of the button 'btnShowDebug' :
private void btnShowDebug_Click(object sender, EventArgs e) {
  debug.ShowDialog();    // here we can show frmDebug (in 'modal' style)
}                        // just to see what log-information is written there


} // frmMain class

} // namespace



这是类 frmDebug 本身的代码: (表单上只放置了一个列表框)

namespace myNamespace {
public partial class frmDebug : Form {

public frmDebug() {
  InitializeComponent();
}

public void Log(string txt) {    // this is the actual 'Log' function (or method)
  this.listBox1.Items.Add(txt);
  Application.DoEvents();        // if the logging takes place in some 
}                                // computing-intensive 'loop' or function,
                                 // (or in my case FTP login and upload process)
                                 // 'DoEvents' ensures every log appears immediately
                                 // after the 'Log()' was called. Otherwise all logs
                                 // would appear together at once, as soon as the 
                                 // computing-intensive 'loop' is finished

} // class frmDebug

} // namespace



我的胃里有一种奇怪的感觉我做错了所以请告诉我如何正确地做到这一点 :)如果没关系,希望它可以帮助像我这样的人。

谢谢!

3 个答案:

答案 0 :(得分:3)

您的应用程序可能有一个名为“Program”的类。在那里你会找到代码

var mainForm = new frmMain();
Application.Run(frmMain);

在此类

中为调试表单创建静态属性
public static frmDebug DebuggingForm { get; private set; }

像这样更改启动代码

DebuggingForm = new frmDebug();
var mainForm = new frmMain();
Application.Run(frmMain);

您可以从其他课程中访问此表单

Program.DebuggingForm.Log("log this text for me please");         
Program.DebuggingForm.Show();

答案 1 :(得分:2)

我认为你不必在内存中保持调试形式。您可以将日志写入某个对象。例如。静态日志:

public static Log
{
    private static List<string> _messages = new List<string>();

    public static Write(string message)
    {
        _messages.Add(message);
    }

    public static IEnumerable<string> Messages 
    { 
       get { return _messages; }
    }
}

您可以通过

从应用程序的每个位置添加日志消息
Log.Write("log this text for me please");

如果您需要查看这些消息,只需创建并显示调试表单:

private void btnShowDebug_Click(object sender, EventArgs e) {
    using (frmDebug debug = new frmDebug())
                debug.ShowDialog();
}  

在加载时以调试形式将Log.Messages分配给列表框。

答案 2 :(得分:0)

另一种方法是使用一个Event Sink作为调试信息的发布订阅中心,这样你就不会在整个地方依赖调试表单,如:

public class EventSink
{
    private static readonly IList<Action<string>> _listeners = new List<Action<string>>();

    public static void RegisterListener(Action<string> listener)
    {
        _listeners.Add(listener);
    }

    public static void RaiseEvent(string message)
    {
        foreach (var l in _listeners)
            l(message);
    }
}
你可以在你的frmDebug的构造函数中执行

EventSink.RegisterListener(msg=>listBox1.Items.Add(msg));

每次需要向调试控制台添加消息时,您都会这样做:

EventSink.RaiseEvent("this is a debug message");

通过这种方式,您可以注册新的侦听器来执行不同的操作,例如在发生某些特定事件时向您发送电子邮件等等。并且您没有使用调试表单(解耦很好:)