NLog.Windows.Forms 4.2 has been released!

28 Dec 2015

NLog.Windows.Forms 4.2 has been released including a new feature for the RichTextBoxTarget — it is now possible to add clickable links to log messages.

Features

This release contains the following features:

It is now possible to add clickable links to messages show in in the RichTextBox control and receive whole event info in the link click handler. To do this, set target’s newly introduced supportLink parameter to true and use new ${rtb-link} layout renderer to specify link part of the layout. To receive link click events, add a handler to RichTextBoxTarget.LinkClicked event. Use RichTextBoxTarget.GetTargetByControl(RichTextBox control) static method to access the target attached to a specific RichTextBox control.

Not sure how to use it? Here are few examples.

Exception details example

When logging exceptions to RichTextBoxTarget you have to find a compromise between flooding the control with huge stacktraces and missing important information. Not anymore! Now you may long only a short description into textbox, and show whole details when user clicks a link:

Just setup a proper layout (don’t forget to enable supportLinks)

<target xsi:type="RichTextBox"
   layout="${message}${onexception:inner= ${exception:format=Message} ${rtb-link:details}}"
   ....
   supportLinks="true"
   ....
   />

And add a link click handler:

public Form1()
{
    InitializeComponent();
    RichTextBoxTarget.ReInitializeAllTextboxes(this); //more on this later
    RichTextBoxTarget.GetTargetByControl(richTextBox1).LinkClicked += Form1_LinkClicked;
}

private void Form1_LinkClicked(RichTextBoxTarget sender, string linkText, LogEventInfo event)
{
    MessageBox.Show(event.Exception.ToString(), "Exception details", MessageBoxButtons.OK);
}

Focusing at specific item example

Sometimes you may need to not only notify user of some problem (like validation failing), but also help him navigate to the problematic item (for example when the list is huge). In this case you may store item’s id of some sort in the LogEventInfo.Property, turn it into a link and navigate to the item in link click handler:

The layout:

<target xsi:type="RichTextBox"
            layout="${message} ${rtb-link:${event-properties:item=Index}}"
            ....
            supportLinks="true"
            ....
            />

Validation code:

private void validateButton_Click(object sender, EventArgs e)
{
    logger.Info("Validation started");
    foreach (ListViewItem item in listView1.Items)
    {
       if (item.SubItems[1].Text.Contains("bad"))
       {
            logger.Info()
               .Message("Validation failed on line")
               .Property("Index", (int)item.Tag)
               .Write();
            return;
        }
    }
    logger.Info("Validation succeeded");
}

Event handling code:

public Form2()
{
    InitializeComponent();
    RichTextBoxTarget.ReInitializeAllTextboxes(this);
    RichTextBoxTarget.GetTargetByControl(richTextBox1).LinkClicked += Form2_LinkClicked;
}

private void Form2_LinkClicked(RichTextBoxTarget sender, string linkText, LogEventInfo event)
{
    int lineIndex = (int)event.Properties["Index"];
    listView1.EnsureVisible(lineIndex);
    listView1.SelectedIndices.Add(lineIndex);
    listView1.Select();
}

Hope you could find more useful applications of this new feature!

A note on 4.1 release

In case you are not sure what RichTextBoxTarget.ReInitializeAllTextboxes(this) call does, then you might have missed a feature added in 4.1 release. It improves the RichTextBoxTarget functional by allowing it to be configured and initialized before the actual control is created. Check allowAccessoryFormCreation and messageRetention options description in the target’s documentation