List Info

Thread: Rich text box appender




Rich text box appender
country flaguser name
United States
2008-04-24 11:12:24
I've often had a need for an appender that would write to a Windows Forms text box. I suppose the reason that none is included in log4net is the required reference to System.Windows.Forms that is not shared by every .NET implementation.
 
I found several text box appenders for older versions of log4net lying about the web. I've taken ideas from them, updated bits of them and wrote an appender that I'm using and I hope might be useful to others.
 
The appender functionality and its configuration are described in the code comments.
 
There are some caveats, of course. This appender requires references to System.Windows.Forms and System.Drawing to compile. Some of the methods used are new in .NET 2.0. The appender should work in .NET 3+ but it hasn't been tested there.
 
Creating a text box appender (that appends to a TextBox control) would be a matter of removing and simplifying much of the functionality of this appender and should be fairly easy to do.

Appender Code:
 

using System;

using System.Windows.Forms;

using System.Drawing;

 

using log4net;

using log4net.Core;

using log4net.Appender;

using log4net.Util;

 

namespace log4net.Appender

{

 &nbsp;  /// <summary>

 &nbsp;  /// Appends logging events to a RichTextBox

 &nbsp;  /// </summary>

 &nbsp;  /// <remarks>

 &nbsp;  /// <para&gt;

 &nbsp;  /// RichTextBoxAppender appends log events to a specified RichTextBox control.

 &nbsp;  /// It also allows the color, font and style of a specific type of message to be set.

 &nbsp;  /// </para&gt;

 &nbsp;  /// <para&gt;

 &nbsp;  /// When configuring the rich text box appender, mapping should be

 &nbsp;  /// specified to map a logging level to a text style. For example:

 &nbsp;  /// </para&gt;

 &nbsp;  /// <code lang="XML" escaped="true">

 &nbsp;  ///  <mapping>

 &nbsp;  /// &nbsp;  <level value="DEBUG" />

 &nbsp;  /// &nbsp;  <textColorName value="DarkGreen" />

 &nbsp;  ///  </mapping>

 &nbsp;  ///  <mapping>

 &nbsp;  /// &nbsp;  <level value="INFO" />

 &nbsp;  /// &nbsp;  <textColorName value="ControlText" />

 &nbsp;  ///  </mapping>

 &nbsp;  ///  <mapping>

 &nbsp;  /// &nbsp;  <level value="WARN" />

 &nbsp;  /// &nbsp;  <textColorName value="Blue" />

 &nbsp;  ///  </mapping>

 &nbsp;  ///  <mapping>

 &nbsp;  /// &nbsp;  <level value="ERROR" />

 &nbsp;  /// &nbsp;  <textColorName value="Red" />

 &nbsp;  /// &nbsp;  <bold value="true" />

 &nbsp;  /// &nbsp;  <pointSize value="10" />

 &nbsp;  ///  </mapping>

 &nbsp;  ///  <mapping>

 &nbsp;  /// &nbsp;  <level value="FATAL" />

 &nbsp;  /// &nbsp;  <textColorName value="Black" />

 &nbsp;  /// &nbsp;  <backColorName value="Red" />

 &nbsp;  /// &nbsp;  <bold value="true" />

 &nbsp;  /// &nbsp;  <pointSize value="12" />

 &nbsp;  /// &nbsp;  <fontFamilyName value="Lucida Console" />

 &nbsp;  ///  </mapping> 

 &nbsp;  /// </code&gt;

 &nbsp;  /// <para&gt;

 &nbsp;  /// The Level is the standard log4net logging level. TextColorName and BackColorName should match

 &nbsp;  /// a value of the System.Drawing.KnownColor enumeration. Bold and/or Italic may be specified, using

 &nbsp;  /// <code&gt;true</code&gt; or <code&gt;false</code&gt;. FontFamilyName should match a font available on the client,

 &nbsp;  /// but if it's not found, the control's font will be used.

 &nbsp;  /// </para&gt;

 &nbsp;  /// <para&gt;

 &nbsp;  /// The RichTextBox property has to be set in code. The most straightforward way to accomplish

 &nbsp;  /// this is in the Load event of the Form containing the control.

 &nbsp;  /// <code lang="C#"&gt;

 &nbsp;  /// private void MainForm_Load(object sender, EventArgs e)

 &nbsp;  /// {

 &nbsp;  /// &nbsp;  log4net.Appender.RichTextBoxAppender.SetRichTextBox(logRichTextBox, "MainFormRichTextAppender");

 &nbsp;  /// }

 &nbsp;  /// </code&gt;

 &nbsp;  /// </para&gt;

 &nbsp;  /// </remarks>

 &nbsp;  /// <author>Stephanie Giovannini</author>

