Un contrôle personnalisé datagridcolumnstyle

Soyez le premier à donner votre avis sur cette source.

Snippet vu 13 540 fois - Téléchargée 33 fois

Contenu du snippet

Ce bout de code à pour but d'exploiter les possibilité d'héritage de la classe DataGridColumnStyle pour intégrer des controles autres que textbox ou checkbox dans une datagrid en VB .net.

Dans l'exemple ci-dessous on affiche un Label dans une colonne d'une datagrid.
Vous pouvez vous appuyer sur ce modèle pour intégrer un dateTimePicker voire une form complète.

Source / Exemple :


Public Class DataGridLabelColumn
    Inherits DataGridColumnStyle

    Private _xMargin As Integer = 2
    Private _yMargin As Integer = 1
    Private _Label As Label
    'Private _OldVal As String = String.Empty
    'Private _InEdit As Boolean = False

    Public Property Label() As Label
        Get
            Return MyClass._Label
        End Get
        Set(ByVal Value As Label)
            MyClass._Label = Value
        End Set
    End Property

    Public Sub New()
        MyClass._Label = New Label
        MyClass._Label.Visible = False
    End Sub

#Region "Heritage de DataGridColumnStyle"
    Protected Overloads Overrides Sub Abort(ByVal RowNum As Integer)
        RollBack()
        HideLabel()
        EndEdit()
    End Sub
    Protected Overloads Overrides Function Commit(ByVal DataSource As CurrencyManager, ByVal RowNum As Integer) As Boolean
        HideLabel()
        Return True
        'Plus utile
        Try
            Dim Value As Object = MyClass._Label.Text
            If NullText.Equals(Value) Then
                Value = Convert.DBNull
            End If
            SetColumnValueAtRow(DataSource, RowNum, Value)
        Catch e As Exception
            RollBack()
            Return False
        End Try
        EndEdit()
        Return True
    End Function
    Protected Overloads Overrides Sub ConcedeFocus()
        MyClass._Label.Visible = False
    End Sub
    Protected Overloads Overrides Sub Edit(ByVal Source As CurrencyManager, ByVal Rownum As Integer, ByVal Bounds As Rectangle, ByVal [ReadOnly] As Boolean, ByVal InstantText As String, ByVal CellIsVisible As Boolean)

        If Not InstantText Is Nothing Then
            MyClass._Label.Text = InstantText
        Else
            MyClass._Label.Text = Me.DataGridTableStyle.DataGrid.Item(Me.DataGridTableStyle.DataGrid.CurrentCell.RowNumber, Me.DataGridTableStyle.DataGrid.CurrentCell.ColumnNumber).ToString
        End If

        Dim OriginalBounds As Rectangle = Bounds

        If CellIsVisible Then
            Bounds.Offset(MyClass._xMargin, MyClass._yMargin)
            Bounds.Width -= MyClass._xMargin * 2
            Bounds.Height -= MyClass._yMargin
            MyClass._Label.Bounds = Bounds
            MyClass._Label.Visible = True
        Else
            MyClass._Label.Bounds = OriginalBounds
            MyClass._Label.Visible = False
        End If

        MyClass._Label.RightToLeft = Me.DataGridTableStyle.DataGrid.RightToLeft
        MyClass._Label.Focus()

        If MyClass._Label.Visible Then
            DataGridTableStyle.DataGrid.Invalidate(OriginalBounds)
        End If

    End Sub
    Protected Overloads Overrides Function GetMinimumHeight() As Integer
        Return MyClass._Label.PreferredHeight + MyClass._yMargin
    End Function
    Protected Overloads Overrides Function GetPreferredHeight(ByVal g As Graphics, ByVal Value As Object) As Integer
        Dim NewLineIndex As Integer = 0
        Dim NewLines As Integer = 0
        Dim ValueString As String = Me.GetText(Value)
        Do
            While NewLineIndex <> -1
                NewLineIndex = ValueString.IndexOf("r\n", NewLineIndex + 1)
                NewLines += 1
            End While
        Loop

        Return FontHeight * NewLines + MyClass._yMargin
    End Function
    Protected Overloads Overrides Function GetPreferredSize(ByVal g As Graphics, ByVal Value As Object) As Size
        Dim Extents As Size = Size.Ceiling(g.MeasureString(GetText(Value), Me.DataGridTableStyle.DataGrid.Font))
        Extents.Width += MyClass._xMargin * 2 + DataGridTableGridLineWidth
        Extents.Height += MyClass._yMargin
        Return Extents
    End Function
    Protected Overloads Overrides Sub Paint(ByVal g As Graphics, ByVal Bounds As Rectangle, ByVal Source As CurrencyManager, ByVal RowNum As Integer)
        Paint(g, Bounds, Source, RowNum, False)
    End Sub
    Protected Overloads Overrides Sub Paint(ByVal g As Graphics, ByVal Bounds As Rectangle, ByVal Source As CurrencyManager, ByVal RowNum As Integer, ByVal AlignToRight As Boolean)
        Dim Text As String = GetText(GetColumnValueAtRow(Source, RowNum))
        PaintText(g, Bounds, Text, AlignToRight)
    End Sub
    Protected Overloads Sub Paint(ByVal g As Graphics, ByVal Bounds As Rectangle, ByVal Source As CurrencyManager, ByVal RowNum As Integer, ByVal BackBrush As Brush, ByVal ForeBrush As Brush, ByVal AlignToRight As Boolean)
        Dim Text As String = GetText(GetColumnValueAtRow(Source, RowNum))
        PaintText(g, Bounds, Text, BackBrush, ForeBrush, AlignToRight)
    End Sub
    Protected Overloads Overrides Sub SetDataGridInColumn(ByVal Value As DataGrid)
        MyBase.SetDataGridInColumn(Value)
        If Not (MyClass._Label.Parent Is Value) Then
            If Not (MyClass._Label.Parent Is Nothing) Then
                MyClass._Label.Parent.Controls.Remove(MyClass._Label)
            End If
        End If

        If Not (Value Is Nothing) Then Value.Controls.Add(MyClass._Label)
    End Sub
    Protected Overloads Overrides Sub UpdateUI(ByVal Source As CurrencyManager, ByVal RowNum As Integer, ByVal InstantText As String)
        MyClass._Label.Text = GetText(GetColumnValueAtRow(Source, RowNum))
        If Not (InstantText Is Nothing) Then
            MyClass._Label.Text = InstantText
        End If
    End Sub
