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

C# 通过静态助手类从另一个类访问GUI,c#,.net,winforms,C#,.net,Winforms,我只是想问一下,下面的代码是否是从另一个类访问GUI的有效方法,或者这是一种不好的做法。我想做的是将日志消息写入Form1中的RichTextBox 如果这是一种不好的做法,那么最好将我的Form1的引用传递给另一个类,以便能够访问RichTextBox 我有以下代码从另一个类访问Form1中的GUI: public partial class Form1 : Form { public Form1() { InitializeComponent();

我只是想问一下,下面的代码是否是从另一个类访问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):

公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
Logger.entrywrited+=Logger\u entrywrited;
MyOtherClass MyOtherClass=新的MyOtherClass();
myOtherClass.DoSomething();
}
void Logger_entrywrited(对象发送方,LogEntryEventArgs args)
{           
rtbLog.AppendText(args.Message);
rtbLog.AppendText(Environment.NewLine);
}
}
公共类MyOtherClass
{
公共无效剂量测定法()
{
Logger.AppendText(“文本…”);
Logger.AppendText(“文本…”);
Logger.AppendText(“文本…”);
}
}
公共静态类记录器
{
公共静态事件EventHandler EntryWrited;
公共静态无效文本(字符串文本)
{
var tmp=输入写入;
如果(tmp!=null)
tmp(null,新的LogEntryEventArgs(text));
}
}
公共类LogEntryEventArgs:EventArgs
{
私有只读字符串消息;
公共LogEntryEventArgs(字符串pMessage)
{
message=pMessage;
}
公共字符串消息
{
获取{返回消息;}
}
}

对于一个小的一次性项目来说,这可能没什么问题,但如果不是这样的话,日志记录器应该对所使用的平台一无所知。那么最好以事件为例。每当写入新日志条目时引发事件,对日志条目感兴趣的消费者将订阅委托

还要注意螺纹。如果您记录来自不同于UI的线程的消息,则会出现异常,因为您将从禁止的不同线程访问GUI控件

编辑:

沿着这条线的东西
LogEntryEventArgs
是您必须创建的一种类型,您可以为它提供诸如
Message
TimeWrited
Severity
等属性

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);
}
公共静态类记录器
{
公共静态事件EventHandler EntryWrited;
公共静态无效文本(字符串文本)
{
var tmp=输入写入;
如果(tmp!=null)
tmp(null,新的LogEntryEventArgs(text));
}
}
消费者:
Logger.entrywrited+=Logger_onentrywrited;
void Logger_onentrywrited(对象发送方、LogEntryEventArgs args args)
{
_rtb.AppendText(args.Message);
_rtb.AppendText(Environment.NewLine);
}

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

对于一个小的一次性项目来说,这可能是好的,但否则Logger不应该知道任何关于所用平台的信息。那么最好以事件为例。每当写入新日志条目时引发事件,对日志条目感兴趣的消费者将订阅委托

还要注意螺纹。如果您记录来自不同于UI的线程的消息,则会出现异常,因为您将从禁止的不同线程访问GUI控件

编辑:

沿着这条线的东西
LogEntryEventArgs
是您必须创建的一种类型,您可以为它提供诸如
Message
TimeWrited
Severity
等属性

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);
}
公共静态类记录器
{
公共静态事件EventHandler EntryWrited;
公共静态无效文本(字符串文本)
{
var tmp=输入写入;
如果(tmp!=null)
tmp(null,新的LogEntryEventArgs(text));
}
}
消费者:
Logger.entrywrited+=Logger_onentrywrited;
void Logger_onentrywrited(对象发送方、LogEntryEventArgs args args)
{
_rtb.AppendText(args.Message);
_rtb.AppendText(Environment.NewLine);
}

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

好吧,您可能想进一步分离它。例如,这不适用于跨线程调用。在任何情况下,你都不需要太多的公共静态的东西——把它作为一个日志记录器并不太糟糕,但你最终会发现自己陷入了难以分割或思考的意大利式代码中。将其作为参数传递将使其更加合理。根据您的用例,使记录的信息成为您调用的方法输出的一部分也可能会发生这种情况。将其反转并将UI(或UI实现的接口)传递到记录器中。不要将实际的UI控件传递给您的记录器,因为您不想用特定于UI的逻辑填充记录器逻辑。好吧,您可能想将其进一步分离。例如,这不适用于跨线程调用。在任何情况下,你都不需要太多的公共静态的东西——把它作为一个日志记录器并不太糟糕,但你最终会发现自己陷入了难以分割或思考的意大利式代码中。将其作为参数传递将使其更加合理。根据您的用例,使记录的信息成为您调用的方法输出的一部分也可能会发生这种情况。将其反转并将UI(或UI实现的接口)传递到记录器中。不要将实际的UI控件传递给记录器,因为您不想用特定于UI的逻辑填充记录器逻辑。谢谢!您有关于如何使用事件解决此类场景的链接吗?谢谢!你有一个关于怎么做的链接吗