Click here to Skip to main content
15,891,033 members
Articles / Programming Languages / C#
Tip/Trick

Poor Men's AboutBox with Animated Auto Scroll TextBox

Rate me:
Please Sign up or sign in to vote.
4.17/5 (5 votes)
2 Oct 2014CPOL 13.6K   257   10   3
How to make from a simple TextBox an animated eye candy.

Introduction

The standard AboutBox of Visual Studio contains a TextBox where you can show some useful information about your program. I wanted to implement some animation in it, so I made this simple extension for automatic scrolling.

Image 1

Using the Code

Add AboutBox class to your project, and you can use it as is.

The Code

We need a separate thread for the animation, an event to be able to stop/start it and another event to indicate if the thread is ready.

C#
    partial class AboutBox : Form
    {
        // BackgroundWorker for the animation
        BackgroundWorker scroller = new BackgroundWorker();
        // If this event is signaled, the scrolling will stop
        ManualResetEvent scrollStop = new ManualResetEvent(true);
        // Closing the form should wait till the thread exits
        AutoResetEvent scrollThreadReady = new AutoResetEvent(false);
...

In the constructor, you can fill the TextBox and set the properties of the animation thread:

C#
public AboutBox()
{
    InitializeComponent();
...
    // Add the content of the ReadMe.txt into the TextBox
    string readMeFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReadMe.txt");
    if (File.Exists(readMeFile))
        textBoxDescription.Text = File.ReadAllText(readMeFile);

    // With mouse click you can start/stop the animation
    textBoxDescription.MouseClick += new MouseEventHandler(textBoxDescription_MouseClick);
    // Set scroller thread
    scroller.DoWork += new DoWorkEventHandler(scroller_DoWork);
    scroller.WorkerSupportsCancellation = true;
}

MouseClick event handler will signal the scrollStop event:

C#
/// <summary>
/// MouseClick on textbox stops/starts scrolling
/// </summary>
void textBoxDescription_MouseClick(object sender, EventArgs e)
{
  // WaitOne(0) returns immediately with true if signaled or false if not signaled
  if (scrollStop.WaitOne(0))
    scrollStop.Reset();
  else
    scrollStop.Set();
}

DoWork event handler:

C#
/// <summary>
/// Scroller thread
/// </summary>
void scroller_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        Debug.WriteLine("Scroll thread started.");

        int direction = 1;
        int line = -1;
        while (true)
        {
            if (scroller.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
            // If mouse clicked on the box, we'll wait until the next click.
            scrollStop.WaitOne();

            int maxLine = textBoxDescription.Lines.Length - 1;
            if (line >= -1 && line <= maxLine) line = direction > 0 ? line + 1 : line - 1;
            if (line == 0 && direction < 0) direction = 1;
            if (line == maxLine && direction > 0) direction = -1;

            BeginInvoke((MethodInvoker)(() => ScrollByLine(textBoxDescription, direction)));

            if (!scroller.CancellationPending)
            {
                Thread.Sleep(300);
            }
        }
    }
    finally
    {
        Debug.WriteLine("Scroll thread ended.");
        scrollThreadReady.Set();
    }
}

The very simple scroll method:

C#
/// <summary>
/// Scrolls a textbox by line up or down
/// </summary>
/// <param name="textBox">The textbox control</param>
/// <param name="line">if negative, scrolling will go up, else down</param>
void ScrollByLine(TextBox textBox, int line)
{
    int firstCharIndex = textBox.GetFirstCharIndexOfCurrentLine();
    int lineNumber = textBox.GetLineFromCharIndex(firstCharIndex);
    int lineCount = textBox.Lines.Length;

    lineNumber = lineNumber + line < 0 ?
      0 : (lineNumber + line >= lineCount ?
      lineCount - 1 : lineNumber + line);

    int charIndex = textBox.GetFirstCharIndexFromLine(lineNumber);

    // select the button, so selection in the textbox won't be visible
    okButton.Select();

    // this will do the scrolling
    textBox.Select(0, charIndex);
    textBox.ScrollToCaret();
}

We should set the appropriate events before start and stop the scroller thread. If the window is not visible, we stop the thread.

C#
private void AboutBox_VisibleChanged(object sender, EventArgs e)
{
    if (Visible)
    {
        scrollThreadReady.Reset();
        scroller.RunWorkerAsync();
    }
    else
    {
        scroller.CancelAsync();
        scrollStop.Set();
    }
}

private void AboutBox_FormClosing(object sender, FormClosingEventArgs e)
{
    scroller.CancelAsync();
    scrollStop.Set();
    Debug.WriteLine("Wait for ending scroll thread.");
    scrollThreadReady.WaitOne();
    Debug.WriteLine("Scroll thread ready event received.");
}

That's it.

Points of Interest

With these few changes, you can make your AboutBox a bit special.

History

  • 02.10.2014 Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Hungary Hungary
I'm software developer & scrum master with several years of experience in project and line management.

Comments and Discussions

 
GeneralMy vote of 2 Pin
bekiser3-Oct-14 6:43
bekiser3-Oct-14 6:43 
GeneralRe: My vote of 2 Pin
Akos Mattiassich5-Oct-14 23:32
Akos Mattiassich5-Oct-14 23:32 
If you want to read it, you can click in the Textbox,then scrolling stops immediately.
As I mentioned, it's only a simple eye candy, not a feature which is needed by everyone.

modified 8-Oct-14 5:59am.

GeneralRe: My vote of 2 Pin
John B Oliver13-Oct-14 11:22
John B Oliver13-Oct-14 11:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.