如何使控件正确绘制/刷新

时间:2014-08-01 18:04:32

标签: vb.net winforms custom-controls onpaint

我有一个来自支票簿的控件,我打电话给#34; SettingBooleanButton",但是当控件上拖动任何窗口或对话框时,控件会保留拖动的迹象

下一张图显示了拖动应用程序窗口而不是控件的效果

ScreenShot

这是我对OnPaint()

的代码块
Public Class SettingBooleanButton
    Inherits CheckBox

    Private _settingSection As String
    Private _settingName As String
    Private _associatedSetting As Setting

    Public Event StateChange(ByVal affectedSetting As Setting)

    Sub New()
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Appearance = Appearance.Button
        FlatStyle = FlatStyle.Flat
        TextAlign = ContentAlignment.MiddleCenter
        AutoSize = False
    End Sub

    Public Property SettingSection As String
        Get
            Return _settingSection
        End Get
        Set(value As String)
            _settingSection = value
        End Set
    End Property

    Public Property SettingName As String
        Get
            Return _settingName
        End Get
        Set(value As String)
            _settingName = value
        End Set
    End Property

    ''' <summary>
    ''' Sets a boolean value to indicate the initial checked state of the control.
    ''' </summary>
    ''' <value>
    '''   <c>true</c> to set it as [checked state]; otherwise, <c>false</c>.
    ''' </value>
    Public Property CheckedState As Boolean
        Get
            Return Checked
        End Get
        Set(value As Boolean)
            _associatedSetting = New Setting(_settingSection, _settingName, String.Empty)

            RemoveHandler CheckedChanged, AddressOf StateChanged
            Checked = value
            SetText()
            AddHandler CheckedChanged, AddressOf StateChanged
        End Set
    End Property

    Private Sub StateChanged(sender As Object, e As EventArgs)
        If IsNothing(_associatedSetting) Then
            Return
        End If

        _associatedSetting.Value = Checked.ToString()
        SetText()
        RaiseEvent StateChange(_associatedSetting)
    End Sub

    Public Sub SetText()
        If Checked Then
            Font = New Font(Font.FontFamily, Font.Size, FontStyle.Bold)
            ForeColor = Color.WhiteSmoke
            Text = Resource.SettingBooleanButton_TrueState
        Else
            Font = New Font(Font.FontFamily, Font.Size, FontStyle.Regular)
            ForeColor = SystemColors.ControlText
            Text = Resource.SettingBooleanButton_FalseState
        End If
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        MyBase.OnPaint(e)

        If Checked Then
            ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, Color.Black, ButtonBorderStyle.Solid)               
        End If
    End Sub

End Class

2 个答案:

答案 0 :(得分:7)

   ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, ...)

像这样使用e.ClipRectangle是Paint事件处理程序中的传统错误。 是一个与您要绘制的边框相匹配的矩形。只有控件的一部分需要才能被绘制。这通常是整个控制,但并非总是如此。例如,在您的控件中拖动窗口时,只需要重新绘制显示的部分。所以现在你把边框画在错误的位置,产生那些黑线。

如果您的绘画代码很昂贵,并且您希望在不需要时跳过那些昂贵的代码,那么您只使用ClipRectangle。这是非常罕见的,在Windows中裁剪已经非常有效。

您需要传递边框的实际矩形。修正:

   ControlPaint.DrawBorder(e.Graphics, Me.ClientRectangle, _
                           Color.Black, ButtonBorderStyle.Solid)

答案 1 :(得分:0)

有时最简单的解决方案(或原因)被忽略了。

我有一个面板,上面有15个按钮,每个按钮都有一个图像。根据从数据网格中选择的行,它们都可能被启用或禁用。

除了在启用和禁用之间切换需要2秒钟以上并在从数据网格中进行多次选择时导致滞后之外,其他所有方法都工作正常。

尝试了几件事,然后我想也许与图像有关。

所有图像均在图像列表中,并且大小设置为24,24,这是32,32和16,16之间的折衷。我将图像列表中的大小更改为32,32,因为这是所有图像的原始大小...和shazam !!!现在基本上所有按钮都立即呈现。不知道ATM是否是小的PNG图像会有所作为...但是我要将所有图像转换为ICO格式。

还...因为我所有的按钮都在面板上,所以我启用/禁用了该面板,该面板又启用和禁用了面板上的所有子项。