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

时间:2010-09-14 01:02:50

标签: wpf richtextbox nlog

如何在WPF应用程序中使用RichTextBox Target? 我不希望有一个单独的日志窗口,我希望所有日志消息都在WPF对话框中的richTextBox中输出。

我试过在里面使用带有RichTextBox框的WindowsFormsHost,但这对我不起作用:NLog无论如何都打开了单独的Windows窗体。

2 个答案:

答案 0 :(得分:2)

同时解决方法是使用3个可用类here,然后按照以下步骤操作:

  1. 将3个文件导入项目

  2. 如果不是这种情况,请使用Project > Add Reference添加对WPF程序集的引用:WindowsBase, PresentationCore, PresentationFramework

  3. WpfRichTextBoxTarget.cs中,将第188-203行替换为:

        //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. 在您的代码中,配置新目标,如下所示:

  5. 我希望它有所帮助,但它绝对不是一个全面的实施......

    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);
    }
    

答案 1 :(得分:-2)

如果在配置文件中定义RichTextBoxTarget,则会自动创建新表单。这是因为NLog在创建(命名)表单和控件之前初始化。即使你没有任何指向目标的规则。也许有一个更好的解决方案,但我通过以编程方式创建目标来解决它:

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);