2009-07-31 76 views
6

Làm thế nào để sắp xếp cột các số nguyên trong một ListViewlàm thế nào để loại Số nguyên trong một listview

C#, .net 2.0, Winform

System.Windows.Forms.ListView

+1

ASP.NET? Windows Forms? –

+0

Tôi đã chỉnh sửa câu trả lời của mình để bao gồm một ví dụ hoàn chỉnh, có thể sắp xếp như cả văn bản và số –

Trả lời

19

Đây là cách tôi thực hiện có thể sắp xếp trên nhiều cột và có thể sắp xếp từng cột dưới dạng số hoặc dưới dạng văn bản.

sử dụng đầu tiên lớp này:

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); 
      } 
     } 
    } 
} 

Trong constructor của mẫu của bạn, thiết lập các sorter như thế này:

lvSeries.ListViewItemSorter = new Sorter(); 

Sau đó xử lý các ColumnClick thậm chí kiểm soát listview của bạn như thế này:

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(); 
    } 

Tất cả điều này phụ thuộc vào thuộc tính Thẻ của mỗi cột hoặc được đặt thành "Số eric "hay không, do đó, các sorter biết làm thế nào để sắp xếp.

Trong ví dụ trên, tôi truyền giá trị dưới dạng số float khi số, bạn có thể muốn thay đổi giá trị đó thành int.

+1

@Neil: Nó sắp xếp chúng dưới dạng văn bản theo mặc định. Ví dụ. 100 đến trước 3. Tuy nhiên, bạn có thể sắp xếp int đúng với ListViewItemSorter tùy chỉnh. –

+0

Ahh thats right. string là kiểu mặc định. –

+0

Tôi theo dõi ví dụ tại http://support.microsoft.com/kb/319401 nhưng nó vẫn không sắp xếp các số nguyên đúng.Wrt văn bản, Làm thế nào để bạn thiết lập cột mặc định để sắp xếp. Nó sắp xếp tốt trên cột 1 nhưng tôi không thể tìm thấy thuộc tính để thiết lập cho cột sắp xếp. – Brad

0

Tôi muốn làm điều đó trong nguồn dữ liệu (mô hình) thay vì xem. Sắp xếp nó ở đó và nó sẽ cập nhật nó trong khung nhìn thông qua databinding.

+0

, nghĩa là sắp xếp dữ liệu, dữ liệu trong trường hợp của tôi, và sau đó tải lại listview khi một cột được nhấp? – Brad

+0

không, thực hành không tốt để tải lại mỗi lần. Google "ListViewItemSorter" và nó sẽ chỉ cho bạn cách sắp xếp theo từng cột. –

+0

yeah đó là những gì tôi nghĩ. – Brad

3

Bạn sẽ cần phải tạo một lớp thực hiện giao diện IComparer (giao diện không chung). Trong lớp bạn đọc Text tài sản từ đúng tiểu mục, chuyển nó sang int, và làm sự so sánh:

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); 
    } 
} 

Sau đó bạn gán một Comparer như vậy đối với tài sản ListViewItemSorter và gọi các phương pháp phân loại của ListView kiểm soát:

// create a comparer for column index 1 and assign it to the control, and sort 
myListView.ListViewItemSorter = new IntegerComparer(1); 
myListView.Sort(); 
+0

một số cột là khác số văn bản ... tôi nên kiểm tra số trước khi sắp xếp? – Brad

+1

tôi đã từng làm một comparer ListViewItem đó kiểm tra mỗi phần tử Bạn sẽ được tốt hơn off có comparers riêng biệt và chọn cái nào để sử dụng dựa trên cột nào đang được sắp xếp, hoặc tạo ra một lớp so sánh, nơi bạn vượt qua một giá trị cho constructor cho biết liệu để sắp xếp dựa trên số, ngày hoặc văn bản, sau đó chuyển sang phương thức So sánh dựa trên giá trị đó (đó là giải pháp mà tôi đã đi trong trường hợp đó) –

+0

Ý tưởng hay. Nhưng tôi đã tạo một biến riêng tư như 'sortType' bên trong listview của tôi so sánh cla thay vào đó. – Chris

5

Nếu bạn đang bắt đầu với một ListView, cuộc sống của bạn sẽ được nhiều dễ dàng hơn nhiều nếu bạn sử dụng một ObjectListView để thay thế. ObjectListView là một trình bao bọc mã nguồn mở xung quanh .NET WinForms ListView, và nó giải quyết tất cả những vấn đề nhỏ gây khó chịu mà thường làm việc với một ListView rất bực bội. Ví dụ, nó tự động sắp xếp các int để '100' xuất hiện sau '3' (DateTimes, bools, và mọi thứ khác sắp xếp đúng).

Nghiêm túc, bạn sẽ không bao giờ muốn quay lại ListView đơn giản sau khi sử dụng ObjectListView.

Vâng, tôi là tác giả - nhưng điều đó không có nghĩa là tôi bị thiên vị ... OK, có thể là vậy :) Hãy nhìn here để biết ý kiến ​​của một số người khác.

+0

Cảm ơn ... sẽ cung cấp cho nó một ổ đĩa thử nghiệm ngay bây giờ – Brad

0

Tôi đã sử dụng lớp của Neil-N nhưng đã thay đổi câu lệnh if để kiểm tra thuộc tính Type thay vì thuộc tính Thẻ. Tôi đặt mỗi cột thành Type Number (thay vì Text) có giá trị số nguyên trong đó. Sắp xếp hoạt động tuyệt vời.

if (l1.ListView.Columns[Column].Type.ToString() == "Number") 
+0

Tôi không chắc chắn nếu bạn để lại một cái gì đó, nhưng [ColumnHeader] (http://msdn.microsoft.com/en-us/library/system.windows .forms.columnheader.aspx) không có thuộc tính 'Loại'. – Nick

0
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); 
      } 
     } 
    } 
} 
Các vấn đề liên quan