Uso de Visual C# para ordenar un control ListView mediante una columna

En este artículo se proporciona información sobre cómo ordenar un control ListView mediante una columna en Visual C# y también se proporciona un ejemplo de código para explicar los métodos.

Versión original del producto: Visual C#
Número de KB original: 319401

Resumen

Cuando se trabaja con el control ListView, es posible que desee ordenar su contenido en función de una columna específica. Un ejemplo de este tipo de funcionalidad se produce en un programa del Explorador de Windows cuando se ve el contenido de una carpeta en el disco duro. En la vista Detalles, el Explorador de Windows muestra información sobre los archivos de esa carpeta. Por ejemplo, verá el nombre de archivo, el tamaño del archivo, el tipo de archivo y la fecha en que se modificó el archivo. Al hacer clic en uno de los encabezados de columna, la lista se ordena en orden ascendente en función de esa columna. Al volver a hacer clic en el mismo encabezado de columna, la columna se ordena en orden descendente.

En el ejemplo de este artículo se define una clase que hereda de la IComparer interfaz. Además, en este ejemplo se usa el Compare método de la CaseInsenstiveComparer clase para realizar la comparación real de los elementos.

Nota:

  • Este método de comparación no distingue mayúsculas de minúsculas.
  • Todas las columnas de este ejemplo se ordenan de forma de texto .

Si desea ordenar de otra manera (por ejemplo, numéricamente), puede reemplazar la siguiente línea de código por cualquier enfoque de ordenación que quiera usar:

ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text,listviewY.SubItems[ColumnToSort].Text);

