Freigeben über


Gewusst wie: Anpassen der Sortierung im DataGridView-Steuerelement in Windows Forms

Das DataGridView-Steuerelement ermöglicht die automatische Sortierung. Sie können die Sortiervorgänge allerdings an Ihre Anforderungen anpassen. Beispielsweise können Sie mit der programmgesteuerten Sortierung eine alternative Benutzeroberfläche (UI) erstellen. Wahlweise können Sie das SortCompare-Ereignis behandeln oder die Sort(IComparer)-Überladung der Sort-Methode aufrufen, um flexibler sortieren zu können, z. B. beim Sortieren mehrerer Spalten.

In den folgenden Codebeispielen werden diese drei Ansätze hinsichtlich benutzerdefinierter Sortierung veranschaulicht. Weitere Informationen finden Sie unter Spaltenssortiermodi im DataGridView-Steuerelement von Windows Forms.

Programmgesteuertes Sortieren

Im folgenden Codebeispiel wird eine programmgesteuerte Sortierung veranschaulicht, die mithilfe der SortOrder-Eigenschaft und der SortedColumn-Eigenschaft durchgeführt wird, um die Sortierrichtung zu bestimmen, und mithilfe der SortGlyphDirection-Eigenschaft, um das Sortiersymbol manuell festzulegen. Die Sort(DataGridViewColumn,ListSortDirection)-Überladung der Sort-Methode wird verwendet, um Daten nur in einer einzelnen Spalte zu sortieren.

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;
        }
    }
}

Benutzerdefinierte Sortierung mit dem SortCompare-Ereignis

Im folgenden Codebeispiel wird eine benutzerdefinierte Sortierung mit einem SortCompare-Ereignishandler veranschaulicht. Die ausgewählte DataGridViewColumn wird sortiert, und für den Fall, dass die Spalte doppelte Werte enthält, wird die ID-Spalte verwendet, um die endgültige Reihenfolge zu bestimmen.

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;
    }
}

Benutzerdefinierte Sortierung mit der IComparer-Schnittstelle

Im folgenden Codebeispiel wird eine benutzerdefinierte Sortierung mithilfe der Sort(IComparer)-Überladung der Sort-Methode veranschaulicht, bei der durch die Implementierung der IComparer-Schnittstelle mehrere Spalten sortiert werden.

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;
        }
    }
}

Kompilieren des Codes

Für diese Beispiele gelten folgende Voraussetzungen:

  • Verweise auf die Assemblys System, System.Drawing und System.Windows.Forms.

Informationen zum Erstellen dieses Beispiels über die Befehlszeile für Visual Basic oder Visual C# finden Sie unter Erstellen von der Befehlszeile aus (Visual Basic) oder Erstellen über die Befehlszeile mit csc.exe. Sie können dieses Beispiel auch in Visual Studio erstellen, indem Sie den Code in ein neues Projekt einfügen. Weitere Informationen finden Sie unter Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio und Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio und Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio und Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio und Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio.

Siehe auch

Aufgaben

Gewusst wie: Festlegen der Sortierungsmodi für Spalten im DataGridView-Steuerelement in Windows Forms

Referenz

DataGridView

Konzepte

Spaltenssortiermodi im DataGridView-Steuerelement von Windows Forms

Weitere Ressourcen

Sortieren von Daten im DataGridView-Steuerelement in Windows Forms