1

残念ながら、このイベントにテキストもDropDown-Buttonもレンダリングされない(ただし機能している)限り、Paint-Eventを「動的に」割り当てるDateTimePickerがあります。

別のコントロールを取り、それに何かを描画するコンポーネントを作成しました

Public Sub New(Byval parent As Control)
    Me._parent = parent
    Me._setStyle = Me._parent.GetType().GetMethod("SetStyle", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
    Me._setStyle.Invoke(Me._parent, New Object() {ControlStyles.UserPaint, True})
    Me._setStyle.Invoke(Me._parent, New Object() {ControlStyles.OptimizedDoubleBuffer, True})

    AddHandler Me._parent.Paint, AddressOf RemotePaintHandler
End Sub

Private Sub RemotePaintHandler(ByVal sender As Object, ByVal e As PaintEventArgs)
    'draw something here'
End Sub

コンポーネントを破棄するときに、ハンドラーを削除してスタイルをリセットします。ただし、ハンドラーが割り当てられている限り、DateTimePickerはコンテンツのない通常のテキストボックスのようにレンダリングされますが、ボタンは機能しており、値を入力することもできます。OnPaint()メソッドを上書きした場合は、MyBase.OnPaint()などを呼び出すだけですが、これはイベントハンドラーです...今はまったくわかりません。

4

2 に答える 2

2

自分自身を描く方法はDateTimePickerありません。OnPaintこれは実際にはWindowsコントロールのラッパーであるSysDateTimePick32ため、UserPaint = trueを設定すると、コントロール(実際のコントロール)はそれ自体を描画せず、描画のみが存在します。

サブスクライバーを実行することにより、メッセージから継承DateTimePicker、オーバーライドWndProc、応答することができます。ここに例があります:WM_PAINTPaint event

Public Class DTP
    Inherits DateTimePicker

    ' Events '
    Public Event Paint2 As PaintEventHandler

    ' Methods '
    Protected Overrides Sub WndProc(ByRef m As Message)

        MyBase.WndProc((m))

        If ((m.Msg = &HF) AndAlso (Not Me.Paint2 Is Nothing)) Then

            Dim g As Graphics = MyBase.CreateGraphics
            Me.Paint2.Invoke(Me, New PaintEventArgs( _
                                       g, _
                                       Rectangle.Round(g.VisibleClipBounds) _
                                     ) _
                            )
        End If

    End Sub

End Class

次に、通常の代わりにこの新しいコントロールを使用し、DateTimePickerPaint2イベントにサブスクライブして、必要なものを描画します。

(設定する必要はありません、とにかくUserPaint = Trueキャプチャしています)WM_PAINT

Public Sub New(Byval parent As Control)
    Me._parent = parent
    Me._setStyle = Me._parent.GetType().GetMethod("SetStyle", _
                               Reflection.BindingFlags.Instance _
                               Or Reflection.BindingFlags.NonPublic)
    'Me._setStyle.Invoke(Me._parent, New Object(){ControlStyles.UserPaint,True})'
    Me._setStyle.Invoke(Me._parent,  _
                        New Object() {ControlStyles.OptimizedDoubleBuffer, True})

    AddHandler Me._parent.Paint2, AddressOf RemotePaintHandler
End Sub

Private Sub RemotePaintHandler(ByVal sender As Object, ByVal e As PaintEventArgs)
    'draw something here'
End Sub

お役に立てれば、

于 2009-10-29T21:19:43.303 に答える
0

私は何かを理解しました。UserPaintは、DateTimePicker自体ではなく、基になるコントロール内で発生するように思われるため、'障害が発生します。これは、StyleUserPaintが設定されている限り発生します。

回避策の1つは、Paint-Event内で正しくレンダリングすることです...これは私が恐れているほど簡単ではありませんが、可能です:

Private Sub RemotePaintHandler(ByVal sender As Object, ByVal e As PaintEventArgs)
    RemoveHandler Me._parent.Paint, AddressOf RemotePaintHandler
    Me._setStyle.Invoke(Me._parent, New Object() {ControlStyles.UserPaint, False})

    Me._parent.Refresh()
    ' now draw something '

    Me._setStyle.Invoke(Me._parent, New Object() {ControlStyles.UserPaint, True})
    AddHandler Me._parent.Paint, AddressOf RemotePaintHandler
End Sub

Paint-Eventのハンドラーとスタイルを削除し、コントロールを更新して('正しくレンダリングされるようにします)、新しくレンダリングされたコントロールの上に描画し、StyleとPaint-Eventhandlerを再度追加します。欠点は、誰かが情報を入力している間(カレンダーボックスを使用している場合はそこにあります)、描画したものがすべて消え、some_one_がコントロールを更新するまで戻ってこない可能性があることです。したがって、これは醜いハックであり、実際の回避策または解決策でさえあるようです[1]。

ただし、これはDateTimePickerでのみテストしたものであり、これが他のコントロールでも機能するかどうかはわかりません(ただし、そう思われます)。

[1]つまり、私は解決策を知っています。フレームワーク内でコントロールを書き直します。

于 2009-10-21T08:48:17.777 に答える