На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: maxim84_, juice
  
> Как сделать сортировку ListView в режиме details при щелчке на заголовке?
    Часто в процессе создания различных программ возникает вопрос: как произвести сортировку ListView (режим details), если пользователь щелкнул по заголовку? Эту проблему можно решить следующим образом.

    ListView содержит свойство ListViewItemSorter, которое позволяет указать объект, используемый для сравнения элементов столбцов во время сортировки. Этот объект должен быть экземпляром класса, реализующего интерфейс IComparer. Его методу Compare() во время сортировки будут передаваться 2 объекта ListViewItem, алгоритм сравнения которых он и должен реализовать. Нужно заметить, что при инициализации свойства ListView.ListViewItemSorter метод ListView.Sort() вызовется автоматически, так что если в обработчике события ListView.ColumnClick инициализировать свойство ListView.ListViewItemSorter экземпляром comparer'a - то метод Sort() вызывать не нужно. Если - же инициализировать ListViewItemSorter только один раз, например в конструкторе, то при клике на header'e необходимо указать условия сортировки (например, столбец и направление) и затем вызвать Sort(). В примере ниже используется вариант с однократной инициализацией ListView.ListViewItemSorter (что уменьшает нагрузку на GC):

    C#:
    ExpandedWrap disabled
      using System;
      using System.Windows.Forms;
      using System.Collections;
      using System.Reflection;
      using System.Drawing;
      //Этот класс реализует интерфейс IComparer
      class ItemComparer: IComparer
      {
       int columnIndex = 0;
       bool sortAscending = true;
       //Это свойство инициализируется при каждом клике на column header'e
       public int ColumnIndex
       {
        set
        {
         //предыдущий клик был на этой же колонке?
         if (columnIndex == value)
          //да - меняем направление сортировки
          sortAscending = !sortAscending;
         else
         {
          columnIndex = value;
          sortAscending = true;
         }
        }
       }
       //здесь непосредственно производится сравнение
       //возвращаемые значения:
       // < 0 если x < y
       // 0 если x = y
       // > 0 если x > y
       public int Compare(object x, object y)
       {
        string value1 = ((ListViewItem)x).SubItems[columnIndex].Text;
        string value2 = ((ListViewItem)y).SubItems[columnIndex].Text;
        return String.Compare(value1, value2) * (sortAscending ? 1 : -1);
       }
      }
      class SortedListViewDemo: Form
      {
       ItemComparer itemComparer = new ItemComparer();
       public SortedListViewDemo()
       {
        //Создаем ListView с двумя столбцами
        ListView listView = new ListView();
        listView.View = View.Details;
        listView.Dock = DockStyle.Fill;
        listView.Columns.Add("Name", -1, HorizontalAlignment.Center);
        listView.Columns.Add("ARGB", -1, HorizontalAlignment.Center);
        listView.ColumnClick += new ColumnClickEventHandler(OnColumnClick);
        listView.Parent = this;
        //Заполняем ListView парами значений ColorValue и ColorName,
        //взятыми из структуры Color при помощи Reflection
        foreach(PropertyInfo propertyInfo in
         typeof(Color).GetProperties(BindingFlags.Public
         | BindingFlags.Static))
        {
         string colorName = propertyInfo.Name;
         Color color = Color.FromName(colorName);
         int argb = color.ToArgb();
         ListViewItem item = listView.Items.Add(colorName);
         //В качестве background'а каждого item'a используем соответствующий
      ему цвет
         item.BackColor = color;
         //Цвет шрифта выбираем инверсный фону
         item.ForeColor = Color.FromArgb(~argb);
         item.SubItems.Add(argb.ToString());
        }
        listView.ListViewItemSorter = itemComparer;
       }
       void OnColumnClick(object sender, ColumnClickEventArgs e)
       {
        //Указываем сортируемую колонку
        itemComparer.ColumnIndex = e.Column;
        //Непосредственно инициируем сортировку
        ((ListView)sender).Sort();
       }
       static void Main()
       {
        Application.Run(new SortedListViewDemo());
       }
      }

    VB.NET:
    ExpandedWrap disabled
       Imports System.Reflection
      Class ItemComparer
          Implements IComparer
          Dim ColIndex As Integer
          Dim SortAscending As Boolean
          Public WriteOnly Property ColumnIndex() As Integer
              Set(ByVal Value As Integer)
                  If ColIndex = Value Then
                      SortAscending = Not SortAscending
                  Else
                      ColIndex = Value
                      SortAscending = True
                  End If
              End Set
          End Property
          Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
              Dim Value1 As String = CType(x, ListViewItem).SubItems.Item(ColIndex).Text
              Dim Value2 As String = CType(y, ListViewItem).SubItems.Item(ColIndex).Text
              Dim CompareResult = String.Compare(Value1, Value2)
              If SortAscending Then
                  Return CompareResult
              Else
                  Return CompareResult * -1
              End If
          End Function
      End Class
      Class SortedListViewDemo
          Inherits Form
          Dim Comparer As ItemComparer = New ItemComparer
          Public Sub New()
              Dim LV As ListView = New ListView
              LV.View = View.Details
              LV.Dock = DockStyle.Fill
              LV.Columns.Add("Name", -1, HorizontalAlignment.Center)
              LV.Columns.Add("ARGB", -1, HorizontalAlignment.Center)
              AddHandler LV.ColumnClick, AddressOf OnColumnClick
              LV.Parent = Me
              Dim PropInfo As PropertyInfo
              For Each PropInfo In GetType(Color).GetProperties(BindingFlags.Public Or BindingFlags.Static)
                  Dim ColorName As String = PropInfo.Name
                  Dim Clr As Color = Color.FromName(ColorName)
                  Dim Argb As Integer = Clr.ToArgb()
                  Dim Item As ListViewItem = LV.Items.Add(ColorName)
                  Item.BackColor = Clr
                  Item.ForeColor = Color.FromArgb(Argb)
                  Item.SubItems.Add(Argb.ToString())
              Next
              LV.ListViewItemSorter = Comparer
          End Sub
          Private Sub OnColumnClick(ByVal sender As Object, ByVal e As ColumnClickEventArgs)
              Comparer.ColumnIndex = e.Column
              CType(sender, ListView).Sort()
          End Sub
      End Class


    Источник: gotdotnet.ru
    My name is Bond. James Bond.
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script Execution time: 0,0851 ]   [ 17 queries used ]   [ Generated: 13.11.19, 23:31 GMT ]