[英]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
和事件处理程序委托“链接”它。
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.
}
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.