как отсортировать целые числа в списке - PullRequest
6 голосов
/ 31 июля 2009

Как отсортировать столбцы целых чисел в ListView

c #, .net 2.0, Winform

System.Windows.Forms.ListView

Ответы [ 7 ]

19 голосов
/ 31 июля 2009

Так я смог сортировать по нескольким столбцам и сортировать каждый столбец как число или текст.

Сначала используйте этот класс:

class Sorter : System.Collections.IComparer
{
    public int Column = 0;
    public System.Windows.Forms.SortOrder Order = SortOrder.Ascending;
    public int Compare(object x, object y) // IComparer Member
    {
        if (!(x is ListViewItem))
            return (0);
        if (!(y is ListViewItem))
            return (0);

        ListViewItem l1 = (ListViewItem)x;
        ListViewItem l2 = (ListViewItem)y;

        if (l1.ListView.Columns[Column].Tag == null)
        {
            l1.ListView.Columns[Column].Tag = "Text";
        }

        if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric")
        {
            float fl1 = float.Parse(l1.SubItems[Column].Text);
            float fl2 = float.Parse(l2.SubItems[Column].Text);

            if (Order == SortOrder.Ascending)
            {
                return fl1.CompareTo(fl2);
            }
            else
            {
                return fl2.CompareTo(fl1);
            }
        }
        else
        {
            string str1 = l1.SubItems[Column].Text;
            string str2 = l2.SubItems[Column].Text;

            if (Order == SortOrder.Ascending)
            {
                return str1.CompareTo(str2);
            }
            else
            {
                return str2.CompareTo(str1);
            }
        }
    }
}

В конструкторе вашей формы установите сортировщик так:

lvSeries.ListViewItemSorter = new Sorter();

Затем обработайте ColumnClick даже в вашем элементе управления списком следующим образом:

private void lvSeries_ColumnClick(object sender, ColumnClickEventArgs e)
    {
        Sorter s = (Sorter)lvSeries.ListViewItemSorter;
        s.Column = e.Column;

        if (s.Order == System.Windows.Forms.SortOrder.Ascending)
        {
            s.Order = System.Windows.Forms.SortOrder.Descending;
        }
        else
        {
            s.Order = System.Windows.Forms.SortOrder.Ascending;
        }
        lvSeries.Sort();
    }

Все это зависит от того, установлено ли свойство Tag каждого столбца на «Числовое» или нет, поэтому сортировщик знает, как сортировать.

В приведенном выше примере я приводил значения в виде чисел с плавающей точкой, вы можете изменить это значение на int.

5 голосов
/ 01 августа 2009

Если вы начинаете работать с ListView, ваша жизнь будет намного проще, если вы вместо этого будете использовать ObjectListView . ObjectListView - это обертка с открытым исходным кодом для .NET WinForms ListView, и она решает все эти надоедливые небольшие проблемы, которые обычно делают работу с ListView такой разочаровывающей. Например, он автоматически сортирует целочисленные значения, поэтому после «3» следует «100» (DateTimes, bools и все остальное тоже сортируются правильно).

Серьезно, вы никогда не захотите вернуться к простому ListView после использования ObjectListView.

Да, я автор - но это не значит, что я предвзятый ... Хорошо, ну, может быть, так и есть :) Посмотрите здесь мнения других людей.

3 голосов
/ 31 июля 2009

Вам нужно будет создать класс, который реализует интерфейс IComparer (не универсальный). В этом классе вы читаете свойство Text из правильного подпункта, конвертируете его в int и выполняете сравнение:

public class IntegerComparer : IComparer
{
    private int _colIndex;
    public IntegerComparer(int colIndex)
    {
        _colIndex = colIndex;
    }
    public int Compare(object x, object y)
    {
        int nx = int.Parse((x as ListViewItem).SubItems[_colIndex].Text);
        int ny = int.Parse((y as ListViewItem).SubItems[_colIndex].Text);
        return nx.CompareTo(ny);
    }
}

