Electronics DIY blog

DIY is fun and is food for the brain and spirit. Don't be afraid to learn.



Thursday, February 7, 2013

C# Tracing code

Tracing code is a nice way to check your app behaviour when you are running it in a machine without the comfort of your compiler/debugger.
If you have doubts about a region of your code or you want to output information from you app you can simply output Trace messages to check what's going on.

Trace can be done to a file, a control, or any text recipient via a TraceListener based class.

Following my previous articles (1, 2) on C# extensions the following extension is a nice, handy peace of software to keep in your apps or reusable libraries to perform Trace output to any TextBoxBase derived class (ex. TextBox, RichTextBox, etc...).

Did you read my article on cross thread calls? This will make use of that tool to perform in a clean easy way extend the TextBoxBase.AppendText with/without auto scroll in a thread-safe/non thread-safe context. Take a look at this.

namespace Extensions
{
    public static class TextBoxBaseExtensions
    {
        /// <summary>
        /// Appends text to TextBoxBase Control and auto-scrolls to end
        /// </summary>
        /// <param name="tbb">TextBoxBase object</param>
        /// <param name="text">Text to append</param>
        static public void AppendTextAndScroll(this TextBoxBase tbb, string text)
        {
            tbb.AppendText(text);
            tbb.SelectionStart = tbb.Text.Length;
            tbb.ScrollToCaret();
        }

        /// <summary>
        /// Appends text to TextBoxBase Control in a UI Thread safe manner
        /// </summary>
        /// <param name="tbb">TextBoxBase object</param>
        /// <param name="text">Text to append</param>
        public static void SafeAppendText(this TextBoxBase tbb, string text)
        {
            tbb.SafeInvoke(delegate
            {
                tbb.AppendText(text);
            });
        }

        /// <summary>
        /// Appends text to TextBoxBase Control and auto-scrolls to end in a UI Thread safe manner
        /// </summary>
        /// <param name="tbb">TextBoxBase object</param>
        /// <param name="text">Text to append</param>
        public static void SafeAppendTextAndScroll(this TextBoxBase tbb, string text)
        {
            tbb.SafeInvoke(delegate
            {
                tbb.AppendTextAndScroll(text);
            });
        }
    }
}

Sweet.
You can now call on any TextBoxBase derived class any of the above methods.
To make use of this to perform trace listening you can simply do this:

using Extensions
/// <summary>
/// Defines a TextBoxBase Control TraceListener.
/// </summary>
public class TextBoxBaseTraceListener : TraceListener
{
    /// <summary>
    /// Gets or sets the TraceListener Control 
    /// </summary>
    public TextBoxBase Control
    {
        get;
        set;
    }

    /// <summary>
    /// Initializes the TextBoxBaseTraceListener object.
    /// </summary>
    /// <param name="control">The target TextBoxBase control.</param>
    public TextBoxBaseTraceListener(TextBoxBase control)
    {
        this.Control = control as TextBoxBase;
        if (this.Control == null)
        {
            throw new ArgumentException("The argument is not a TextBoxBase control", "control");
        }
    }

    /// <summary>
    /// Captures and display a Trace.Write call.
    /// </summary>
    /// <param name="message">The trace text message.</param>
    public override void Write(string message)
    {
        this.Control.SafeAppendTextAndScroll(message);
    }

    /// <summary>
    /// Captures and display a Trace.WriteLine call. Add NewLine char sequence to the end of the string.
    /// </summary>
    /// <param name="message">The trace text message.</param>
    public override void WriteLine(string message)
    {
        this.Control.SafeAppendTextAndScroll(message + System.Environment.NewLine);
    }
}

And use it like any other trace listener:

TextBoxBaseTraceListener myTracer = new TextBoxBaseTraceListener(richtextBox1); // the target control goes here
Trace.Listeners.Add(myTracer);

With these to lines you now intercept any Trace.Write Trace.WriteLine calls and show the message content.

Easy as pie.

No comments:

Post a Comment