Как я могу использовать NLog RichTextBox Target в приложении WPF? - PullRequest
2 голосов
/ 14 сентября 2010

Как я могу использовать RichTextBox Target в приложении WPF? Я не хочу иметь отдельное окно с журналом, я хочу, чтобы все сообщения журнала выводились в richTextBox, расположенном в диалоговом окне WPF.

Я пытался использовать WindowsFormsHost с коробкой RichTextBox внутри, но у меня это не получалось: NLog все равно открыл отдельную форму Windows.

Ответы [ 2 ]

2 голосов
/ 10 октября 2011

Обходной путь в настоящее время заключается в использовании 3 доступных классов здесь , а затем выполните следующую процедуру:

  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. В вашем коде настройте новую цель, как показано в следующем примере:

Надеюсь, это поможет, но это определенно не кажется всеобъемлющей реализацией ...

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);
}
0 голосов
/ 18 марта 2011

Если вы определяете 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);
...