How to make a control to be painted/refreshed properly

坚强是说给别人听的谎言 提交于 2019-12-02 21:52:26

问题


I have a control derived from checkbook which I called "SettingBooleanButton", but when any window or dialog is dragged over the control the control keeps signs of the drag

The next image shows the effect of dragging an application window over control

This is the code block that I have for 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

回答1:


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

Using e.ClipRectangle like this is a traditional bug in a Paint event handler. It is not a rectangle that matches the border you want to draw. It is only the part of the control that needs to be painted. Which is usually the entire control, but not always. Such as in your case when you drag a window across your control, only the part that is revealed needs to be repainted. So now you are painting the border in the wrong position, producing those black lines.

You only ever use the ClipRectangle if your painting code is expensive and you want to take the opportunity to skip that expensive code when it isn't needed anyway. Which is pretty rare, clipping in Windows is already pretty efficient.

You'll need to pass the actual rectangle of your border. Fix:

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


来源:https://stackoverflow.com/questions/25086097/how-to-make-a-control-to-be-painted-refreshed-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!