Pasos para compilar el proyecto de ejemplo

  1. Cree un nuevo proyecto de aplicación de Windows de Visual C#. Form1 se crea de forma predeterminada.

  2. Agregue un control ListView a Form1. Ajuste el tamaño de la forma para que sea de varias pulgadas de ancho por varias pulgadas de alto.

  3. Pegue el código siguiente en la clase del formulario:

    private ListViewColumnSorter lvwColumnSorter;
    
  4. Pegue el código siguiente en el constructor del formulario, después de la llamada al InitializeComponent método :

    // Create an instance of a ListView column sorter and assign it
    // to the ListView control.
    lvwColumnSorter = new ListViewColumnSorter();
    this.listView1.ListViewItemSorter = lvwColumnSorter;
    
  5. Pegue el código siguiente en el Load evento del formulario:

    ColumnHeader columnheader;// Used for creating column headers.
    ListViewItem listviewitem;// Used for creating listview items.
    
    // Ensure that the view is set to show details.
    listView1.View = View.Details;
    
    // Create some listview items consisting of first and last names.
    listviewitem = new ListViewItem("John");
    listviewitem.SubItems.Add("Smith");
    this.listView1.Items.Add(listviewitem);
    
    listviewitem = new ListViewItem("Bob");
    listviewitem.SubItems.Add("Taylor");
    this.listView1.Items.Add(listviewitem);
    
    listviewitem = new ListViewItem("Kim");
    listviewitem.SubItems.Add("Zimmerman");
    this.listView1.Items.Add(listviewitem);
    
    listviewitem = new ListViewItem("Olivia");
    listviewitem.SubItems.Add("Johnson");
    this.listView1.Items.Add(listviewitem);
    
    // Create some column headers for the data.
    columnheader = new ColumnHeader();
    columnheader.Text = "First Name";
    this.listView1.Columns.Add(columnheader);
    
    columnheader = new ColumnHeader();
    columnheader.Text = "Last Name";
    this.listView1.Columns.Add(columnheader);
    
    // Loop through and size each column header to fit the column header text.
    foreach (ColumnHeader ch in this.listView1.Columns)
    {
        ch.Width = -2;
    }
    

    Nota:

    El código debe cambiarse en Visual Studio. Al crear un proyecto de Windows Forms, Visual C# agrega un formulario al proyecto de forma predeterminada. Este formulario se denomina Form1. Los dos archivos que representan el formulario se denominan Form1.cs y Form1.designer.cs. Escriba el código en Form1.cs. El archivo Designer.cs es donde el Windows Forms Designer escribe el código que implementa todas las acciones que ha realizado agregando controles. Para obtener más información sobre la Windows Forms Designer en Visual C#, visite Creating a Project (Visual C#).

  6. Pegue el código siguiente en el ColumnClick evento para el control ListView:

    // Determine if clicked column is already the column that is being sorted.
    if (e.Column == lvwColumnSorter.SortColumn)
    {
        // Reverse the current sort direction for this column.
        if (lvwColumnSorter.Order == SortOrder.Ascending)
        {
            lvwColumnSorter.Order = SortOrder.Descending;
        }
        else
        {
            lvwColumnSorter.Order = SortOrder.Ascending;
        }
    }
    else
    {
        // Set the column number that is to be sorted; default to ascending.
        lvwColumnSorter.SortColumn = e.Column;
        lvwColumnSorter.Order = SortOrder.Ascending;
    }
    
    // Perform the sort with these new sort options.
    this.listView1.Sort();
    
  7. En el menú Proyecto , haga clic en Agregar clase para agregar una nueva clase al proyecto.

  8. Reemplace todo el código predeterminado de la nueva clase por el código siguiente:

    using System.Collections;
    using System.Windows.Forms;
    
    /// <summary>
    /// This class is an implementation of the 'IComparer' interface.
    /// </summary>
    public class ListViewColumnSorter : IComparer
    {
        /// <summary>
        /// Specifies the column to be sorted
        /// </summary>
        private int ColumnToSort;
    
        /// <summary>
        /// Specifies the order in which to sort (i.e. 'Ascending').
        /// </summary>
        private SortOrder OrderOfSort;
    
        /// <summary>
        /// Case insensitive comparer object
        /// </summary>
        private CaseInsensitiveComparer ObjectCompare;
    
        /// <summary>
        /// Class constructor. Initializes various elements
        /// </summary>
        public ListViewColumnSorter()
        {
            // Initialize the column to '0'
            ColumnToSort = 0;
    
            // Initialize the sort order to 'none'
            OrderOfSort = SortOrder.None;
    
            // Initialize the CaseInsensitiveComparer object
            ObjectCompare = new CaseInsensitiveComparer();
        }
    
        /// <summary>
        /// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive comparison.
        /// </summary>
        /// <param name="x">First object to be compared</param>
        /// <param name="y">Second object to be compared</param>
        /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
        public int Compare(object x, object y)
        {
            int compareResult;
            ListViewItem listviewX, listviewY;
    
            // Cast the objects to be compared to ListViewItem objects
            listviewX = (ListViewItem)x;
            listviewY = (ListViewItem)y;
    
            // Compare the two items
            compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text,listviewY.SubItems[ColumnToSort].Text);
    
            // Calculate correct return value based on object comparison
            if (OrderOfSort == SortOrder.Ascending)
            {
                // Ascending sort is selected, return normal result of compare operation
                return compareResult;
            }
            else if (OrderOfSort == SortOrder.Descending)
            {
                // Descending sort is selected, return negative result of compare operation
                return (-compareResult);
            }
            else
            {
                // Return '0' to indicate they are equal
                return 0;
            }
        }
    
        /// <summary>
        /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
        /// </summary>
        public int SortColumn
        {
            set
            {
                ColumnToSort = value;
            }
            get
            {
                return ColumnToSort;
            }
        }
    
        /// <summary>
        /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
        /// </summary>
        public SortOrder Order
        {
            set
            {
                OrderOfSort = value;
            }
            get
            {
                return OrderOfSort;
            }
        }
    
    }
    
  9. Guarde, compile y ejecute el proyecto de ejemplo.

  10. Haga clic en los distintos encabezados de columna del control ListView. Al hacer clic en el encabezado, el contenido del control ListView se ordena en orden ascendente en función de la columna en la que haga clic. Al volver a hacer clic en el mismo encabezado de columna, esa columna se ordena en orden descendente.