Howto fix Backgroundcolor bleeding in bordered ToolStripStatusLabel

996 Views Asked by At

I have a problem with a ToolStripStatusLabel which occurs when the BorderSides is set to All and I set a Background Color different to the owning StatusStrip Background Color: The ToolStripStatusLabels Backgroundcolor bleeds outside the border - which looks pretty ugly. I tried to set the BorderStyle property to other settings than Flat without success.

In the screenshot added below, you see the issue - the example in teal is with BorderStyle = Adjust to get the border drawn outside the rectangle. But unfortunately the border dissappears completely.

Different BorderStyles won't help

What I would like to get is no bleeding at all like in this hand-drawn example.

enter image description here

Is this possible to do by a setting or by inheriting or overriding a specific method of the ToolStripStatusLabel? I'm open to programmatical solutions, but I don't know where to start from, so any hints would be welcome.


Implemented Solution by combining x4rf41 and TaWs answers below

Since I made use of multiple answers which led me on the right track, I added the final solution to the question.

I extended the ToolStripStatusLabel class and overrode the OnPaint method. This gave me the possibility to make use of the classes properties and draw it as it would draw itself normally but without the bleeding.

public partial class ToolStripStatusLabelWithoutColorBleeding : ToolStripStatusLabel
{
    /// <summary>
    /// Bugfix to prevent bleeding of background colors outside the borders.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    {
        Rectangle borderRectangle = new Rectangle(0, 0, Width - 1, Height - 1);

        // Background
        e.Graphics.FillRectangle(new SolidBrush(BackColor), borderRectangle);

        // Border (if required)
        if (BorderSides != ToolStripStatusLabelBorderSides.None)
            ControlPaint.DrawBorder3D(e.Graphics, borderRectangle, BorderStyle, (Border3DSide)BorderSides);

        // Draw Text if you need it
        e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), 0,0);

    }
}
2

There are 2 best solutions below

2
On BEST ANSWER

I don't think that your problem can be solved by setting the labels properties. You have to do some custom drawing.

I don't know exactly what you are trying to do with your labels but the easiest way for custom drawing is to use the paint event of the label:

private void toolStripStatusLabel1_Paint(object sender, PaintEventArgs e)
{
    // Use the sender, so that you can use the same event handler for every label
    ToolStripStatusLabel label = (ToolStripStatusLabel)sender;
    // Background
    e.Graphics.FillRectangle(new SolidBrush(label.BackColor), e.ClipRectangle);
    // Border
    e.Graphics.DrawRectangle(
        new Pen(label.ForeColor),  // use any Color here for the border
        new Rectangle(e.ClipRectangle.Location,new Size(e.ClipRectangle.Width-1,e.ClipRectangle.Height-1))
    );
    // Draw Text if you need it
    e.Graphics.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), e.ClipRectangle.Location);
}

this will give you your hand-drawn example if you set the BackColor of the label to magenta and the ForeColor to the right gray.

You can also extend the ToolStripStatusLabel class and override the onPaint method. The code would be pretty much the same, but you have more options in the custom class, like adding a BorderColor property or something like that.

2
On

I played around a little using ControlPaint.DrawBorder3D and found that it too has the BackColor showing as a bottom and right line.

So, similar to xfr41's answer, I tried to do owner-drawing. My idea was to use the system's routines, but to enlarge the drawing rectangle over the clipping area; this way the wrong stripes are lost altogether..

private void toolStripStatusLabel1_Paint(object sender, PaintEventArgs e)
{
    Rectangle r = e.ClipRectangle; 
    Rectangle r2 = new Rectangle(r.X, r.Y, r.Width + 1, r.Height + 1);
    ControlPaint.DrawBorder3D(e.Graphics, r2 , Border3DStyle.SunkenInner);
}