Cette fonction permet d'ajuster la largeur des colonnes d'un contrôle DataGrid en fonction de leur contenu : entête de la colonne, contenu des enregistrements, en fonction de la police de caractères.
Pré-requis :
- il faut créer un TableStyle pour la DataTable associée à la grille en tant que DataSource.
- il faut créer un GridColumnStyle pour chaque colonne à afficher dans la grille, avec une taille (Width) > 0
Comportement :
- s'il n'y a pas de TableStyle associé à la grille pour DataSource, une exception est levée.
- si une colonne ne possède pas de GridColumnStyle, elle est ignorée lors du redimensionnement.
- si une colonne possède un GridColumnStyle avec une taille (Width) égale à 0, elle est ignorée lors du redimensionnement.
- fonctionne pour les DataGridTextBoxColumnStyle et les DatagridBoolColumnStyle, quel que soit le type de donnée de la colonne (Int16, Int32, String, Decimal, Double, etc...)
- la DataSource de la grille, peut être un DataView pointant sur un DataTable, un DataTable, un DataSet avec un des DataTable qu'il contient.
Jetez un coup d'oeil sur l'image en début.
Source / Exemple :
Private Sub DataGridColumnAutoResize(ByRef oDataGrid As DataGrid)
Dim ds As DataSet
Dim dt As DataTable
Dim dw As DataView
Dim row As DataRow
Dim c As DataColumn
Dim i As Integer
Dim v() As Object
Dim o As Object
Dim maxcolsize() As Single
Dim sg As Single
Dim col_font As Font
Dim header_font As Font
Dim g As Graphics
Dim s As String
Dim tmp_sz As SizeF
Dim nbcol As Integer = -1
Dim nbgcs As Integer = -1
Dim ColumnResizedIndexes() As Integer = Nothing
Dim GridColumnStyleResizedIndexes() As Integer = Nothing
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' les colonnes dont la largeur (width) a été positionnée à 0 auparavant sont considérées
' comme masquées et sont laissées telles quelles
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' la source de données doit être une Datatable, un Dataview ou un DataSet
If TypeOf oDataGrid.DataSource Is DataTable Then
dt = CType(oDataGrid.DataSource, DataTable)
ElseIf TypeOf oDataGrid.DataSource Is DataView Then
dw = CType(oDataGrid.DataSource, DataView)
dt = dw.Table
ElseIf TypeOf oDataGrid.DataSource Is DataSet Then
ds = CType(oDataGrid.DataSource, DataSet)
dw = Nothing
dt = ds.Tables(oDataGrid.DataMember)
Else
Throw New Exception("DataGridColumnAutoResize : la source de données pour n'est pas valide.")
Exit Sub
End If
Dim tabname As String = dt.TableName
If Not oDataGrid.TableStyles.Contains(tabname) Then
Throw New Exception("DataGridColumnAutoResize : le TableStyle '" + tabname + "' n'existe pas.")
Exit Sub
End If
g = oDataGrid.CreateGraphics()
i = 0
For Each c In dt.Columns
If oDataGrid.TableStyles(tabname).GridColumnStyles.Contains(c.ColumnName) Then
nbgcs += 1
If oDataGrid.TableStyles(tabname).GridColumnStyles(nbgcs).Width > 0 Then
nbcol += 1
ReDim Preserve ColumnResizedIndexes(nbcol)
ColumnResizedIndexes(nbcol) = i
ReDim Preserve GridColumnStyleResizedIndexes(nbcol)
GridColumnStyleResizedIndexes(nbcol) = nbgcs
End If
End If
i += 1
Next
ReDim maxcolsize(nbcol)
header_font = oDataGrid.TableStyles(tabname).HeaderFont
' la taille max de chaque colonne est initialisée avec la taille des entêtes
nbcol = 0
For Each i In GridColumnStyleResizedIndexes
tmp_sz = g.MeasureString(oDataGrid.TableStyles(tabname).GridColumnStyles(i).HeaderText, _
header_font)
maxcolsize(nbcol) = tmp_sz.Width * (1 + (2 / tmp_sz.Width)) ' formule à la con ...
nbcol += 1
Next
' on tient enfin compte des données contenues dans la source de données liée au Datagrid
For Each row In dt.Rows
nbcol = 0
If (Not (row.RowState = DataRowState.Deleted)) AndAlso (Not (row(0) Is DBNull.Value)) Then
v = row.ItemArray
i = 0
For Each o In v
If [Array].IndexOf(ColumnResizedIndexes, i) <> -1 Then
Select Case [Type].GetTypeCode(o.GetType())
Case TypeCode.String
s = o
Case TypeCode.DateTime
s = CStr(o) ' conversion DateTime vers String, en enlevant l'heure
Case Else
s = o.ToString
End Select
col_font = oDataGrid.Font
tmp_sz = g.MeasureString(s, col_font)
sg = tmp_sz.Width * (1 + (2 / tmp_sz.Width)) ' formule à la con ...
If maxcolsize(nbcol) < sg Then
maxcolsize(nbcol) = sg
End If
nbcol += 1
End If
i = i + 1
Next
End If
Next
nbcol = 0
For Each i In GridColumnStyleResizedIndexes
oDataGrid.TableStyles(tabname).GridColumnStyles(i).Width = maxcolsize(nbcol)
nbcol += 1
Next
End Sub
Conclusion :
Le redimensionnement ne fonctionne pas forcément bien si vous avez créé des ColumnStyle personnalisé, avec ComboBox, ou DateTimePicker, etc....
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.