 &nbsp;  public class RichTextBoxAppender : AppenderSkeleton

 &nbsp;  {

 &nbsp; &nbsp; &nbsp;  #region Public Instance Constructor

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Initializes a new instance of the <see cref="RichTextBoxAppender" /> class.

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// The instance of the <see cref="RichTextBoxAppender" /> class can be assigned

 &nbsp; &nbsp; &nbsp;  /// a <see cref="System.Windows.Forms.RichTextBox" /> to write to.

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  public RichTextBoxAppender()

 &nbsp; &nbsp; &nbsp; &nbsp;   ; : base()

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  #endregion

 

  &nbsp; &nbsp; &nbsp; #region Public Instance Properties and Methods

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Reference to RichTextBox that displays logging events

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// This property is a reference to the RichTextBox control

 &nbsp; &nbsp; &nbsp;  /// that will display logging events.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// <para&gt;If RichTextBox is null, no logging events will be displayed.</para&gt;

 &nbsp; &nbsp; &nbsp;  /// <para&gt;RichTextBox will be set to null when the control's containing

 &nbsp; &nbsp; &nbsp;  /// Form is closed.</para&gt;

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  public RichTextBox RichTextBox

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; set

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; if (!object.ReferenceEquals(value, _richtextBox))

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; if (_containerForm != null)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   _containerForm.FormClosed -= new FormClosedEventHandler(containerForm_FormClosed);

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   _containerForm = null;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; }

 

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; if (value != null)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   value.ReadOnly = true;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   value.HideSelection = false;

 

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   _containerForm = value.FindForm();

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   _containerForm.FormClosed += new FormClosedEventHandler(containerForm_FormClosed);

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; }

 

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; _richtextBox = value;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; get

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; return _richtextBox;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Add a mapping of level to text style - done by the config file

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <param name="mapping">The mapping to add</param>

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// Add a <see cref="LevelTextStyle"/> mapping to this appender.

 &nbsp; &nbsp; &nbsp;  /// Each mapping defines the text style for a level.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  public void AddMapping(LevelTextStyle mapping)

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; _levelMapping.Add(mapping);

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Maximum number of characters in control before it is cleared

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  public int MaxBufferLength

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; get { return _maxTextLength; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; set

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; if (value > 0)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; _maxTextLength = value;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  #endregion

 

 &nbsp; &nbsp; &nbsp;  #region Override Implementation of AppenderSkeleton

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Initialize the options for this appender

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// Initialize the level to text style mappings set on this appender.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  public override void ActivateOptions()

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp; base.ActivateOptions();

 &nbsp; &nbsp; &nbsp; &nbsp;   ; _levelMapping.ActivateOptions();

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// This method is called by the <see cref="AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <param name="loggingEvent"&gt;The event to log.</param>

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// Writes the event to the RichTextBox control, if set.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// The format of the output will depend on the appender's layout.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// This method can be called from any thread.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  protected override void Append(LoggingEvent LoggingEvent)

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; if (_richtextBox != null)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; if (_richtextBox.InvokeRequired)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; _richtextBox.Invoke(

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp;  new UpdateControlDelegate(UpdateControl),

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp;  new object[] { LoggingEvent });

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; else

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; UpdateControl(LoggingEvent);

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Delegate used to invoke UpdateControl

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <param name="loggingEvent"&gt;The event to log</param>

 &nbsp; &nbsp; &nbsp;  /// <remarks>This delegate is used when UpdateControl must be

 &nbsp; &nbsp; &nbsp;  /// called from a thread other than the thread that created the

 &nbsp; &nbsp; &nbsp;  /// RichTextBox control.</remarks>

 &nbsp; &nbsp; &nbsp;  private delegate void UpdateControlDelegate(LoggingEvent loggingEvent);

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Add logging event to configured control

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <param name="loggingEvent"&gt;The event to log</param>

 &nbsp; &nbsp; &nbsp;  private void UpdateControl(LoggingEvent loggingEvent)

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; // There may be performance issues if the buffer gets too long

 &nbsp; &nbsp; &nbsp; &nbsp;   ; // So periodically clear the buffer

 &nbsp; &nbsp; &nbsp; &nbsp;   ; if (_richtextBox.TextLength > _maxTextLength)

 &nbsp; &nbsp; &nbsp; &nbsp;    {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; _richtextBox.Clear();

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; _richtextBox.AppendText(string.Format("(earlier messages cleared because log length exceeded maximum of )nn", _maxTextLength));

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 

 &nbsp; &nbsp; &nbsp; &nbsp;   ; // look for a style mapping

 &nbsp; &nbsp; &nbsp; &nbsp;    LevelTextStyle selectedStyle = _levelMapping.Lookup(loggingEvent.Level) as LevelTextStyle;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; if (selectedStyle != null)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; // set the colors of the text about to be appended

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; _richtextBox.SelectionBackColor = selectedStyle.BackColor;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; _richtextBox.SelectionColor = selectedStyle.TextColor;

 

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; // alter selection font as much as necessary

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; // missing settings are replaced by the font settings on the control

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; if (selectedStyle.Font != null)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; // set Font Family, size and styles

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; _richtextBox.SelectionFont = selectedStyle.Font;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; else if (selectedStyle.PointSize > 0 && _richtextBox.Font.SizeInPoints != selectedStyle.PointSize)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; // use control's font family, set size and styles

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; float size = selectedStyle.PointSize > 0.0f ? selectedStyle.PointSize : _richtextBox.Font.SizeInPoints;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; _richtextBox.SelectionFont = new Font(_richtextBox.Font.FontFamily.Name, size, selectedStyle.FontStyle);

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; }

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; else if (_richtextBox.Font.Style != selectedStyle.FontStyle)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; // use control's font family and size, set styles

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; &nbsp; &nbsp; _richtextBox.SelectionFont = new Font(_richtextBox.Font, selectedStyle.FontStyle);

 &nbsp; &nbsp; &nbsp;   &nbsp; &nbsp; &nbsp; &nbsp;}

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 

 &nbsp; &nbsp; &nbsp; &nbsp;   ; _richtextBox.AppendText(RenderLoggingEvent(loggingEvent));

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Remove reference to RichTextBox when container form is closed

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <param name="sender"></param>

 &nbsp; &nbsp; &nbsp;  /// <param name="e"&gt;</param>

 &nbsp; &nbsp; &nbsp;  private void containerForm_FormClosed(object sender, FormClosedEventArgs e)

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; RichTextBox = null;

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Remove references to container form

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  protected override void OnClose()

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; base.OnClose();

 &nbsp; &nbsp; &nbsp; &nbsp;   ; if (_containerForm != null)

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; _containerForm.FormClosed -= new FormClosedEventHandler(containerForm_FormClosed);

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; _containerForm = null;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// This appender requires a <see cref="Layout"/> to be set.

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <value&gt;<c>;true</c></value&gt;

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// <para&gt;

 &nbsp; &nbsp; &nbsp;  /// This appender requires a <see cref="Layout"/> to be set.

 &nbsp; &nbsp; &nbsp;  /// </para&gt;

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  protected override bool RequiresLayout

 &nbsp; &nbsp; &nbsp;  {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; get

 &nbsp; &nbsp; &nbsp; &nbsp;   ; {

 &nbsp; &nbsp; &nbsp; &nbsp;   ; &nbsp; &nbsp; return true;

 &nbsp; &nbsp; &nbsp; &nbsp;   ; }

 &nbsp; &nbsp; &nbsp;  }

 

 &nbsp; &nbsp; &nbsp;  #endregion

 

 &nbsp; &nbsp; &nbsp;  #region Public Static Methods

 

 &nbsp; &nbsp; &nbsp;  /// <summary>

 &nbsp; &nbsp; &nbsp;  /// Assign a RichTextBox to a RichTextBoxAppender

 &nbsp; &nbsp; &nbsp;  /// </summary>

 &nbsp; &nbsp; &nbsp;  /// <param name="richTextBox">;Reference to RichTextBox control that will display logging events</param>

 &nbsp; &nbsp; &nbsp;  /// <param name="appenderName"&gt;Name of RichTextBoxAppender (case-sensitive)</param>

 &nbsp; &nbsp; &nbsp;  /// <returns>True if a RichTextBoxAppender named <code&gt;appenderName</code&gt; was found</returns>

 &nbsp; &nbsp; &nbsp;  /// <remarks>

 &nbsp; &nbsp; &nbsp;  /// <para&gt;This method sets the RichTextBox property of the RichTextBoxAppender

 &nbsp; &nbsp; &nbsp;  /// in the default repository with <code&gt;Name == appenderName</code&gt;.</para&gt;

 &nbsp; &nbsp; &nbsp;  /// </remarks>

 &nbsp; &nbsp; &nbsp;  /// <example>

 &nbsp; &nbsp; &nbsp;  /// <code lang="C#"&gt;

 &nbsp; &nbsp; &nbsp;  /// private void MainForm_Load(object sender, EventArgs e)

 &nbsp; &nbsp; &nbsp;  /// {

 &nbsp; &nbsp; &nbsp;  /// &nbsp;  log4net.Appender.RichTextBoxAppender.SetRichTextBox(logRichTextBox, "MainFormRichTextAppender");