#End Region

#Region "Méthodes privées"
    Private ReadOnly Property DataGridTableGridLineWidth() As Integer
        Get
            If Me.DataGridTableStyle.GridLineStyle = DataGridLineStyle.Solid Then
                Return 1
            Else
                Return 0
            End If
        End Get
    End Property
    Private Sub EndEdit()
        Invalidate()
    End Sub

    Private Function GetText(ByVal Value As Object) As String
        If Value Is System.DBNull.Value Then Return NullText

        If Not Value Is Nothing Then
            Return Value.ToString
        Else
            Return String.Empty
        End If

    End Function

    Private Sub HideLabel()
        If MyClass._Label.Focused Then
            Me.DataGridTableStyle.DataGrid.Focus()
        End If
        MyClass._Label.Visible = False
    End Sub

    Private Sub RollBack()

    End Sub

    Private Sub PaintText(ByVal g As Graphics, ByVal Bounds As Rectangle, ByVal Text As String, ByVal AlignToRight As Boolean)

        Dim BackBrush As Brush = New SolidBrush(Me.DataGridTableStyle.BackColor)
        Dim ForeBrush As Brush = New SolidBrush(Me.DataGridTableStyle.ForeColor)
        PaintText(g, Bounds, Text, BackBrush, ForeBrush, AlignToRight)
    End Sub

    Private Sub PaintText(ByVal g As Graphics, ByVal TextBounds As Rectangle, ByVal Text As String, ByVal BackBrush As Brush, ByVal ForeBrush As Brush, ByVal AlignToRight As Boolean)

        Dim Rect As Rectangle = TextBounds
        Dim RectF As RectangleF = RectF.op_Implicit(Rect) ' Convert to RectangleF
        Dim Format As StringFormat = New StringFormat

        If AlignToRight Then
            Format.FormatFlags = StringFormatFlags.DirectionRightToLeft
        End If

        Select Case Me.Alignment
            Case Is = HorizontalAlignment.Left
                Format.Alignment = StringAlignment.Near
            Case Is = HorizontalAlignment.Right
                Format.Alignment = StringAlignment.Far
            Case Is = HorizontalAlignment.Center
                Format.Alignment = StringAlignment.Center
        End Select

        Format.FormatFlags = Format.FormatFlags Or StringFormatFlags.NoWrap
        g.FillRectangle(Brush:=BackBrush, Rect:=Rect)

        Rect.Offset(0, MyClass._yMargin)
        Rect.Height -= MyClass._yMargin
        g.DrawString(Text, Me.DataGridTableStyle.DataGrid.Font, ForeBrush, RectF, Format)
        Format.Dispose()

    End Sub
#End Region
End Class

A voir également

Ajouter un commentaire Commentaires
Messages postés
337
Date d'inscription
jeudi 19 décembre 2002
Statut
Membre
Dernière intervention
15 avril 2006

la msdn regorge d'info interressante : un datetimepicker tout fait ... avec les commentaires http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/cpref/html/frlrfsystemwindowsformsdatagridcolumnstyleclasstopic.asp
Messages postés
1356
Date d'inscription
samedi 8 décembre 2001
Statut
Membre
Dernière intervention
23 octobre 2006
7
Merci beaucoup
Messages postés
18
Date d'inscription
lundi 1 décembre 2003
Statut
Membre
Dernière intervention
12 octobre 2004

je vais mettre un exemple d'utilisation sur le source du message précédent.
Messages postés
1356
Date d'inscription
samedi 8 décembre 2001
Statut
Membre
Dernière intervention
23 octobre 2006
7
Tu veux dire par quoi
référence à system.windows.forms
L'inclure dans les références? OUI
J'ai tjrs le message
Et comment utiliser cette classe dans une form comprenant un Datagrid
Merci de tes éclaircissements
Messages postés
18
Date d'inscription
lundi 1 décembre 2003
Statut
Membre
Dernière intervention
12 octobre 2004

As tu fait une référence à system.windows.forms dans ta dll? Par défaut, elle n'y est pas.

(la même chose avec un control générique: http://www.vbfrance.com/code.aspx?ID=18359)
Afficher les 13 commentaires

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.