2012-03-22 68 views
3

我正在学习C#,我需要的是对其他类(同一名称空间)的窗体上的访问控制。如何访问其他类中的控件

我知道这里有很多关于这个主题的文章,但是没有找到完整的解决方案,所以我在这里写下我想到的,请告诉我 - 这是正确的方法吗?

背景:我在应用程序中有一些“调试”形式,我需要所有其他形式才能将其活动记录到此表单中。有一些ListBox控件,其中所有来自其他表单的日志都被写入。当我(或没有Visual Studio的测试者朋友之一)玩弄应用程序并发生不好的事情时,我可以查看该调试窗体以查看所有详细日志在'错误时刻'之前发生的情况。

我的应用程序的主要形式(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 



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

谢谢!

+0

如果您发现自己经常从他们没有定义的表单中访问控件,很有可能你的UI架构不健全。我建议你阅读MVC和MVVM(维基百科文章是很好的介绍),以了解现代UI交互模式。 – 2012-03-22 23:24:35

回答

3

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

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(); 
+0

Yessss!这正是我想要的!谢谢:-D – Enriqe 2012-03-22 23:45:15

2

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

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

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

如果您需要查看这些消息只是创建并显示调试表单中添加日志消息在负载分配Log.Messages到你的列表框的调试形式。

+0

谢谢,也非常好点! – Enriqe 2012-03-22 23:47:32

0

一种不同的方法将有一个事件接收器,将作为一个发布订阅中心为您调试信息,这样你没有得到所有的地方调试形式的依赖关系,是这样的:

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

这样,那么你可以注册新的听众做不同的事情一样,当一些特定的事件发生,等等,你是不是加上你调试的形式向您发送电子邮件(去耦好:)

+0

这对我来说太过分了(在这个时候)我还不理解那些听众,但是无论如何谢谢你。:-) – Enriqe 2012-03-22 23:51:36

+0

我觉得,只是想提供一种不同的方法。祝你好运 – Jaime 2012-03-23 02:38:14