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.
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.
partial class AboutBox : Form
{
BackgroundWorker scroller = new BackgroundWorker();
ManualResetEvent scrollStop = new ManualResetEvent(true);
AutoResetEvent scrollThreadReady = new AutoResetEvent(false);
...
In the constructor, you can fill the TextBox
and set the properties of the animation thread:
public AboutBox()
{
InitializeComponent();
...
string readMeFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReadMe.txt");
if (File.Exists(readMeFile))
textBoxDescription.Text = File.ReadAllText(readMeFile);
textBoxDescription.MouseClick += new MouseEventHandler(textBoxDescription_MouseClick);
scroller.DoWork += new DoWorkEventHandler(scroller_DoWork);
scroller.WorkerSupportsCancellation = true;
}
MouseClick
event handler will signal the scrollStop
event:
void textBoxDescription_MouseClick(object sender, EventArgs e)
{
if (scrollStop.WaitOne(0))
scrollStop.Reset();
else
scrollStop.Set();
}
DoWork
event handler:
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;
}
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:
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);
okButton.Select();
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.
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