通过静态助手类从另一个类访问GUI

时间:2015-02-20 16:57:28

标签: c# .net winforms

我只是想问下面的代码是否是从另一个类访问GUI的有效方法,或者是不好的做法。我想要做的是将日志消息写入Form1中的RichTextBox。

如果这是不好的做法,最好将我的Form1的引用传递给另一个类,以便能够访问RichTextBox。

我有以下代码从另一个类访问我的Form1中的GUI:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();             
        Logger.Init(this.rtbLog);

        MyOtherClass myOtherClass = new MyOtherClass();
        myOtherClass.DoSomething();
    } 
}

public class MyOtherClass
{
    public void DoSomething()
    {
        Logger.AppendText("text...");
        Logger.AppendText("text...");
        Logger.AppendText("text...");
    }
}

public static class Logger
{
    private static RichTextBox _rtb;

    public static void Init(RichTextBox rtb)
    {
        _rtb = rtb;
    }

    public static void AppendText(String text)
    {
        _rtb.AppendText(text);
        _rtb.AppendText(Environment.NewLine);
    }
}

通过活动(感谢Ondrej):

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();             

        Logger.EntryWritten += Logger_EntryWritten;

        MyOtherClass myOtherClass = new MyOtherClass();
        myOtherClass.DoSomething();
    }

    void Logger_EntryWritten(object sender, LogEntryEventArgs args)
    {           
        rtbLog.AppendText(args.Message);
        rtbLog.AppendText(Environment.NewLine);
    }
}

public class MyOtherClass
{
    public void DoSomething()
    {
        Logger.AppendText("text...");
        Logger.AppendText("text...");
        Logger.AppendText("text...");
    }
}

public static class Logger
{
    public static event EventHandler<LogEntryEventArgs> EntryWritten;

    public static void AppendText(string text)
    {
        var tmp = EntryWritten;
        if (tmp != null)
            tmp(null, new LogEntryEventArgs(text));
    }
}

public class LogEntryEventArgs : EventArgs
{
    private readonly String message;

    public LogEntryEventArgs(String pMessage)
    {
        message = pMessage;
    }

    public String Message
    {
        get { return message; }
    }
}

1 个答案:

答案 0 :(得分:4)

对于一个小小的丢弃项目来说可能没问题,但是否则记录器不应该对使用过的平台有所了解。然后,例如使用事件会很好。无论何时写入新的日志条目,并且对记录的条目感兴趣的消费者都会订阅代表,都会举起活动。

还要小心线程。如果您从不同于UI的线程记录消息,则最终会出现异常,因为您将从禁止的其他线程访问GUI控件。

修改

这些方面的东西。 LogEntryEventArgs是您必须创建的类型,您可以为其提供MessageTimeWrittenSeverity等属性。

public static class Logger
{
    public static event EventHandler<LogEntryEventArgs> EntryWritten;

    public static void AppendText(string text)
    {
        var tmp = EntryWritten;
        if (tmp != null)
            tmp(null, new LogEntryEventArgs(text));
    }
}

consumer:

Logger.EntryWritten += Logger_OnEntryWritten;

void Logger_OnEntryWritten(object sender, LogEntryEventArgs args)
{
    _rtb.AppendText(args.Message);
    _rtb.AppendText(Environment.NewLine);
}

另外,不要忘记在表单上调用Logger_OnEntryWritten的主体,以避免跨线程访问异常(如果您正在考虑使用线程)。