C# – Change border color and appearance for WinForms control

c++winforms

When the user will hover the label, it will add a top-border and bottom-border to the label.

Something similar to this: http://ianlunn.github.io/Hover/ -> Border Transitions
-> Underline From Center.

However, I only know how to define the normal border. I can't even change the color of the border, his width and more…

This is what I achieved so far:

designer.cs:

this.label1.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.label1.Font = new System.Drawing.Font("Arial", 16F, System.Drawing.FontStyle.Bold);
this.label1.Location = new System.Drawing.Point(124, 187);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(217, 65);
this.label1.TabIndex = 0;
this.label1.Text = "Something Cool";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label1.MouseHover += new System.EventHandler(this.label1_MouseHover);
this.label1.MouseLeave += new System.EventHandler(this.label1_MouseLeave);

cs:

private void label1_MouseHover(object sender, EventArgs e)
{
    label1.BorderStyle = BorderStyle.FixedSingle;
    label1.Font = new Font("Arial", 18, FontStyle.Bold);
}

private void label1_MouseLeave(object sender, EventArgs e)
{
    // initialize
    label1.BorderStyle = BorderStyle.None;
    label1.Font = new Font("Arial", 16, FontStyle.Bold);
}

Best Solution

At first I suggest you to use the label1_MouseEnter() event instead of the label1_MouseHover() event. Since the hover event constantly fires while you are hovering label1. Thats unnecessary because you will change the looking of label1 just when you enter the label and change it back to the default one, once you leave it. So MouseEnter() is your preferred choice.

We will define a bool variable to check if a surroinding border shell be drawn around label1. We change it's value in the MouseEnter() and MouseLeave() event.

bool changeBorder;

In those events we will call label1.Refresh(), which redraws the control, so it's Paint() event will be fired.

private void label1_MouseEnter(object sender, EventArgs e)
{
    changeBorder = true;
    label1.Refresh();
}

private void label1_MouseLeave(object sender, EventArgs e)
{
    changeBorder = false;
    label1.Refresh();
}

Now we validate if a new special border shell be drawn or not. If so we use the ControlPaint class with it's DrawBorder() method to draw a custom border of the size of label1's Rectangle. You can modify this border as you wish to. If we don't want to draw this special border, we draw a default border. What simply has the color of the Form's Backcolor, so it seems like there isn't any border around label1.

private void label1_Paint(object sender, PaintEventArgs e)
{
    if (changeBorder)
    {
        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle,
                      Color.Red, 0, ButtonBorderStyle.Solid,
                      Color.Red, 2, ButtonBorderStyle.Solid,
                      Color.Red, 0, ButtonBorderStyle.Solid,
                      Color.Red, 2, ButtonBorderStyle.Solid);
    }
    else
        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, this.BackColor, ButtonBorderStyle.None);
    }

In the method parameters for ControlPaint.DrawBorder() be aware of the 0 instead of the 2. The parameters of ControlPaint.DrawBorder() for the rectangles width are as followed:

  1. int leftWidth
  2. int topWidth
  3. int rightWidth
  4. int bottowmWidth

That's why I set as the first and third the value 0 so no border will be drawn on the right and left side. You can adjust that according to your needs.