使用vb.net 对 Windows Form 按列排序 ListView 项目

** 使用 Windows Form 按列排序 ListView 项目 **

** 摘要: ** 说明如何根据所单击的列在 Microsoft .NET 中的 ListView 控件提供项目排序。

** 简介 **

** ListView ** 控件是显示文件系统信息和显示 XML 或数据库数据的非常好的方式。 ListView 控件通常用于显示表示项目以及项目文本的图形图标。此外, ListView 控件还可以用于显示有关子项目中项目的其他信息。例如,如果 ListView 控件显示一列文件,您可以配置 ListView 控件来显示作为子项目的诸如文件大小和属性的详细信息。要显示 ListView 控件中的子项目信息,必须将 View 属性设置为 View.Details 。此外,您必须创建 ColumnHeader 对象并将这些对象分配给 ListView 控件的 Columns 属性。在设置这些属性后,项目以行和列格式进行显示,类似于 DataGrid 控件。以这种方式显示项目的能力使 ListView 控件为从任意类型的数据源显示数据提供了快速、简便的解决方案。

对 ** ListView ** 控件进行排序是通过使用 ListViewSorting 属性而提供的。这使您可以定义要应用到项目的排序类型。如果您只想按项目排序,这是一个非常好的功能。如果您要按子项目排序,必须使用 ListView 控件的自定义排序功能。本文将说明如何在 ListView 控件中执行自定义排序,以及在排序时如何处理特殊的数据类型条件。

** ListView 控件的自定义排序功能 **

** ListView ** 控件提供了您可以使用排序的功能,而不是由 Sorting 属性提供。当 ListView 控件使用 Sorting 属性排序项目时,它使用一个实现 System.Collections.IComparer 接口的类。这个类提供用于排序每个项目的排序功能。为了按子项目进行排序,您必须创建自己的类,来实现反过来可以实现 ListView 控件所需排序的 IComparer 接口。该类利用构造函数进行定义,该构造函数可以指定 ListView 控件排序所用的列。在您创建这个类后(通常将其作为窗体的嵌套类),您可以创建该类的一个实例,并将其分配到 ListViewListViewItemSorter 属性。当调用 Sort 方法时,这会确定 ListView 控件将要使用的自定义排序类。 Sort 方法执行 ListView 项目的实际排序。

升序排序

以下部分提供的基本示例说明了在 ** ListView ** 控件中基于其子项目的排序。该示例说明了以升序排序 ListView 控件中的项目。升序排序或降序排序将会在本文的稍后部分进行说明。此处的目标就是说明在 ListView 控件中进行自定义排序的基本要求。

** 初始化控件 **

如果要开始,请创建 ** ListView ** 控件的实例,并将其添加到窗体中。在控件位于窗体上后,使用 Items 属性将项目添加到 ListView 控件。您可以添加任意多的项目,只要确保每个项目的文本都是唯一的。在您创建项目时,为每个项目添加两个子项目。第一个子项目应该包含数字信息,第二个子项目包含日期信息。下面的表格示例说明该信息在 ListView 控件中可能如何显示。

项目

|

子项目 1

|

子项目 2

---|---|---

Alpha

|

1.0

|

4/5/1945

Charlie

|

3.5

|

1/9/1920

Bravo

|

2.4

|

12/8/1930

创建两个 ** ColumnHeader ** 对象,并将它们分配到 ListView 控件的 Columns 属性中。将 View 属性设置为 View.Details

** 处理 ColumnClick 事件 **

为了确定按哪个子项目集进行排序,您需要了解用户何时单击某个子项目的列标题。为此,您需要为 ** ListView ** 的 ColumnClick 事件创建一个事件处理方法。将事件处理方法作为窗体中的一个成员,并确保它包含的签名相似于下面代码示例所显示的签名。

'Visual Basic

Private Sub listView1_ColumnClick(sender As Object, e As System.Windows.Forms.ColumnClickEventArgs)

End Sub

//C#

private void listView1_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)

{

}

通过向窗体的构造函数中添加代码,将事件处理方法连接到 ** ListView ** 控件,如下面的示例所示。

'Visual Basic

AddHandler listView1.ColumnClick, AddressOf Me.listView1_ColumnClick

//C#

this.listView1.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.listView1_ColumnClick);

将下面的代码添加到用于 ** ColumnClick ** 事件的事件处理方法。

'Visual Basic

' Set the ListViewItemSorter property to a new ListViewItemComparer

' object.

Me.listView1.ListViewItemSorter = New ListViewItemComparer(e.Column)

' Call the sort method to manually sort.

listView1.Sort()

//C#

// Set the ListViewItemSorter property to a new ListViewItemComparer

// object.

this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column);

// Call the sort method to manually sort.

listView1.Sort();

添加到事件处理方法的代码会利用 ** ListViewItemComparer ** 类(在下一部分中定义)的新实例来设置 ListView 控件的 ListViewItemSorter 属性,然后分配要单击的列。被单击的列作为事件参数的组成部分进行传递。在设置 ListViewItemSorter 属性后,调用 Sort 方法来执行手动排序。

