2010-09-14 17 views
2

Comment utiliser RichTextBox Target dans une application WPF? Je ne veux pas avoir une fenêtre séparée avec le journal, je veux que tous les messages de journal soient sortis dans richTextBox situé dans la boîte de dialogue WPF.Comment puis-je utiliser la cible RichTextBox de NLog dans une application WPF?

J'ai essayé d'utiliser WindowsFormsHost avec la boîte RichTextBox à l'intérieur mais cela n'a pas fonctionné pour moi: NLog a ouvert le formulaire Windows séparé de toute façon.

Répondre

-2

Si vous définissez un objet RichTextBoxTarget dans le fichier de configuration, un nouveau formulaire est automatiquement créé. C'est parce que NLog s'initialise avant que votre formulaire (nommé) et votre contrôle aient été créés. Même si vous n'avez aucune règle pointant vers la cible. Peut-être il y a une meilleure solution, mais je l'ai résolu en créant la cible 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); 
+5

Ceci ne ne fonctionne pas avec WPF. –

2

Une solution de contournement dans le temps moyen est d'utiliser les 3 classes disponibles here, puis suivez cette procédure:

  1. Importer les 3 fichiers dans votre projet

  2. Si pas déjà le cas, utilisez Project > Add Reference d'ajouter des références aux assemblées WPF: WindowsBase, PresentationCore, PresentationFramework.

  3. En WpfRichTextBoxTarget.cs, remplacer les lignes 188-203 avec:

    //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. Dans votre code, configurez la nouvelle cible comme ceci exemple ci-dessous:

J'espère que cela aide, mais définitivement ne semble pas être une mise en œuvre complète ...

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

J'ai créé un exemple de projet et je l'ai attaché à [ticket] (https://nlog.codeplex.com/workitem/6272), pour ceux qui ont besoin de voir les changements dans l'action. Changements mineurs pour accommoder à mon goût ;-) –