Cleaven Cleaven - 3 months ago 13
C# Question

Create an outline of a certain color on combobox when selected index is changed

I just wanted to know if in windows forms I can create a red line around the border of a combobox when its changed? Like just a flash of red and then gone again just to show that it was changed. Catch the user's eye or something. I will provide screens to represent what i would like.

If it is possible, please tell me where I can look it up to gain some information on it.

No border
enter image description here
Border flash on change
enter image description here
Border gone again after a second or two
enter image description here

Answer

Anytime the combobox changes, I want to flash a border to indicate it has changed.

The main idea is using a timer and drawing a border for some times. You can draw the border using different solutions. For example you can (1) draw the border on ComboBox or (2) you can draw border on Parent of ComboBox.

In the answer which I posed, I created a MyComboBox and added a FlashHotBorder method which can be called to flash border. Also I added a HotBorderColor property which can be used to set border color.

Flashing Border of ComboBox

To draw a border for ComboBox you can handle WM_Paint message of ComboBox and draw a border for control. Then to flash the border, you need to use a timer and turn on and turn off border for some times:

enter image description here

MyComboBox Code

I've created a FlashHotBorder method which you can call in SelectedIndexChanged event. Also if always you want to flash border when selected index changes, you can call it in OnSelectedIndexChanged. I prefer to call it in event handler. Here is the implementation:

using System.Drawing;
using System.Windows.Forms;
public class MyComboBox : ComboBox
{
    int flash = 0;
    private const int WM_PAINT = 0xF;
    private int buttonWidth = SystemInformation.HorizontalScrollBarArrowWidth;
    public Color HotBorderColor { get; set; }
    private bool DrawBorder { get; set; }
    Timer timer;
    public MyComboBox()
    {
        this.HotBorderColor = Color.Red;
        timer = new Timer() { Interval = 100 };
        timer.Tick += new System.EventHandler(timer_Tick);
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == WM_PAINT && this.DrawBorder)
            using (var g = Graphics.FromHwnd(this.Handle))
            using (var p = new Pen(this.HotBorderColor))
                g.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);
    }
    public void FlashHotBorder()
    {
        flash = 0;
        timer.Start();
    }
    void timer_Tick(object sender, System.EventArgs e)
    {
        if (flash < 10)
        {
            flash++;
            this.DrawBorder = !this.DrawBorder;
            this.Invalidate();
        }
        else
        {
            timer.Stop();
            flash = 0;
            DrawBorder = false;
        }
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing) { timer.Dispose(); }
        base.Dispose(disposing);
    }
}

Then it's enough to use this event handler for SelectedIndexChanged event of eeach combo which you want to flash:

private void myComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    var combo = sender as FlatCombo;
    if (combo != null)
        combo.FlashHotBorder();
}