** 创建 ListViewItemComparer 类 **

正如前面提到的那样,在 ** ListView ** 控件中进行自定义排序的关键在于创建实现 System.Collections.IComparer 接口的类。就是这个类为项目提供排序。对于这个示例,定义了名为 ListViewItemComparer 的类,并且将其添加为窗体的嵌套类。ListViewItemComparer 执行传递到其构造函数的指定列的基本升序排序。将以下类定义添加到 Form 类并确保它在窗体内是正确嵌套的。

'Visual Basic

' Implements the manual sorting of items by column.

Class ListViewItemComparer

Implements IComparer

Private col As Integer

Public Sub New()

col = 0

End Sub

Public Sub New(column As Integer)

col = column

End Sub

Public Function Compare(x As Object, y As Object) As Integer _

Implements System.Collections.IComparer.Compare

Dim returnVal as Integer = -1

returnVal = [String].Compare(CType(x, _

ListViewItem).SubItems(col).Text, _

CType(y, ListViewItem).SubItems(col).Text)

Return returnVal

End Function

End Class

//C#

// Implements the manual sorting of items by column.

class ListViewItemComparer : IComparer {

private int col;

public ListViewItemComparer() {

col=0;

}

public ListViewItemComparer(int column)

{

col=column;

}

public int Compare(object x, object y)

{

int returnVal = -1;

returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,

((ListViewItem)y).SubItems[col].Text);

return returnVal;

}

}

以一个名为 ** Compare ** 的 IComparer 接口的必要方法执行排序。这个方法将两个对象作为参数,而参数会包含要进行比较的两个项目。当在 ListView 控件的 ColumnClick 事件处理方法中调用 Sort 方法时, Sort 方法会使用已定义并已分配到 ListViewItemSorter 属性的 ListViewItemComparer 对象,并且调用其 Compare 方法。创建 ListViewItemComparer 对象后,分配给它被单击的列的索引。该列的索引用于从需要进行排序的列中访问子项目。然后,将子项目传递到 String.Compare 方法,该方法比较项目并返回三个结果中的一个。如果 x 参数中的项目小于 y 参数中的项目,则返回一个小于零的值。如果两个项目相同,则返回零。最后,如果 x 参数中的值大于 y 参数中的值,则返回一个大于零的值。 Compare 方法返回的值传递回 Sort 方法,这确定正在比较的每个项目在列中的位置。 Sort 方法可以根据在所选择列中排序所有子项目的需要对 Compare 方法调用任意多次。

前面的示例就完成了。如果您运行该示例并单击 ** ListView ** 控件的列标题,项目将会按字母顺序或数字顺序进行适当地排序。唯一不能正确排序的列就是包含日期信息的列。稍后本文将介绍排序日期列。

这个示例说明了在 ** ListView ** 控件中执行基本手动项目排序所需要的基本要素。接下来的部分会扩展这个示例,提供升序和降序排序功能。

升序或降序排序

** ListView ** 控件的用户将期望具有同时以升序和降序排序项目的功能。为了实现这个功能,需要对前面的示例进行某些改动,以便使 Compare 方法可以确定要排序的项目。

** 对窗体的更改 **

通常情况下,要在升序和降序排序之间切换,您要多次单击列标题。用户期望如果他们单击列标题,排序将会发生,随后再次单击将更改排序顺序。前面的代码示例需要能够确定何时多次单击列。为此,您可以将一个私有整数变量添加到 ** Form ** 类。这个变量存储上一次单击的列。 ColumnClick 事件处理方法将使用这个变量来比较上一次的列与当前单击的列,并确定它们是否相同。将以下成员定义添加到 Form 类中。

'Visual Basic

Dim sortColumn as Integer = -1

//C#

private int sortColumn = -1;

** ColumnClick 事件处理方法的更改 **

在前面的示例中定义的 ** ColumnClick ** 事件处理方法需要进行修改,以便跟踪单击过的列和当前排序顺序。添加以下代码以替换在前面的示例中创建的 ColumnClick 事件处理方法中的代码。

'Visual Basic

Private Sub listView1_ColumnClick(sender As Object, e As

System.Windows.Forms.ColumnClickEventArgs)

' Determine whether the column is the same as the last column clicked.

If e.Column <> sortColumn Then

' Set the sort column to the new column.

sortColumn = e.Column

' Set the sort order to ascending by default.

listView1.Sorting = SortOrder.Ascending

Else

' Determine what the last sort order was and change it.

If listView1.Sorting = SortOrder.Ascending Then

listView1.Sorting = SortOrder.Descending

Else

listView1.Sorting = SortOrder.Ascending

End If

End If

' Call the sort method to manually sort.

<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow

Published At
Categories with Web编程
Tagged with
comments powered by Disqus