Переопределить datetimepicker vb.net - PullRequest
1 голос
/ 12 октября 2011

Я хотел бы переопределить объект datetimepicker для удаления текста, когда свойство _clearOnDisabled имеет значение true.Когда свойство _readOnly имеет значение true, я хотел бы показать текст черным, а не серым.

Итак, я попытался с WndProc, но мне кажется, что каждый объект проходит через мою функцию, а не только мой datetimepicker.Я получаю 100% CPU, когда я помещаю сообщение WM_PAINT.Я также пытался переопределить 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

1 Ответ

1 голос
/ 12 октября 2011

Не ешьте сообщение рисования, но рисуйте после него:

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.

...