Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.175.243] |
|
Сообщ.
#1
,
|
|
|
Часто в процессе создания различных программ возникает вопрос: как произвести сортировку 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#: 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: 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 |