This article is about how to output the logging from Log4Net to a textbox.
It assumes a basic knowledge of Log4Net.
Create a Custom Appender
Create this class in your project, it will automatically get picked up by the Configurator.
public class TextBoxAppender : log4net.Appender.AppenderSkeleton
{
private TextBox _textBox;
public string FormName { get; set; }
public string TextBoxName { get; set; }
protected override void Append(log4net.Core.LoggingEvent loggingEvent)
{
if (_textBox == null)
{
if (String.IsNullOrEmpty(FormName) ||
String.IsNullOrEmpty(TextBoxName))
return;
Form form = Application.OpenForms[FormName];
if (form == null)
return;
_textBox = form.Controls[TextBoxName] as TextBox;
if (_textBox == null)
return;
form.FormClosing += (s, e) => _textBox = null;
}
using (StringWriter writer = new StringWriter())
{
this.Layout.Format(writer, loggingEvent);
_textBox.AppendText(writer.ToString() + Environment.NewLine);
}
}
}
- This class implements the log4Net base appender and overrides the
Append
method. - The properties
FormName
andTextBoxName
are set when loading the configuration (below) - The object
loggingEvent
has a method calledRenderedMessage
which returns just the message, but to get the formatted message (i.e. with the date, level, etc.) use theLayout.Format
method.
Add the Configuration
Add this configuration to your Log4Net configuration (either in your App.config or a custom config)
<log4net>
<appender name="textboxAppender" type="ScreenAppender.TextBoxAppender, ScreenAppender">
<formName value="Form1"/>
<textBoxName value="textBox1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{yyyy-MM-dd HH:mm:ss} %-5level %logger - %message" />
</layout>
</appender>
<root>
<appender-ref ref="textboxAppender"/>
</root>
</log4net>
The properties formName and textBoxName will automatically get passed to the class above and need to be the exact names of the objects (else it won’t find the text box).
All together now
In your code, log as you normally would, and if the form name and textbox name match the configuration, it should look something like this…
Update
I have extended this code by creating a User Control with a RichTextBox to make it reusable (and have color).
I have also removed the need for specifying the form and textbox names in the configuration so as to allow for multiple controls (like pop-ups) using the same appender (although not automatic anymore).
I will post that solution if I get time, but am just letting you know what is possible.