Затем вы назначаете такой компаратор свойству ListViewItemSorter и вызываете метод сортировки элемента управления ListView:

// create a comparer for column index 1 and assign it to the control, and sort
myListView.ListViewItemSorter = new IntegerComparer(1);
myListView.Sort();
0 голосов
/ 12 мая 2019
Public Class Form1

Private Sub btnSortListView_Click(sender As Object, e As EventArgs) Handles btnSortListView.Click
        If btnSortListView.Text = "Sort Ascending" Then

            ListViewGar.ListViewItemSorter = New IntegerComparer(1)
            ListViewGar.Sort()

            btnSortListView.Text = "Not Sort"

        Else
            ListViewGar.ListViewItemSorter = New IntegerComparer(0)
            btnSortListView.Text = "Sort Ascending"
        End If

    End Sub
End Class

 Public Class IntegerComparer
    Implements System.Collections.IComparer

    Private _colIndex As Integer

    Public Sub New(ByVal colIndex As Integer)
        MyBase.New
        Me._colIndex = colIndex
    End Sub

    'Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer
    '    Dim nx As Integer = Integer.Parse(CType(x, ListViewItem).SubItems(Me._colIndex).Text)
    '    Dim ny As Integer = Integer.Parse(CType(y, ListViewItem).SubItems(Me._colIndex).Text)
    '    Return nx.CompareTo(ny)
    'End Function

    Private Function IComparer_Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
        Dim nx As Integer = Integer.Parse(CType(x, ListViewItem).SubItems(Me._colIndex).Text)
        Dim ny As Integer = Integer.Parse(CType(y,ListViewItem).SubItems(Me._colIndex).Text)

        Dim colIndPlus As Integer = Me._colIndex
        Do While nx.CompareTo(ny) = 0
            colIndPlus = colIndPlus + 1
            nx = Integer.Parse(CType(x, ListViewItem).SubItems(colIndPlus).Text)
            ny = Integer.Parse(CType(y, ListViewItem).SubItems(colIndPlus).Text)
        Loop

        Return nx.CompareTo(ny)

    End Function
End Class

изображение до и после сортировки

0 голосов
/ 20 августа 2015
class ListViewAutoSorter : System.Collections.IComparer
{
    private int Column = 0;
    private System.Windows.Forms.SortOrder Order = SortOrder.Ascending;

    public ListViewAutoSorter(int Column, SortOrder Order)
    {
        this.Column = Column;
        this.Order = Order;
    }

    public int Compare(object x, object y) // IComparer Member
    {
        if (!(x is ListViewItem))
            return (0);
        if (!(y is ListViewItem))
            return (0);

        var l1 = (ListViewItem)x;
        var l2 = (ListViewItem)y;

        var value1 = 0.0;
        var value2 = 0.0;

        if (Double.TryParse(l1.SubItems[Column].Text, out value1) && 
            Double.TryParse(l2.SubItems[Column].Text, out value2))
        {
            if (Order == SortOrder.Ascending)
            {
                return value1.CompareTo(value2);
            }
            else
            {
                return value2.CompareTo(value1);
            }
        }
        else
        {
            var str1 = l1.SubItems[Column].Text;
            var str2 = l2.SubItems[Column].Text;

            if (Order == SortOrder.Ascending)
            {
                return str1.CompareTo(str2);
            }
            else
            {
                return str2.CompareTo(str1);
            }
        }
    }
}
0 голосов
/ 18 сентября 2012

Я использовал класс Neil-N, но изменил оператор if, чтобы проверить свойство Type вместо свойства Tag. Я установил для каждого столбца номер типа (вместо текста), в котором было целочисленное значение. Сортировка отлично работает.

if (l1.ListView.Columns[Column].Type.ToString() == "Number")
0 голосов
/ 31 июля 2009

Я бы сделал это в источнике данных (модели) вместо представления. Сортируйте это там, и это должно обновить это в представлении через привязку данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...