Une combobox comme style de colonne d'un datagrid

Contenu du snippet

Cette source est un Style de Colonne destiné à être utilisé dans un DataGrid. Il n'accepte d'un seul argument : une datatable composée de deux colonnes. La première sera la ValueMember du ComboBox et la seconde sera la DisplayMember.

DataGridComboBoxColumn hérite de DataGridColumnStyle.
Les méthodes suivantes sont redéfinies :
- Abort : événement en cas d'abandon de l'édition
- Edit : édition d'une cellule
- Commit : enregistrement des données dans la table source
- Paint : affichage dans le DataGrid
- GetMinimumHeight : retourne la propriété Height
- GetPreferedHeight : retourne la propriété Height
- GetPreferredSize : retourne la propriété Size
- ComboBoxValueChanged : événement lors de l'édition
- SetDataGridInColumn : intégration de la combo dans la DatGrid

Pour pouvoir l'utiliser il faut aménager la DataGrid en déclarant une colonne en DataGridComboBoxColumn. Le code suivant permet de le faire :

Dim MonStyleDeGrille As DataGridTableStyle = New DataGridTableStyle
MonStyleDeGrille.MappingName = "nom de la table source de la DataGrid"
Dim MonStyleDeColonne As DataGridComboBoxColumn = New DataGridComboBoxColumn(dtType)
MonStyleDeColonne.MappingName = "nom de la colonne de lien"
MonStyleDeColonne.HeaderText = "nommage de la colonne"
MonStyleDeColonne.Width = 100
MonStyleDeGrille.GridColumnStyles.Add(TypeColumnStyle)
MaDataGrid.TableStyles.Add(MonStyleDeGrille)

Je vous invite néanmoins à vous documenter sur l'affectation de styles de colonnes à une DataGrid.

Source / Exemple :


Imports System
Imports System.Data
Imports System.Windows.Forms
Imports System.Drawing
Imports System.ComponentModel

Public Class DataGridComboBoxColumn
    Inherits DataGridColumnStyle

    Private MaCombo As New ComboBox
    Private isEditing As New Boolean
    Dim dt As New DataTable
    Dim change As String

    Sub New(ByVal dtType As DataTable)
        isEditing = False
        dt = dtType
        MaCombo.DataSource = dt
        MaCombo.DisplayMember = dt.Columns(1).ToString
        MaCombo.ValueMember = dt.Columns(0).ToString
        MaCombo.Visible = False
    End Sub

    Protected Overrides Sub Abort(ByVal rowNum As Integer)
        isEditing = False
        RemoveHandler MaCombo.SelectedValueChanged, AddressOf ComboBoxValueChanged
        Invalidate()
    End Sub

    Protected Overrides Function Commit(ByVal dataSource As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer) As Boolean
        Try
            MaCombo.Bounds = Rectangle.Empty
            RemoveHandler MaCombo.SelectedValueChanged, AddressOf ComboBoxValueChanged

            If Not isEditing Then
                Return True
            End If
            isEditing = False

            Dim value As String
            value = Me.MaCombo.SelectedValue()
            SetColumnValueAtRow(dataSource, rowNum, value)

        Catch ex As Exception
            MessageBox.Show(ex.ToString, "Erreur de Mise à Jour des données saisies.")
        End Try

        Invalidate()
        Return True
    End Function

    Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
        Try
            If cellIsVisible Then
                MaCombo.Bounds = New Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height)
                MaCombo.SelectedIndex = 0
                MaCombo.Visible = True
                AddHandler MaCombo.SelectedValueChanged, AddressOf ComboBoxValueChanged
            Else
                MaCombo.Visible = False
            End If
        Catch ex As Exception
            MessageBox.Show(ex.ToString, "Erreur d'Edition")
        End Try

        If MaCombo.Visible Then
            DataGridTableStyle.DataGrid.Invalidate(bounds)
        End If
    End Sub

    Protected Overrides Function GetMinimumHeight() As Integer
        Return Me.MaCombo.Height
    End Function

    Protected Overrides Function GetPreferredHeight(ByVal g As System.Drawing.Graphics, ByVal value As Object) As Integer
        Return Me.MaCombo.Height
    End Function

    Protected Overrides Function GetPreferredSize(ByVal g As System.Drawing.Graphics, ByVal value As Object) As System.Drawing.Size
        Return Me.MaCombo.Size
    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)
        Paint(g, bounds, [source], rowNum, Brushes.Red, Brushes.Blue, alignToRight)
    End Sub

    Protected Overloads Overrides 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)
        Try
            Dim clef As String
            Dim valeur As String
            clef = GetColumnValueAtRow([source], rowNum).ToString
            If Not clef = "" Then

                Dim row As DataRow
                If dt.Rows.Contains(clef) Then
                    row = dt.Rows.Find(clef)
                    valeur = row.Item(1).ToString
                Else
                    valeur = "Erreur"
                End If
            Else
                valeur = "Vide"
            End If

            Dim rect As Rectangle = bounds
            g.FillRectangle(backBrush, rect)
            rect.Offset(0, 2)
            rect.Height -= 2
            g.DrawString(valeur, Me.DataGridTableStyle.DataGrid.Font, foreBrush, RectangleF.FromLTRB(rect.X, rect.Y, rect.Right, rect.Bottom))
        Catch ex As Exception
            MessageBox.Show(ex.ToString, "Erreur d'Affichage des Données")
        End Try
    End Sub

    Private Sub ComboBoxValueChanged(ByVal sender As Object, ByVal e As EventArgs)
        Me.isEditing = True
        MyBase.ColumnStartedEditing(MaCombo)
    End Sub

    Protected Overrides Sub SetDataGridInColumn(ByVal value As DataGrid)
        MyBase.SetDataGridInColumn(value)
        If Not (MaCombo.Parent Is Nothing) Then
            MaCombo.Parent.Controls.Remove(MaCombo)
        End If
        If Not (value Is Nothing) Then
            value.Controls.Add(MaCombo)
        End If
    End Sub
End Class

A voir également

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.