【问题标题】:How to make a control to be painted/refreshed properly如何正确绘制/刷新控件
【发布时间】:2014-09-25 00:05:03
【问题描述】:

我有一个从支票簿派生的控件,我称之为“SettingBooleanButton”,但是当任何窗口或对话框被拖动到控件上时,控件会保留拖动的迹象

下图显示了将应用程序窗口拖动到控件上的效果

这是我用于 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

【问题讨论】:

  • 就是这样,画一条线的代码?背景等呢?
  • 我无法真正重现它。在控件的构造函数中尝试SetStyle(ControlStyles.UserPaint, True)AllPaintingInWmPaintOptimizedDoubleBufferResizeRedraw 也是如此。
  • @Plutonix:我添加了 e.Graphics.FillRectangle(Brushes.LimeGreen, e.ClipRectangle),以确保背景被替换/重新绘制,但我仍然得到相同的行为跨度>
  • @Jens 也许如果您将按钮的 FlatStyle 属性设置为 Flat,您可以获得相同的行为
  • 不,仍然工作得很好。发布更多代码。定义、构造函数、完整的 OnPaint 事件。也许我们可以弄清楚。在黑暗中猜测无济于事。

标签: vb.net winforms custom-controls onpaint


【解决方案1】:
   ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, ...)

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

只有在您的绘画代码很昂贵并且您想在不需要时跳过该昂贵代码时才使用 ClipRectangle。这很少见,Windows 中的剪辑已经非常有效。

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

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

【讨论】:

    【解决方案2】:

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

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

    除了在启用和禁用之间切换需要 2 多秒并且在从数据网格中进行多选时会导致延迟之外,一切都运行良好。

    尝试了一些东西,然后我想这可能与图像有关。

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

    另外...由于我所有的按钮都在面板上,我启用/禁用面板,从而启用和禁用面板上的所有子项。

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 1970-01-01
      • 2020-08-27
      相关资源
      最近更新 更多