如何使控件正确绘制/刷新 [英] How to make a control to be painted/refreshed properly

查看:111
本文介绍了如何使控件正确绘制/刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从支票簿派生的控件,我称之为"SettingBooleanButton",但是当任何窗口或对话框在控件上拖动时,该控件都会保持拖动的迹象

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

这是我用于OnPaint()的代码块

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

推荐答案

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

像这样使用e.ClipRectangle是Paint事件处理程序中的传统错误.它是不是与您要绘制的边框匹配的矩形.只是需要绘画的控件的一部分.通常是整个控件,但并非总是如此.例如,当您在控件上拖动窗口时,仅需要重绘显示的部分.因此,现在您在错误的位置上绘制了边框,从而产生了黑线.

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.

仅当绘画代码昂贵时才使用ClipRectangle,而您想趁此机会在不需要它时跳过该昂贵代码.这非常罕见,在Windows中裁剪已经非常有效.

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)

这篇关于如何使控件正确绘制/刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