繁体   English   中英

如何在 WPF 应用程序中使用 RichTextBox 作为 NLog 目标?

[英]How can I use a RichTextBox as a NLog Target in a WPF application?

我阅读了以下帖子,但都没有帮助获得与 Winforms 中相同的将日志从 NLog 打印到 RichTextBox 控件目标的有效方式。

如何在 WPF 应用程序中使用 NLog 的 RichTextBox 目标?

WPF:将 RichTextBox 绑定到记录器 Output

我也浏览了官方论坛,但没有成功(除了阅读上述两个帖子的建议)。

这个想法是将目标添加为:

<target xsi:type="RichTextBox" name="console"
     layout="${longdate:useUTC=true}|${level:uppercase=true}|${logger}::${message}"
     autoScroll="true"
     maxLines="1000000"
     controlName="rtbConsole"
     formName="MyWPFWindowName"
     useDefaultRowColoringRules="true">
</target>

并在 WPF window 中以 MyWPFWindowName 为名称,使用 rtbConsole 添加 RichTextBox 控件。 即使我在加载 winow 后以编程方式创建目标,它也不会使用现有的 rtbConsole 而是创建一个新表单。

因此,感谢您的帮助!

我创建了一个自定义 NLog 目标并将其链接到一个文本框。

public class NlogMemoryTarget : Target
{
    public Action<string> Log = delegate { };

    public NlogMemoryTarget (string name, LogLevel level)
    {
        LogManager.Configuration.AddTarget (name, this);

        LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", level, this));//This will ensure that exsiting rules are not overwritten
        LogManager.Configuration.Reload(); //This is important statement to reload all applied settings

        //SimpleConfigurator.ConfigureForTargetLogging (this, level); //use this if you are intending to use only NlogMemoryTarget  rule
    }

    protected override void Write (AsyncLogEventInfo[] logEvents)
    {
        foreach (var logEvent in logEvents) {
            Write (logEvent);
        }
    }

    protected override void Write (AsyncLogEventInfo logEvent)
    {
        Write (logEvent.LogEvent);
    }

    protected override void Write (LogEventInfo logEvent)
    {
        Log (logEvent.FormattedMessage);
    }
}


public partial class MainWindow
{
    private NlogMemoryTarget _Target;

    public MainWindow ()
    {
        InitializeComponent ();

        this.Loaded += (s, e) => {
            _Target = new NlogMemoryTarget ("text box output", LogLevel.Trace);
            _Target.Log += log => LogText (log);
        };
    }

    private void LogText (string message)
    {
        this.Dispatcher.Invoke ((Action) delegate () {
            this.MessageView.AppendText (message + "\n");
            this.MessageView.ScrollToEnd ();
        });
    }
}

虽然这并不能真正回答你的问题,但我相信这个解决方案更好。 用于在列表视图中显示 NLog 日志的 wpf 控件。 https://github.com/erizet/NlogViewer

正如@mafu 的回答所暗示的:

[创建] 自定义NLog [内存] Target并将其 [链接] 到TextBox

此示例将通过event和事件处理程序委托“链接”它。

将 NLog Memory 目标定义为Type

public class NlogMemoryTarget : Target
{
    public event EventHandler<string> OnLog;

    public NlogMemoryTarget(string name, LogLevel level) : this(name, level, level) {}
    public NlogMemoryTarget(string name, LogLevel minLevel, LogLevel maxLevel)
    {
        // important: we want LogManager.Configuration property assign behaviors \ magic to occur
        //   see: https://stackoverflow.com/a/3603571/1366179
        var config = LogManager.Configuration;

        // Add Target and Rule to their respective collections
        config.AddTarget(name, this);
        config.LoggingRules.Add(new LoggingRule("*", minLevel, maxLevel, this));

        LogManager.Configuration = config;
    }

    [Obsolete]
    protected override void Write(AsyncLogEventInfo[] logEvents)
    {
        foreach (var logEvent in logEvents) {
            Write(logEvent.LogEvent);
        }
    }

    protected override void Write(AsyncLogEventInfo logEvent)
    {
        Write(logEvent.LogEvent);
    }

    protected override void Write(LogEventInfo logEvent)
    {
        OnLog(this, logEvent.FormattedMessage);
    }

    // consider overriding WriteAsyncThreadSafe methods as well.
}

在 WPF Window 控制中的使用

public partial class MainWindow
{
    private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    private NlogMemoryTarget _nlogMemoryTarget;

    public MainWindow()
    {
        InitializeComponent();

        _nlogMemoryTarget = new NlogMemoryTarget("TextBoxOutput", LogLevel.Trace);
        _nlogMemoryTarget.OnLog += LogText;
    }

    private void LogText(object sender, string message)
    {
        this.MessageView.AppendText($"{message}\n");
        this.MessageView.ScrollToEnd();
    }

    private void DoSomething() {
       logger.Trace("DoSomething called!");
    }
}

当您调用DoSomething (或执行logger.Trace )时,您的 memory 目标中的重载方法将执行 - 这会引发事件OnLog 由于您在MainWindow的构造中为OnLog分配了一个事件处理程序LogText ,因此它将执行。

我同意问题中引用的 2 个链接不是最佳的。 (我也不会使用这些解决方案。)

这是我要尝试的:

使用类似于 NLog 的FormControlTarget的算法编写自定义 (WPF) 控件目标

确保注册您的新目标
此外,NLog 的FormHelper可能会有所帮助。

大多数 WinForms 代码应该可以轻松转换为 WPF。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM