C# 如何修复带边框ToolStripStatusLabel中的背景色出血

C# 如何修复带边框ToolStripStatusLabel中的背景色出血,c#,winforms,statusstrip,toolstripstatuslabel,C#,Winforms,Statusstrip,Toolstripstatuslabel,当BorderSides设置为All并且我设置了与所属StatusStrip背景色不同的背景色时,就会出现ToolStripStatusLabel背景色问题:ToolStripStatusLabels背景色在边界外流血-看起来很难看。我尝试将BorderStyle属性设置为除Flat之外的其他设置,但没有成功 在下面添加的屏幕截图中,您可以看到问题-teal中的示例是使用BorderStyle=Adjust在矩形外绘制边框。但不幸的是,边界似乎完全消失了 我想得到的是完全没有流血,就像这个手绘

BorderSides
设置为
All
并且我设置了与所属
StatusStrip
背景色不同的背景色时,就会出现
ToolStripStatusLabel
背景色问题:ToolStripStatusLabels背景色在边界外流血-看起来很难看。我尝试将
BorderStyle
属性设置为除Flat之外的其他设置,但没有成功

在下面添加的屏幕截图中,您可以看到问题-teal中的示例是使用
BorderStyle=Adjust
在矩形外绘制边框。但不幸的是,边界似乎完全消失了

我想得到的是完全没有流血,就像这个手绘的例子

这可以通过设置或继承或重写
ToolStripStatusLabel
的特定方法来实现吗?我对编程解决方案持开放态度,但我不知道从哪里开始,所以欢迎提供任何提示。


通过结合和下面的答案实施解决方案 因为我使用了多个答案,这让我走上了正确的道路,所以我为问题添加了最终的解决方案

我扩展了
ToolStripStatusLabel
类,并重写了
OnPaint
方法。这使我有可能使用类属性,并像正常绘制自己一样绘制它,但不会流血

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);

    }
}
public分部类ToolStripStatusLabel不带颜色出血:ToolStripStatusLabel
{
/// 
///修正错误,以防止出血的背景颜色以外的边界。
/// 
/// 
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
矩形边框矩形=新矩形(0,0,宽度-1,高度-1);
//背景
e、 Graphics.FillRectangle(新的SolidBrush(背景色)、borderRectangle);
//边界(如果需要)
如果(BorderSides!=ToolStripStatusLabelBorderSides.None)
ControlPaint.DrawBorder3D(例如图形、边框矩形、边框样式、(Border3DSide)BorderSides);
//如果需要,可以绘制文本
e、 图形.抽绳(文本,字体,新SolidBrush(前景色),0,0);
}
}

我认为通过设置标签属性无法解决您的问题。你必须做一些自定义绘图

我不知道您正试图如何处理标签,但自定义绘图的最简单方法是使用标签的“绘制”事件:

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);
}
如果您将标签的背景色设置为洋红色,前景色设置为右灰色,这将为您提供手绘示例


还可以扩展ToolStripStatusLabel类并重写onPaint方法。代码基本相同,但在自定义类中有更多选项,例如添加BorderColor属性或类似的内容。

我使用
ControlPaint.DrawBorder3D
进行了一些研究,发现它的背景色也显示为底部和右侧线条

因此,与xfr41的回答类似,我尝试绘制所有者的图形。我的想法是使用系统的例程,但是在剪切区域上放大绘图矩形;这样一来,错误的条纹就完全消失了

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);
}

我喜欢ControlPaint,因为它使用默认的系统颜色,但这也意味着您无法更改它。我想知道的是为什么在事件处理程序中调用base.OnPaint,这不是Form.OnPaint方法吗?哎呀,它已经滑进去了,更正。-是的,它将使用系统颜色,因此与系统的其他配色方案保持“颜色同步”。如果你想要完全的自由,那就不太好。。在每个操作系统版本中,它还具有全套3DBorderstyles。有希望地。(但是,如果截止技巧始终有效,这是另一个问题。)我决定扩展该类并按照建议使用ControlPaint.DrawBorder3D方法重写OnPaint方法,因为它保持与未重写时相同的颜色。我已将此添加到OP中并接受您的回答,因为它引导我找到了正确的路径。我只是想告诉您,我已通过不再依赖e.ClipRectangle修复了解决方案的一部分-因为ClipRectangle的大小并不总是客户端区域的大小(例如,如果您将窗口移到屏幕外)。我现在使用控件的实际宽度和高度,效果很好。你能同时更新你的答案来修正它吗?