Datetimepicker avec une propriété readonly

0/5 (1 avis)

Snippet vu 13 293 fois - Téléchargée 31 fois

Contenu du snippet

Voici comment faire pour ajouter une propriété ReadOnly sur un DateTimePicker, pour le rendre insensible aux clicks de souris, et changer sa couleur en gris.

Sur le contrôle DateTimePicker 'standard', seule la propriété Enabled peut être mise à False, mais cela change aussi l'aspect du contrôle : il est 'flouté'.
Le fonctionnement est le même que le propriété ReadOnly du contrôle TextBox.

Source / Exemple :


Public Class MonDTP
    Inherits System.Windows.Forms.DateTimePicker

#Region " Code généré par le Concepteur Windows Form "

    Public Sub New()
        MyBase.New()

        'Cet appel est requis par le Concepteur Windows Form.
        InitializeComponent()

        'Ajoutez une initialisation quelconque après l'appel InitializeComponent()

    End Sub

    'La méthode substituée Dispose du UserControl1 pour nettoyer la liste des composants.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not m_backBrush Is Nothing Then
                m_backBrush.Dispose()
            End If
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Requis par le Concepteur Windows Form
    Private components As System.ComponentModel.IContainer

    'REMARQUE : la procédure suivante est requise par le Concepteur Windows Form
    'Elle peut être modifiée en utilisant le Concepteur Windows Form.  
    'Ne la modifiez pas en utilisant l'éditeur de code.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container
    End Sub

#End Region

    Private m_backBrush As SolidBrush
    Private _dtp_ro As Boolean = False

    Public Overrides Property BackColor() As Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal Value As Color)
            If Not m_backBrush Is Nothing Then
                m_backBrush.Dispose()
            End If
            MyBase.BackColor = Value
            m_backBrush = New SolidBrush(Me.BackColor)
            Me.Invalidate()
        End Set
    End Property

    Protected Overrides Sub WndProc(ByRef m As Message)
        Const WM_ERASEBKGND As Int32 = &H14
        Const WM_LBUTTONDOWN As Int32 = &H201

        Select Case m.Msg
            Case WM_ERASEBKGND
                Dim g As Graphics = Graphics.FromHdc(m.WParam)

                MyBase.WndProc(m)

                If Not (Me._dtp_ro) Then    ' readonly=false
                    If m_backBrush Is Nothing Then
                        m_backBrush = New SolidBrush(Me.BackColor)
                    End If
                    g.FillRectangle(m_backBrush, Me.ClientRectangle)
                    g.Dispose()
                Else                         ' readonly=true
                    Dim ro_backBrush As SolidBrush
                    ro_backBrush = New SolidBrush(Color.FromKnownColor(KnownColor.Control))
                    g.FillRectangle(ro_backBrush, Me.ClientRectangle)
                    g.Dispose()
                End If

            Case WM_LBUTTONDOWN
                If Not Me._dtp_ro Then
                    MyBase.WndProc(m)
                End If
            Case Else
                MyBase.WndProc(m)
        End Select

    End Sub

    Public Property Read_Only() As Boolean
        Get
            Return Me._dtp_ro
        End Get
        Set(ByVal Value As Boolean)
            Me._dtp_ro = Value

            Dim g As Graphics = Me.CreateGraphics
            Dim ro_backBrush As SolidBrush

            If Not (Me._dtp_ro) Then    ' readonly=false
                ro_backBrush = New SolidBrush(Color.Empty)
            Else                        ' readonly=true
                ro_backBrush = New SolidBrush(Color.FromKnownColor(KnownColor.Control))
            End If
            g.FillRectangle(ro_backBrush, Me.ClientRectangle)
            g.Dispose()
        End Set
    End Property

End Class

Conclusion :


L'éventail des possibilités est illimité : j'ai juste désactivé l'évènement WM_LBUTTONDOWN, qui arrive lorsqu'on enfonce le bouton gauche de la souris (je veus dire par là que l'évènement qui arrive lorsqu'on RELACHE le bouton gauche de la souris n'est pas, lui, désactivé).

Cette gestion des évènements peut être complexifiée à volonté dans la procédure WndProc.

Voilà.

A voir également

Ajouter un commentaire Commentaire
cs_sebeto Messages postés 7 Date d'inscription dimanche 11 mars 2007 Statut Membre Dernière intervention 29 septembre 2010
29 sept. 2010 à 05:33
Si ton DateTimePicker s'appelle myDTP et que tu as dans ton form un autre contrôle appelé OtherControl, il y a aussi cette solution toute simple :

Quand tu veux le mettre en readonly, tu le passes en mode "spin box" (avec myDTP.ShowUpDown=True), et tu détournes l'évènement Enter :

Private Sub myDTP _Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles myDTP .Enter
OtherControl.Focus()
End Sub

Du coup, impossible d'entrer dans le DTP, et vu que rien n'est sélectionnable, les boutons du spin box ne font rien et tu as un DTP en readonly...

Si tu veux en plus avoir son fond en gris, il suffit alors de changer CalendarForeColor

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.