vb.net 带彩色边框的 Winforms groupbox

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21824467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 16:47:01  来源:igfitidea点击:

Winforms groupbox with colored border

vb.netwinformsgroupbox

提问by Matthias

I have used the following code to create a groupbox with colored borders:

我使用以下代码创建了一个带有彩色边框的分组框:

Public Class BorderGroupBox
    Inherits GroupBox

    Private _borderColor As Color
    Private _borderWidth As Integer
    Private _borderStyle As ButtonBorderStyle

    ...

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim tSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font)
        Dim borderRect As Rectangle = e.ClipRectangle
        borderRect.Y = CInt((borderRect.Y + (tSize.Height / 2)))
        borderRect.Height = CInt((borderRect.Height - (tSize.Height / 2)))
        ControlPaint.DrawBorder(e.Graphics, borderRect, _borderColor, _borderWidth, _borderStyle, BorderColor, _borderWidth, _borderStyle, BorderColor, _borderWidth, _borderStyle, BorderColor, _borderWidth, _borderStyle)
        Dim textRect As Rectangle = e.ClipRectangle
        textRect.X = (textRect.X + 6)
        textRect.Width = tSize.Width + 6
        textRect.Height = tSize.Height
        e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect)
        e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect)
    End Sub
End Class

The problem is, it is placed inside a scrollable container, and if it is scrolled the border isn't redrawn correctly:

问题是,它被放置在一个可滚动的容器中,如果它被滚动,则边框不会正确重绘:

Redraw

重绘

回答by Hans Passant

You can get it to misbehave a lot worse than that:

你可以让它行为不端比这更糟糕:

enter image description here

enter image description here

This goes wrong because of your code using e.ClipRectangle. Note that it appears twice in your snippet. That variable does notgive you the border rectangle. It tells you how much of your client area needs to be re-drawn. It is an optimizationopportunity, you can draw less by omitting the parts of the client area that don't need to be refreshed.

这是因为您的代码使用 e.ClipRectangle 导致的。请注意,它在您的代码段中出现了两次。该变量并没有给你的边界矩形。它会告诉您需要重新绘制多少客户区域。这是一个优化机会,您可以通过省略不需要刷新的客户区部分来减少绘制。

It is usuallythe same size as the display rectangle, which is why it looked like it worked just fine. But not when you put it inside a scrollable container, Windows optimizes scrolls by blitting the parts of the client area that simply can be moved. And then generates a paint for the parts that are revealed by the scroll. With a small e.ClipRectangle. You can see that in the screenshot, note the small rectangles.

通常与显示矩形的大小相同,这就是为什么它看起来工作得很好。但是当你把它放在一个可滚动的容器中时,Windows 会通过将客户区中可以简单移动的部分块化来优化滚动。然后为卷轴显示的部分生成油漆。带有一个小的 e.ClipRectangle。您可以在屏幕截图中看到,注意小矩形。

Replace e.ClipRectangle with Me.DisplayRectangle.

用 Me.DisplayRectangle 替换 e.ClipRectangle。

回答by Liam

This class allows the border to be set for all of your boxes or individually by adding a border color control to the properties tab for the group box.

此类允许为所有框设置边框或通过将边框颜色控件添加到组框的属性选项卡来单独设置边框。

Public Class GroupBoxA
    Inherits GroupBox

    Private _borderColor As Color

    Public Sub New()
        MyBase.New()
        Me._borderColor = Color.OrangeRed
    End Sub

    Public Property BorderColor() As Color
        Get
            Return Me._borderColor
        End Get
        Set(ByVal value As Color)
            Me._borderColor = value
        End Set
    End Property

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim tSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font)
        Dim borderRect As Rectangle = Me.DisplayRectangle

        borderRect.Y = (borderRect.Y + (tSize.Height / 2))
        borderRect.Height = (borderRect.Height - (tSize.Height / 2))

        ControlPaint.DrawBorder(e.Graphics, borderRect, Me._borderColor,
                                ButtonBorderStyle.Solid)

        Dim textRect As Rectangle = Me.DisplayRectangle
        textRect.X = (textRect.X + 6)
        textRect.Width = tSize.Width
        textRect.Height = tSize.Height

        e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect)
        e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect)
    End Sub
End Class

回答by Hardik

you have to use Me.ClientRectangle instead of Me.DisplayRectangle for boder and text. If you using old way then flicker issue not solve and text of group box will not display.

对于边框和文本,您必须使用 Me.ClientRectangle 而不是 Me.DisplayRectangle。如果您使用旧方式,则闪烁问题无法解决,并且不会显示组框文本。