How can I use NLog's RichTextBox Target in WPF application?

有些话、适合烂在心里 提交于 2019-11-27 21:45:01

If you define a RichTextBoxTarget in the config file, a new form is automatically created. This is because NLog initializes before your (named) form and control has been created. Even if you haven't got any rules pointing to the target. Perhaps there is a better solution, but I solved it by creating the target programatically:

using NLog;
//[...]
RichTextBoxTarget target = new RichTextBoxTarget();
target.Name = "RichTextBox";
target.Layout = "${longdate} ${level:uppercase=true} ${logger} ${message}";
target.ControlName = "textbox1";
target.FormName = "Form1";
target.AutoScroll = true;
target.MaxLines = 10000;
target.UseDefaultRowColoringRules = false;
target.RowColoringRules.Add(
    new RichTextBoxRowColoringRule(
        "level == LogLevel.Trace", // condition
        "DarkGray", // font color
        "Control", // background color
        FontStyle.Regular
    )
);
target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Debug", "Gray", "Control"));
target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Info", "ControlText", "Control"));
target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Warn", "DarkRed", "Control"));
target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Error", "White", "DarkRed", FontStyle.Bold));
target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Fatal", "Yellow", "DarkRed", FontStyle.Bold));

AsyncTargetWrapper asyncWrapper = new AsyncTargetWrapper();
asyncWrapper.Name = "AsyncRichTextBox";
asyncWrapper.WrappedTarget = target;

SimpleConfigurator.ConfigureForTargetLogging(asyncWrapper, LogLevel.Trace);

A workaround in the mean time is to use the 3 classes available here, then follow this procedure:

  1. Import the 3 files into your project

  2. If not already the case, use Project > Add Reference to add references to the WPF assemblies: WindowsBase, PresentationCore, PresentationFramework.

  3. In WpfRichTextBoxTarget.cs, replace lines 188-203 with:

        //this.TargetRichTextBox.Invoke(new DelSendTheMessageToRichTextBox(this.SendTheMessageToRichTextBox), new object[] { logMessage, matchingRule });
        if (System.Windows.Application.Current.Dispatcher.CheckAccess() == false) {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => {
                SendTheMessageToRichTextBox(logMessage, matchingRule);
            }));
        }
        else {
            SendTheMessageToRichTextBox(logMessage, matchingRule);
        }
    }
    
    private static Color GetColorFromString(string color, Brush defaultColor) {
        if (defaultColor == null) return Color.FromRgb(255, 255, 255); // This will set default background colour to white.
        if (color == "Empty") {
            return (Color)colorConverter.ConvertFrom(defaultColor);
        }
    
        return (Color)colorConverter.ConvertFromString(color);
    }
    
  4. In your code, configure the new target like this below example:

I hope it helps, but it definitely does not seem to be a comprehensive implementation...

public void loading() {
    var target = new WpfRichTextBoxTarget();
    target.Name = "console";
    target.Layout = "${longdate:useUTC=true}|${level:uppercase=true}|${logger}::${message}";
    target.ControlName = "rtbConsole"; // Name of the richtextbox control already on your window
    target.FormName = "MonitorWindow"; // Name of your window where there is the richtextbox, but it seems it will not really be taken into account, the application mainwindow will be used instead.
    target.AutoScroll = true;
    target.MaxLines = 100000;
    target.UseDefaultRowColoringRules = true;
    AsyncTargetWrapper asyncWrapper = new AsyncTargetWrapper();
    asyncWrapper.Name = "console";
    asyncWrapper.WrappedTarget = target;
    SimpleConfigurator.ConfigureForTargetLogging(asyncWrapper, LogLevel.Trace);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!