Comment : personnaliser le tri dans le contrôle DataGridView Windows Forms
Le contrôle DataGridView assure le tri automatique mais, selon vos besoins, vous pouvez devoir personnaliser certaines opérations de tri. Par exemple, vous pouvez utiliser le tri par programmation pour créer une autre interface utilisateur. Vous pouvez également gérer l'événement SortCompare ou appeler la surcharge Sort(IComparer) de la méthode Sort pour disposer de plus de souplesse de tri supérieure, par exemple pour trier plusieurs colonnes.
Les exemples de code suivants illustrent ces trois approches en matière de tri personnalisé. Pour plus d'informations, consultez Modes de tri des colonnes du contrôle DataGridView Windows Forms.
Tri par programme
L'exemple de code suivant montre un tri par programme à l'aide des propriétés SortOrder et SortedColumn pour déterminer le sens du tri et la propriété SortGlyphDirection pour définir manuellement le glyphe de tri. La surcharge Sort(DataGridViewColumn,ListSortDirection) de la méthode Sort est utilisée pour trier uniquement les données d'une seule colonne.
Imports System
Imports System.ComponentModel
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private WithEvents sortButton As New Button()
Private WithEvents dataGridView1 As New DataGridView()
' Initializes the form.
' You can replace this code with designer-generated code.
Public Sub New()
With dataGridView1
.Dock = DockStyle.Fill
.AllowUserToAddRows = False
.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect
.MultiSelect = False
End With
sortButton.Dock = DockStyle.Bottom
sortButton.Text = "Sort"
Controls.Add(dataGridView1)
Controls.Add(sortButton)
Text = "DataGridView programmatic sort demo"
PopulateDataGridView()
End Sub
' Establish the main entry point for the application.
<STAThreadAttribute()> _
Public Shared Sub Main()
Application.Run(New Form1())
End Sub
' Populates the DataGridView.
' Replace this with your own code to populate the DataGridView.
Public Sub PopulateDataGridView()
' Add columns to the DataGridView.
dataGridView1.ColumnCount = 2
dataGridView1.Columns(0).HeaderText = "Last Name"
dataGridView1.Columns(1).HeaderText = "City"
' Put the new columns into programmatic sort mode
dataGridView1.Columns(0).SortMode = _
DataGridViewColumnSortMode.Programmatic
dataGridView1.Columns(1).SortMode = _
DataGridViewColumnSortMode.Programmatic
' Populate the DataGridView.
dataGridView1.Rows.Add(New String() {"Parker", "Seattle"})
dataGridView1.Rows.Add(New String() {"Watson", "Seattle"})
dataGridView1.Rows.Add(New String() {"Osborn", "New York"})
dataGridView1.Rows.Add(New String() {"Jameson", "New York"})
dataGridView1.Rows.Add(New String() {"Brock", "New Jersey"})
End Sub
Private Sub SortButton_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles sortButton.Click
' Check which column is selected, otherwise set NewColumn to Nothing.
Dim newColumn As DataGridViewColumn
If dataGridView1.Columns.GetColumnCount(DataGridViewElementStates _
.Selected) = 1 Then
newColumn = dataGridView1.SelectedColumns(0)
Else
newColumn = Nothing
End If
Dim oldColumn As DataGridViewColumn = dataGridView1.SortedColumn
Dim direction As ListSortDirection
' If oldColumn is null, then the DataGridView is not currently sorted.
If oldColumn IsNot Nothing Then
' Sort the same column again, reversing the SortOrder.
If oldColumn Is newColumn AndAlso dataGridView1.SortOrder = _
SortOrder.Ascending Then
direction = ListSortDirection.Descending
Else
' Sort a new column and remove the old SortGlyph.
direction = ListSortDirection.Ascending
oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None
End If
Else
direction = ListSortDirection.Ascending
End If
' If no column has been selected, display an error dialog box.
If newColumn Is Nothing Then
MessageBox.Show("Select a single column and try again.", _
"Error: Invalid Selection", MessageBoxButtons.OK, _
MessageBoxIcon.Error)
Else
dataGridView1.Sort(newColumn, direction)
If direction = ListSortDirection.Ascending Then
newColumn.HeaderCell.SortGlyphDirection = SortOrder.Ascending
Else
newColumn.HeaderCell.SortGlyphDirection = SortOrder.Descending
End If
End If
End Sub
End Class
using System;
using System.ComponentModel;
using System.Windows.Forms;
class Form1 : Form
{
private Button sortButton = new Button();
private DataGridView dataGridView1 = new DataGridView();
// Initializes the form.
// You can replace this code with designer-generated code.
public Form1()
{
dataGridView1.Dock = DockStyle.Fill;
dataGridView1.AllowUserToAddRows = false;
dataGridView1.SelectionMode =
DataGridViewSelectionMode.ColumnHeaderSelect;
dataGridView1.MultiSelect = false;
sortButton.Dock = DockStyle.Bottom;
sortButton.Text = "Sort";
Controls.Add(dataGridView1);
Controls.Add(sortButton);
Text = "DataGridView programmatic sort demo";
}
// Establishes the main entry point for the application.
[STAThreadAttribute()]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
// Populates the DataGridView.
// Replace this with your own code to populate the DataGridView.
public void PopulateDataGridView()
{
// Add columns to the DataGridView.
dataGridView1.ColumnCount = 2;
dataGridView1.Columns[0].HeaderText = "Last Name";
dataGridView1.Columns[1].HeaderText = "City";
// Put the new columns into programmatic sort mode
dataGridView1.Columns[0].SortMode =
DataGridViewColumnSortMode.Programmatic;
dataGridView1.Columns[1].SortMode =
DataGridViewColumnSortMode.Programmatic;
// Populate the DataGridView.
dataGridView1.Rows.Add(new string[] { "Parker", "Seattle" });
dataGridView1.Rows.Add(new string[] { "Watson", "Seattle" });
dataGridView1.Rows.Add(new string[] { "Osborn", "New York" });
dataGridView1.Rows.Add(new string[] { "Jameson", "New York" });
dataGridView1.Rows.Add(new string[] { "Brock", "New Jersey" });
}
protected override void OnLoad(EventArgs e)
{
sortButton.Click += new EventHandler(sortButton_Click);
PopulateDataGridView();
base.OnLoad(e);
}
private void sortButton_Click(object sender, System.EventArgs e)
{
// Check which column is selected, otherwise set NewColumn to null.
DataGridViewColumn newColumn =
dataGridView1.Columns.GetColumnCount(
DataGridViewElementStates.Selected) == 1 ?
dataGridView1.SelectedColumns[0] : null;
DataGridViewColumn oldColumn = dataGridView1.SortedColumn;
ListSortDirection direction;
// If oldColumn is null, then the DataGridView is not currently sorted.
if (oldColumn != null)
{
// Sort the same column again, reversing the SortOrder.
if (oldColumn == newColumn &&
dataGridView1.SortOrder == SortOrder.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
// Sort a new column and remove the old SortGlyph.
direction = ListSortDirection.Ascending;
oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
else
{
direction = ListSortDirection.Ascending;
}
// If no column has been selected, display an error dialog box.
if (newColumn == null)
{
MessageBox.Show("Select a single column and try again.",
"Error: Invalid Selection", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
else
{
dataGridView1.Sort(newColumn, direction);
newColumn.HeaderCell.SortGlyphDirection =
direction == ListSortDirection.Ascending ?
SortOrder.Ascending : SortOrder.Descending;
}
}
}
Tri personnalisé à l'aide de l'événement SortCompare
L'exemple de code suivant illustre un tri personnalisé à l'aide d'un gestionnaire d'événement SortCompare. Le DataGridViewColumn sélectionné est trié et, s'il y a des valeurs en double dans la colonne, la colonne d'ID est utilisée pour déterminer l'ordre final.
Imports System
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private WithEvents DataGridView1 As New DataGridView()
' Establish the main entry point for the application.
<STAThreadAttribute()> _
Public Shared Sub Main()
Application.Run(New Form1())
End Sub
Public Sub New()
' Initialize the form.
' This code can be replaced with designer generated code.
Me.DataGridView1.AllowUserToAddRows = False
Me.DataGridView1.Dock = DockStyle.Fill
Me.Controls.Add(Me.DataGridView1)
Me.Text = "DataGridView.SortCompare demo"
Me.PopulateDataGridView()
End Sub
' Replace this with your own population code.
Private Sub PopulateDataGridView()
With Me.DataGridView1
' Add columns to the DataGridView.
.ColumnCount = 3
' Set the properties of the DataGridView columns.
.Columns(0).Name = "ID"
.Columns(1).Name = "Name"
.Columns(2).Name = "City"
.Columns("ID").HeaderText = "ID"
.Columns("Name").HeaderText = "Name"
.Columns("City").HeaderText = "City"
End With
' Add rows of data to the DataGridView.
With Me.DataGridView1.Rows
.Add(New String() {"1", "Parker", "Seattle"})
.Add(New String() {"2", "Parker", "New York"})
.Add(New String() {"3", "Watson", "Seattle"})
.Add(New String() {"4", "Jameson", "New Jersey"})
.Add(New String() {"5", "Brock", "New York"})
.Add(New String() {"6", "Conner", "Portland"})
End With
' Autosize the columns.
Me.DataGridView1.AutoResizeColumns()
End Sub
Private Sub DataGridView1_SortCompare( _
ByVal sender As Object, ByVal e As DataGridViewSortCompareEventArgs) _
Handles DataGridView1.SortCompare
' Try to sort based on the contents of the cell in the current column.
e.SortResult = System.String.Compare(e.CellValue1.ToString(), _
e.CellValue2.ToString())
' If the cells are equal, sort based on the ID column.
If (e.SortResult = 0) AndAlso Not (e.Column.Name = "ID") Then
e.SortResult = System.String.Compare( _
DataGridView1.Rows(e.RowIndex1).Cells("ID").Value.ToString(), _
DataGridView1.Rows(e.RowIndex2).Cells("ID").Value.ToString())
End If
e.Handled = True
End Sub
End Class
#region Using directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
#endregion
class Form1 : Form
{
private DataGridView dataGridView1 = new DataGridView();
// Establish the main entry point for the application.
[STAThreadAttribute()]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
// Initialize the form.
// This code can be replaced with designer generated code.
dataGridView1.AllowUserToAddRows = false;
dataGridView1.Dock = DockStyle.Fill;
dataGridView1.SortCompare += new DataGridViewSortCompareEventHandler(
this.dataGridView1_SortCompare);
Controls.Add(this.dataGridView1);
this.Text = "DataGridView.SortCompare demo";
PopulateDataGridView();
}
// Replace this with your own population code.
public void PopulateDataGridView()
{
// Add columns to the DataGridView.
dataGridView1.ColumnCount = 3;
// Set the properties of the DataGridView columns.
dataGridView1.Columns[0].Name = "ID";
dataGridView1.Columns[1].Name = "Name";
dataGridView1.Columns[2].Name = "City";
dataGridView1.Columns["ID"].HeaderText = "ID";
dataGridView1.Columns["Name"].HeaderText = "Name";
dataGridView1.Columns["City"].HeaderText = "City";
// Add rows of data to the DataGridView.
dataGridView1.Rows.Add(new string[] { "1", "Parker", "Seattle" });
dataGridView1.Rows.Add(new string[] { "2", "Parker", "New York" });
dataGridView1.Rows.Add(new string[] { "3", "Watson", "Seattle" });
dataGridView1.Rows.Add(new string[] { "4", "Jameson", "New Jersey" });
dataGridView1.Rows.Add(new string[] { "5", "Brock", "New York" });
dataGridView1.Rows.Add(new string[] { "6", "Conner", "Portland" });
// Autosize the columns.
dataGridView1.AutoResizeColumns();
}
private void dataGridView1_SortCompare(object sender,
DataGridViewSortCompareEventArgs e)
{
// Try to sort based on the cells in the current column.
e.SortResult = System.String.Compare(
e.CellValue1.ToString(), e.CellValue2.ToString());
// If the cells are equal, sort based on the ID column.
if (e.SortResult == 0 && e.Column.Name != "ID")
{
e.SortResult = System.String.Compare(
dataGridView1.Rows[e.RowIndex1].Cells["ID"].Value.ToString(),
dataGridView1.Rows[e.RowIndex2].Cells["ID"].Value.ToString());
}
e.Handled = true;
}
}
Tri personnalisé à l'aide de l'interface IComparer
L'exemple de code suivant montre le tri personnalisé à l'aide de la surcharge Sort(IComparer) de la méthode Sort, qui prend une implémentation de l'interface IComparer pour exécuter un tri sur plusieurs colonnes.
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private WithEvents DataGridView1 As New DataGridView()
Private FlowLayoutPanel1 As New FlowLayoutPanel()
Private WithEvents Button1 As New Button()
Private RadioButton1 As New RadioButton()
Private RadioButton2 As New RadioButton()
' Establish the main entry point for the application.
<STAThreadAttribute()> _
Public Shared Sub Main()
Application.Run(New Form1())
End Sub
Public Sub New()
' Initialize the form.
' This code can be replaced with designer generated code.
AutoSize = True
Text = "DataGridView IComparer sort demo"
FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown
FlowLayoutPanel1.Location = New System.Drawing.Point(304, 0)
FlowLayoutPanel1.AutoSize = True
FlowLayoutPanel1.Controls.Add(RadioButton1)
FlowLayoutPanel1.Controls.Add(RadioButton2)
FlowLayoutPanel1.Controls.Add(Button1)
Button1.Text = "Sort"
RadioButton1.Text = "Ascending"
RadioButton2.Text = "Descending"
RadioButton1.Checked = True
Controls.Add(FlowLayoutPanel1)
Controls.Add(DataGridView1)
PopulateDataGridView()
End Sub
' Replace this with your own code to populate the DataGridView.
Private Sub PopulateDataGridView()
DataGridView1.Size = New Size(300, 300)
' Add columns to the DataGridView.
DataGridView1.ColumnCount = 2
' Set the properties of the DataGridView columns.
DataGridView1.Columns(0).Name = "First"
DataGridView1.Columns(1).Name = "Last"
DataGridView1.Columns("First").HeaderText = "First Name"
DataGridView1.Columns("Last").HeaderText = "Last Name"
DataGridView1.Columns("First").SortMode = _
DataGridViewColumnSortMode.Programmatic
DataGridView1.Columns("Last").SortMode = _
DataGridViewColumnSortMode.Programmatic
' Add rows of data to the DataGridView.
DataGridView1.Rows.Add(New String() {"Peter", "Parker"})
DataGridView1.Rows.Add(New String() {"James", "Jameson"})
DataGridView1.Rows.Add(New String() {"May", "Parker"})
DataGridView1.Rows.Add(New String() {"Mary", "Watson"})
DataGridView1.Rows.Add(New String() {"Eddie", "Brock"})
End Sub
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
If RadioButton1.Checked = True Then
DataGridView1.Sort(New RowComparer(SortOrder.Ascending))
ElseIf RadioButton2.Checked = True Then
DataGridView1.Sort(New RowComparer(SortOrder.Descending))
End If
End Sub
Private Class RowComparer
Implements System.Collections.IComparer
Private sortOrderModifier As Integer = 1
Public Sub New(ByVal sortOrder As SortOrder)
If sortOrder = sortOrder.Descending Then
sortOrderModifier = -1
ElseIf sortOrder = sortOrder.Ascending Then
sortOrderModifier = 1
End If
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
Implements System.Collections.IComparer.Compare
Dim DataGridViewRow1 As DataGridViewRow = CType(x, DataGridViewRow)
Dim DataGridViewRow2 As DataGridViewRow = CType(y, DataGridViewRow)
' Try to sort based on the Last Name column.
Dim CompareResult As Integer = System.String.Compare( _
DataGridViewRow1.Cells(1).Value.ToString(), _
DataGridViewRow2.Cells(1).Value.ToString())
' If the Last Names are equal, sort based on the First Name.
If CompareResult = 0 Then
CompareResult = System.String.Compare( _
DataGridViewRow1.Cells(0).Value.ToString(), _
DataGridViewRow2.Cells(0).Value.ToString())
End If
Return CompareResult * sortOrderModifier
End Function
End Class
End Class
#region Using directives
using System;
using System.Drawing;
using System.Windows.Forms;
#endregion
class Form1 : Form
{
private DataGridView DataGridView1 = new DataGridView();
private FlowLayoutPanel FlowLayoutPanel1 = new FlowLayoutPanel();
private Button Button1 = new Button();
private RadioButton RadioButton1 = new RadioButton();
private RadioButton RadioButton2 = new RadioButton();
// Establish the main entry point for the application.
[STAThreadAttribute()]
public static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
// Initialize the form.
// This code can be replaced with designer generated code.
AutoSize = true;
Text = "DataGridView IComparer sort demo";
FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
FlowLayoutPanel1.Location = new System.Drawing.Point( 304, 0 );
FlowLayoutPanel1.AutoSize = true;
FlowLayoutPanel1.Controls.Add( RadioButton1 );
FlowLayoutPanel1.Controls.Add( RadioButton2 );
FlowLayoutPanel1.Controls.Add( Button1 );
Button1.Text = "Sort";
RadioButton1.Text = "Ascending";
RadioButton2.Text = "Descending";
RadioButton1.Checked = true;
Controls.Add( FlowLayoutPanel1 );
Controls.Add( DataGridView1 );
}
protected override void OnLoad( EventArgs e )
{
PopulateDataGridView();
Button1.Click += new EventHandler(Button1_Click);
base.OnLoad( e );
}
// Replace this with your own code to populate the DataGridView.
private void PopulateDataGridView()
{
DataGridView1.Size = new Size(300, 300);
// Add columns to the DataGridView.
DataGridView1.ColumnCount = 2;
// Set the properties of the DataGridView columns.
DataGridView1.Columns[0].Name = "First";
DataGridView1.Columns[1].Name = "Last";
DataGridView1.Columns["First"].HeaderText = "First Name";
DataGridView1.Columns["Last"].HeaderText = "Last Name";
DataGridView1.Columns["First"].SortMode =
DataGridViewColumnSortMode.Programmatic;
DataGridView1.Columns["Last"].SortMode =
DataGridViewColumnSortMode.Programmatic;
// Add rows of data to the DataGridView.
DataGridView1.Rows.Add(new string[] { "Peter", "Parker" });
DataGridView1.Rows.Add(new string[] { "James", "Jameson" });
DataGridView1.Rows.Add(new string[] { "May", "Parker" });
DataGridView1.Rows.Add(new string[] { "Mary", "Watson" });
DataGridView1.Rows.Add(new string[] { "Eddie", "Brock" });
}
private void Button1_Click( object sender, EventArgs e )
{
if ( RadioButton1.Checked == true )
{
DataGridView1.Sort( new RowComparer( SortOrder.Ascending ) );
}
else if ( RadioButton2.Checked == true )
{
DataGridView1.Sort( new RowComparer( SortOrder.Descending ) );
}
}
private class RowComparer : System.Collections.IComparer
{
private static int sortOrderModifier = 1;
public RowComparer(SortOrder sortOrder)
{
if (sortOrder == SortOrder.Descending)
{
sortOrderModifier = -1;
}
else if (sortOrder == SortOrder.Ascending)
{
sortOrderModifier = 1;
}
}
public int Compare(object x, object y)
{
DataGridViewRow DataGridViewRow1 = (DataGridViewRow)x;
DataGridViewRow DataGridViewRow2 = (DataGridViewRow)y;
// Try to sort based on the Last Name column.
int CompareResult = System.String.Compare(
DataGridViewRow1.Cells[1].Value.ToString(),
DataGridViewRow2.Cells[1].Value.ToString());
// If the Last Names are equal, sort based on the First Name.
if ( CompareResult == 0 )
{
CompareResult = System.String.Compare(
DataGridViewRow1.Cells[0].Value.ToString(),
DataGridViewRow2.Cells[0].Value.ToString());
}
return CompareResult * sortOrderModifier;
}
}
}
Compilation du code
Ces exemples nécessitent :
- Références aux assemblys System, System.Drawing et System.Windows.Forms.
Pour plus d'informations sur la génération de ces exemples à partir de la ligne de commande pour Visual Basic ou Visual C#, consultez Génération à partir de la ligne de commande (Visual Basic) ou Génération à partir de la ligne de commande avec csc.exe. Vous pouvez aussi générer cet exemple dans Visual Studio en collant le code dans un nouveau projet. Pour plus d'informations, consultez Comment : compiler et exécuter un exemple complet de code Windows Forms à l'aide de Visual Studio et Comment : compiler et exécuter un exemple complet de code Windows Forms à l'aide de Visual Studio et Comment : compiler et exécuter un exemple complet de code Windows Forms à l'aide de Visual Studio et Comment : compiler et exécuter un exemple complet de code Windows Forms à l'aide de Visual Studio et Comment : compiler et exécuter un exemple complet de code Windows Forms à l'aide de Visual Studio.
Voir aussi
Tâches
Comment : définir les modes de tri des colonnes du contrôle DataGridView Windows Forms
Référence
Concepts
Modes de tri des colonnes du contrôle DataGridView Windows Forms