覆盖 datetimepicker vb.net

发布于 2024-12-09 05:05:25 字数 2789 浏览 0 评论 0原文

我想重写 datetimepicker 对象以在属性 _clearOnDisabled 为 true 时删除文本。当 _readOnly 属性为 true 时,我想以黑色而不是灰色显示文本。

所以我尝试使用 WndProc,但我似乎每个对象都经过我的函数,而不仅仅是我的日期时间选择器。当我输入 WM_PAINT 消息时,我的 CPU 利用率为 100%。我也尝试覆盖 OnPaint 但它没有进入。

谢谢帮助

Imports System.Drawing
Imports System.Windows.Forms
Imports DTP.WindowsMessages

Public Class DTP
    Inherits System.Windows.Forms.DateTimePicker

    Private _readOnly As Boolean = False
    Private _clearOnDisabled As Boolean = True
    Private _backColorReadOnly As Color = MyBase.BackColor

    Public Sub New()
        MyBase.New()
    End Sub

    Public Overrides Property BackColor() As Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal Value As Color)
            MyBase.BackColor = Value
            If Not _readOnly Then
                Me.Invalidate()
            End If
        End Set
    End Property

    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_ERASEBKGND
                Dim g As Graphics = Graphics.FromHdc(m.WParam)
                Dim backBrush As SolidBrush

                If _readOnly Then
                    backBrush = New SolidBrush(_backColorReadOnly)
                    g.FillRectangle(backBrush, Me.ClientRectangle)
                Else
                    backBrush = New SolidBrush(MyBase.BackColor)
                    g.FillRectangle(backBrush, Me.ClientRectangle)
                End If
                g.Dispose()
            Case WM_LBUTTONDOWN, WM_KEYDOWN
                If Not _readOnly Then
                    MyBase.WndProc(m)
                End If

                'Case WM_PAINT ', WM_NCPAINT, WM_DRAWITEM
                '    If Not _clearOnDisabled Then
                '        MyBase.WndProc(m)
                '    End If

            Case Else
                MyBase.WndProc(m)
        End Select
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If Not _clearOnDisabled Then
            MyBase.OnPaint(e)
        End If
    End Sub

    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaintBackground(pevent)
    End Sub

    Public Property [ReadOnly]() As Boolean
        Get
            Return _readOnly
        End Get
        Set(ByVal Value As Boolean)
            _readOnly = Value
            Me.Invalidate()
        End Set
    End Property

    Public Property BackColorReadOnly() As Color
        Get
            Return _backColorReadOnly
        End Get
        Set(ByVal Value As Color)
            _backColorReadOnly = Value
            If _readOnly Then
                Me.Invalidate()
            End If
        End Set
    End Property

End Class

I would like to overrides the datetimepicker object to remove the texte when the property _clearOnDisabled is true. When _readOnly property is true, I would like to show the text in black not gray.

So I tried with WndProc but I seem that every single object go through my function not only my datetimepicker. I get 100% CPU when I put the WM_PAINT message. I also tried to overrides the OnPaint but its not getting in.

Thx for the help

Imports System.Drawing
Imports System.Windows.Forms
Imports DTP.WindowsMessages

Public Class DTP
    Inherits System.Windows.Forms.DateTimePicker

    Private _readOnly As Boolean = False
    Private _clearOnDisabled As Boolean = True
    Private _backColorReadOnly As Color = MyBase.BackColor

    Public Sub New()
        MyBase.New()
    End Sub

    Public Overrides Property BackColor() As Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal Value As Color)
            MyBase.BackColor = Value
            If Not _readOnly Then
                Me.Invalidate()
            End If
        End Set
    End Property

    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_ERASEBKGND
                Dim g As Graphics = Graphics.FromHdc(m.WParam)
                Dim backBrush As SolidBrush

                If _readOnly Then
                    backBrush = New SolidBrush(_backColorReadOnly)
                    g.FillRectangle(backBrush, Me.ClientRectangle)
                Else
                    backBrush = New SolidBrush(MyBase.BackColor)
                    g.FillRectangle(backBrush, Me.ClientRectangle)
                End If
                g.Dispose()
            Case WM_LBUTTONDOWN, WM_KEYDOWN
                If Not _readOnly Then
                    MyBase.WndProc(m)
                End If

                'Case WM_PAINT ', WM_NCPAINT, WM_DRAWITEM
                '    If Not _clearOnDisabled Then
                '        MyBase.WndProc(m)
                '    End If

            Case Else
                MyBase.WndProc(m)
        End Select
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If Not _clearOnDisabled Then
            MyBase.OnPaint(e)
        End If
    End Sub

    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaintBackground(pevent)
    End Sub

    Public Property [ReadOnly]() As Boolean
        Get
            Return _readOnly
        End Get
        Set(ByVal Value As Boolean)
            _readOnly = Value
            Me.Invalidate()
        End Set
    End Property

    Public Property BackColorReadOnly() As Color
        Get
            Return _backColorReadOnly
        End Get
        Set(ByVal Value As Color)
            _backColorReadOnly = Value
            If _readOnly Then
                Me.Invalidate()
            End If
        End Set
    End Property

End Class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

定格我的天空 2024-12-16 05:05:25

不要吃掉绘制消息,而是在它之后绘制:

Case WM_PAINT
  MyBase.WndProc(m)
  If _clearOnDisabled Then
    Dim dc As IntPtr = GetWindowDC(Me.Handle)
    Using g As Graphics = Graphics.FromHdc(dc)
      g.FillRectangle(SystemBrushes.Window, New Rectangle(SystemInformation.Border3DSize.Width, _
                                                            SystemInformation.Border3DSize.Height, _
                                                            Me.ClientSize.Width - SystemInformation.VerticalScrollBarWidth, _
                                                            Me.ClientSize.Height))
    End Using
    ReleaseDC(Me.Handle, dc)
  End If

您可以摆脱 OnPaint、OnPaintBackground 覆盖。

Don't eat the paint message, but paint after it:

Case WM_PAINT
  MyBase.WndProc(m)
  If _clearOnDisabled Then
    Dim dc As IntPtr = GetWindowDC(Me.Handle)
    Using g As Graphics = Graphics.FromHdc(dc)
      g.FillRectangle(SystemBrushes.Window, New Rectangle(SystemInformation.Border3DSize.Width, _
                                                            SystemInformation.Border3DSize.Height, _
                                                            Me.ClientSize.Width - SystemInformation.VerticalScrollBarWidth, _
                                                            Me.ClientSize.Height))
    End Using
    ReleaseDC(Me.Handle, dc)
  End If

You can get rid of your OnPaint, OnPaintBackground overrides.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文