Mike Webb Mike Webb - 3 months ago 20
C# Question

How do I program a "flash" effect when updating text boxes in a windows form with C#?

What I have is a Windows form, in C#, with 7 text boxes. Each text box updates 2 or 3 others when its value is changed and accepted. What I want to do is somehow take those text boxes that need to be updated and make them "flash" with a light back color or something. The purpose is to show the user what is being updated with an added bit of flair.

I'm not sure if there is an easy way to do this and that is why I'm asking here. I can use a timer, a while loop, and a back color with a decreasing alpha channel on the text box control back color, I think, but I want to see if there is a better way.

jQuery UI has a "Highlight" effect that shows what I want to accomplish (although I want mine to be a bit slower). Just go here to the jQuery UI Effects Demo page, select "highlight" from the drop-down box in the window, and click "Run Effect".

Edit

I had to go with my own solution based on my time and resource constraints, but text boxes do not support transparent colors as mentioned by Hans Passant. So, I used a self-stopping timer that increases the R, G, and B values until the control is completely white (R=255, G=255, B=255);

Edit 2

Wound up recoding the flash event as an extension method using a variation of George Johnston's solution after we updated to .NET 4.0. This is a much cleaner solution, I feel, and the extension method makes it automatically available to anyone

using
it.

Answer

You could spin off a seperate thread per flashing textbox as to not block your form from being used during the flashing of your textbox(s). Be sure to invoke your form as spinning of the thread will require cross threading. Full solution below.

private void Form1_Load(object sender, EventArgs e)
{
    // textBox1 is the control on your form.
    // 1000 is the total interval between flashes
    // Color.LightBlue is the flash color
    // 10 is the number of flashes before the thread quits.
    Flash(textBox1, 1000,Color.LightBlue,10);
    Flash(textBox2, 1500,Color.Green,10);
    Flash(textBox3, 100,Color.Red,10);
    Flash(textBox4, 500,Color.Brown,10);
    Flash(textBox5, 200,Color.Pink,10);
}

public void Flash(TextBox textBox, int interval, Color color, int flashes)
{
    new Thread(() => FlashInternal(textBox, interval, color, flashes)).Start();
}

private delegate void UpdateTextboxDelegate(TextBox textBox, Color originalColor);
public void UpdateTextbox(TextBox textBox, Color color)
{
    if (textBox.InvokeRequired)
    {
        this.Invoke(new UpdateTextboxDelegate(UpdateTextbox), new object[] { textBox, color });
    }
    textBox.BackColor = color;
}

private void FlashInternal(TextBox textBox, int interval, Color flashColor, int flashes)
{
    Color original = textBox.BackColor;
    for (int i = 0; i < flashes; i++)
    {

        UpdateTextbox(textBox, flashColor);
        Thread.Sleep(interval/2);
        UpdateTextbox(textBox, original);
        Thread.Sleep(interval/2);
    }
}

This avoids having to put supporting timer controls on your form.