Cómo: Ordenar elementos del control ListView

Actualización: noviembre 2007

.NET Compact Framework no admite el método Sort para un control ListView, pero se sigue pudiendo ordenar elementos mediante la interfaz IComparer y utilizar el método Sort en una clase ArrayList.

La tabla siguiente define tres clases.

Clase

Descripción

ColHeader

Esta clase, que se deriva de la clase ColumnHeader, se utiliza para agregar columnas al control ListView y para ordenar la columna seleccionada. Incluye la propiedad ascending para especificar la dirección de la ordenación: true especifica ordenación ascendente y false especifica ordenación descendente.

SortWrapper

Cuando se hace clic en una columna, se crea una instancia de esta clase para cada propiedad ListItem y se agrega a una clase ArrayList. Cada elemento implementado mediante una clase contenedora incluye una propiedad que contiene el índice de la columna seleccionada.

Esta clase contiene la clase SortComparer.

SortComparer

Dentro de la clase SortWrapper, esta clase define una implementación de la interfaz IComparer cuyo método Compare compara objetos de dos en dos cuando se ordena ArrayList.

El controlador de eventos para el evento ColumnClick realiza la operación de ordenación del modo siguiente:

  1. Crea una instancia de la clase ColHeader para determinar qué columna se selecciona.

  2. Establece la propiedad "ascending" del objeto ColHeader para ordenar en dirección opuesta.

  3. Obtiene el número de elementos de la lista.

  4. Deshabilita la presentación actualizada durante la ordenación con el método BeginUpdate.

  5. Agrega una clase SortWrapper para cada elemento de ListView a una clase ArrayList.

  6. Ordena los elementos del control ArrayList utilizando una nueva instancia de la clase SortComparer cuya implementación de la interfaz IComparer contiene la lógica de la ordenación en su método Compare.

  7. Borra los elementos del control ListView y rellena el control con los elementos ordenados de ArrayList.

  8. Habilita la presentación actualizada con el método EndUpdate.

Observe que el método Sort en una clase ArrayList realiza una ordenación inestable; es decir, si dos elementos son iguales, no se puede conservar su orden. Por el contrario, una ordenación estable conserva el orden de los elementos que son iguales.

Para crear la aplicación

  1. Agregue la clase SortWrapper al proyecto, que también contiene la clase SortComparer.

    // An instance of the SortWrapper class is created for
    // each item and added to the ArrayList for sorting.
    public class SortWrapper
    {
        internal ListViewItem sortItem;
        internal int sortColumn;
    
    
        // A SortWrapper requires the item and the index of the clicked column.
        public SortWrapper (ListViewItem Item, int iColumn)
        {
            sortItem = Item;
            sortColumn = iColumn;
        }
    
        // Text property for getting the text of an item.
        public string Text
        {
            get
            {
                return sortItem.SubItems[sortColumn].Text;
            }
        }
    
        // Implementation of the IComparer
        // interface for sorting ArrayList items.
        public class SortComparer : IComparer
        {
            bool ascending;
    
            // Constructor requires the sort order;
            // true if ascending, otherwise descending.
            public SortComparer(bool asc)
            {
                this.ascending = asc;
            }
    
            // Implemnentation of the IComparer:Compare
            // method for comparing two objects.
            public int Compare(object x, object y)
            {
                SortWrapper xItem = (SortWrapper) x;
                SortWrapper yItem = (SortWrapper) y;
    
                string xText = xItem.sortItem.SubItems[xItem.sortColumn].Text;
                string yText = yItem.sortItem.SubItems[yItem.sortColumn].Text;
                return xText.CompareTo(yText) * (this.ascending ? 1 : -1);
            }
        }
    }
    
    
    
  2. Agregue la clase ColHeader al proyecto.

    // The ColHeader class is a ColumnHeader object with an
    // added property for determining an ascending or descending sort.
    // True specifies an ascending order, false specifies a descending order.
    public class ColHeader : ColumnHeader
    {
        public bool ascending;
        public ColHeader(string text, int width,  HorizontalAlignment align, bool asc)
        {
            this.Text = text;
            this.Width = width;
            this.TextAlign = align;
            this.ascending = asc;
        }
    }
    
    
    
  3. Agregue columnas con la clase ColHeader y agregue elementos de ListView.

    this.listView1.View = View.Details;
    
    // Add columns using the ColHeader class. The fourth
    // parameter specifies true for an ascending sort order.
    listView1.Columns.Add(new ColHeader("Name", 110, HorizontalAlignment.Left, true));
    listView1.Columns.Add(new ColHeader("Region", 50, HorizontalAlignment.Left, true));
    listView1.Columns.Add(new ColHeader("Sales", 70, HorizontalAlignment.Left, true));
    
    // Add the data.
    listView1.Items.Add(new ListViewItem(new string[] {"Archer, Karen","4","0521.28"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Benson, Max","8","0828.54"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Bezio, Marin","3","0535.22"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Higa, Sidney","2","0987.50"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Martin, Linda","6","1122.12"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Nash, Mike","7","1030.11"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Sanchez, Ken","1","0958.78"}));
    listView1.Items.Add(new ListViewItem(new string[] {"Smith, Ben","5","0763.25"}));
    
    // Connect the ListView.ColumnClick event to the ColumnClick event handler.
    this.listView1.ColumnClick += new ColumnClickEventHandler(listView1_ColumnClick);
    
    
    
  4. Agregue el código preciso para realizar la ordenación.

    private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
    {
    
        // Create an instance of the ColHeader class.
        ColHeader clickedCol = (ColHeader)this.listView1.Columns[e.Column];
    
        // Set the ascending property to sort in the opposite order.
        clickedCol.ascending = !clickedCol.ascending;
    
        // Get the number of items in the list.
        int numItems = this.listView1.Items.Count;
    
        // Turn off display while data is repoplulated.
        this.listView1.BeginUpdate();
    
        // Populate an ArrayList with a SortWrapper of each list item.
        ArrayList SortArray = new ArrayList();
        for (int i = 0; i < numItems; i++)
        {
            SortArray.Add(new SortWrapper(this.listView1.Items[i], e.Column));
        }
    
        // Sort the elements in the ArrayList using a new instance of the SortComparer
        // class. The parameters are the starting index, the length of the range to sort,
        // and the IComparer implementation to use for comparing elements. Note that
        // the IComparer implementation (SortComparer) requires the sort
        // direction for its constructor; true if ascending, othwise false.
        SortArray.Sort(0, SortArray.Count, new SortWrapper.SortComparer(clickedCol.ascending));
    
        // Clear the list, and repopulate with the sorted items.
        this.listView1.Items.Clear();
        for  (int i = 0; i < numItems; i++)
            this.listView1.Items.Add(((SortWrapper)SortArray[i]).sortItem);
    
        // Turn display back on.
        this.listView1.EndUpdate();
    }
    
    
    

Para este ejemplo se requieren referencias a los siguientes espacios de nombres:

Adiciones de comunidad

Mostrar: