DataGridView 控件提供自动排序方式,但是根据您的需要,您可能要自定义排序操作。例如,可以使用通过编程方法实现的排序方式来创建一个替换用户界面 (UI)。或者,可以处理 SortCompare 事件,或调用 Sort 方法的 Sort(IComparer) 重载来进行更灵活的排序(如对多列进行排序)。
下面的代码示例演示三种自定义排序的方法。有关更多信息,请参见 Windows 窗体 DataGridView 控件中的列排序模式。
下面的代码示例演示如何以编程方式实现排序,具体为使用 SortOrder 和 SortedColumn 属性确定排序的方向,并使用 SortGlyphDirection 属性手动设置排序的标志符号。Sort 方法的 Sort(DataGridViewColumn,ListSortDirection) 重载仅用于在单列中对数据进行排序。
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._ 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" ' 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 Not oldColumn Is 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"; // 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; } } }
下面的代码示例演示如何使用 SortCompare 事件处理程序自定义排序。对选择的 DataGridViewColumn 进行排序,如果列中有重复值,则使用 ID 列确定最终顺序。
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._ 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; } }
下面的代码示例演示如何使用 Sort 方法的 Sort(IComparer) 重载自定义排序,该重载采用 IComparer 接口的实现来执行多列排序。
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._ 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; } } }