本文档提供关于在 XtraGrid 中数据排序的基础信息。 排序功能可用于网格视图 (包括其子类) 和卡片视图。
视图 允许通过无限数目的列对数据排序。 当排序被应用于视图时,记录被重新排列,以符合当前的排序设置。XtraGrid 为所有类型的数据源管理自动排序。 从版本 3.0 以上开始,网格控件自身进行数据排序,不再把此功能委托给下层数据源。 下面的小节提供了关于排序功能的更多细节:
在运行时刻排序
要按照网格视图的列对数据排序,或者改变列的排序顺序,则最终用户可以单击 列标头。 列的当前排序顺序是由 排序符号 (一个显示在列标头右边缘的小箭头) 标识的。 如果数据以升序排序,则排序符号显示为一个向上的箭头。 在按降序排序时,排序符号显示为一个向下的箭头。 如果列没有被排序,则排序符号被隐藏。 在下面的插图中,数据按照 Country 列升序排序,并按照 City 列降序排序。
在卡片视图中,可以通过 “Customization(自定义)”按钮 为列 (卡片字段) 应用排序。 单击此按钮调用列出了可用列的下拉控件。 在下拉控件中,单击列的 “Sort(排序)” 按钮 与单击网格视图中的 列标头 类似 。
如果没有应用排序,则单击列标头 (在卡片视图中为“排序”按钮) 会根据列的内容以升序对数据排序。 如果已经为列应用排序,则后续单击会反转当前的排序顺序。 注意,在列标头 (“排序”按钮) 上的常规单击,会清除任何其他列的排序设置。 要保持其他列现有的排序设置,则在单击时按下 SHIFT 键。 当需要同时为多个列应用排序时,这是很有用的。 可以通过在单击列标头 (“排序”按钮) 的同时按下 CTRL 键,来清除列的排序。
在网格视图中,最终用户也可以通过 列标头的上下文菜单 对列进行排序:
该菜单的可用性由视图的 GridOptionsMenu.EnableColumnMenu 属性控制。 菜单的内容可以被定制,如同在 为弹出式菜单实现自定义行为 章节中描述的那样。
在网格视图中, GridOptionsCustomization.AllowSort 属性可以用于阻止最终用户改变视图中任何列的当前排序设置。 OptionsColumn.AllowSort 选项可以用于阻止特定列的排序设置被改变。 对网格视图和卡片视图中的列,此选项都是可用的。 注意,如果禁用某个列的排序,则记录不能按照该列进行分组。 要获得更多关于分组信息,请参阅 分组概述 文档。
不管网格的 GridOptionsCustomization.AllowSort 和列的 OptionsColumn.AllowSort 属性值如何,始终可以通过代码改变排序顺序。
通过代码排序
要为列应用排序,则可以使用下列方法:
- 把所需列的 GridColumn.SortOrder 属性设置为 ColumnSortOrder.Ascending 或 ColumnSortOrder.Descending。
- 把一个适当的项添加到 ColumnView.SortInfo 集合中。 每个项都由 GridColumnSortInfo 对象表示,并且此对象标识了列及其相关的排序顺序。
要移除列的排序,则可以执行下列操作:
- 把列的 GridColumn.SortOrder 属性设置为 ColumnSortOrder.None。
- 从 ColumnView.SortInfo 集合中移除引用了所需列的项。
- 调用 ColumnView.ClearSorting 方法。 这样将移除所有列的排序设置 (分组列除外)。
ColumnView.SortInfo 属性维护视图中排序列和分组列的集合。 因此添加元素到集合中以及从集合中移除元素,将应用或删除对特定列的排序。 列的 GridColumn.SortOrder 属性将自动反映对排序设置所作出的更改。
与此类似,当列的 GridColumn.SortOrder 属性值设置为 ColumnSortOrder.Ascending 或 ColumnSortOrder.Descending 时,一个项被添加到 ColumnView.SortInfo 集合中。 把 GridColumn.SortOrder 属性设置为 ColumnSortOrder.None,则从 ColumnView.SortInfo 集合中移除相应的项。
下列代码展示了如何按照 Country 列以升序对数据排序:
C# | 复制代码 |
---|---|
gridView1.Columns["Country"].SortOrder = DevExpress.Data.ColumnSortOrder.Ascending;
|
Visual Basic | 复制代码 |
---|---|
GridView1.Columns("Country").SortOrder = DevExpress.Data.ColumnSortOrder.Ascending
|
通过代码改变列的排序顺序时,不清除其他列的排序设置。 因此上述代码只是把 Country 列添加到之前已排序的列集合中。 在某些情况下,可能需要在应用新的排序之前,先移除按照其他列的排序。
下列代码展示了如何通过 ColumnView.SortInfo 集合,为 Country 和 City 列应用排序,同时移除任何应用于其他列的排序。 为了达到此目的,使用了 GridColumnSortInfoCollection.ClearAndAddRange 方法。 此方法删除现有的排序项,然后添加新建的排序项。
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Grid; using DevExpress.XtraGrid.Columns; using DevExpress.Data; // ... GridView View = gridControl1.FocusedView as GridView; gridView1.SortInfo.ClearAndAddRange(new GridColumnSortInfo[] { new GridColumnSortInfo(view.Columns["Country"], ColumnSortOrder.Ascending), new GridColumnSortInfo(view.Columns["City"], ColumnSortOrder.Descending) }); |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Grid Imports DevExpress.XtraGrid.Columns Imports DevExpress.Data ' ... Dim View As GridView = GridControl1.FocusedView GridView1.SortInfo.ClearAndAddRange(New GridColumnSortInfo() { _ New GridColumnSortInfo(view.Columns("Country"), ColumnSortOrder.Ascending), _ New GridColumnSortInfo(view.Columns("City"), ColumnSortOrder.Descending) _ }) |
使用 GridColumn.SortOrder 属性为这两个列应用排序的等效代码如下:
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Grid; using DevExpress.Data; // ... GridView View = gridControl1.FocusedView as GridView; view.BeginSort(); try { View.ClearSorting(); View.Columns["Country"].SortOrder = ColumnSortOrder.Ascending; View.Columns["City"].SortOrder = ColumnSortOrder.Descending; } finally { View.EndSort(); } |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Grid Imports DevExpress.Data ' ... Dim View As GridView = GridControl1.FocusedView view.BeginSort() Try View.ClearSorting() View.Columns("Country").SortOrder = ColumnSortOrder.Ascending View.Columns("City").SortOrder = ColumnSortOrder.Descending Finally View.EndSort() End Try |
在本示例中使用的 ColumnView.ClearSorting 方法清除排序的列集合。 当多个列的排序设置被同时改变时,调用 ColumnView.BeginSort 和 ColumnView.EndSort 方法来防止过多的数据排序 (请参阅 防止过度的数据重新排序 小节)。
在已排序的列集合中,列的顺序是重要的,因为它定义了数据的排序顺序。 首先,是根据集合中的第一个列对数据排序。 然后,根据第二个列对数据排序,等等。
可以通过只读的 ColumnView.SortedColumns 集合,来访问所有已排序的列。 此集合与 ColumnView.SortInfo 集合不同,它不存储分组列。 列在 ColumnView.SortedColumns 集合中的位置由 GridColumn.SortIndex 属性指定。 可以使用该属性来取消排序,以升序对列应用排序,或者改变列在其他排序列之间的位置。当列的排序设置被改变时,网格执行下列操作:
- 引发 ColumnView.StartSorting 事件;
- 根据设置对数据排序;
- 引发 ColumnView.EndSorting 事件。
防止过度的数据重新排序
假设您的代码由多个语句组成,每个语句修改一个或多个列的排序设置。 例如,在上述示例中,在 try 和 finally 关键字之间的代码首先移除所有列的任何排序,然后依次把排序应用于 Country、City 列。 在默认情况下,在每次调用修改排序设置的功能 (属性) 之后,网格都重设数据顺序,因此在本示例中在默认情况下数据会被重设三次顺序。
为了防止过度的数据重新排序,可以使用 ColumnView.BeginSort 和 ColumnView.EndSort 方法。 在这种情况下,仅在调用 ColumnView.EndSort 方法之后,数据才被排序,并且考虑所有近来对排序设置作出的更改。
每个 ColumnView.BeginSort 调用都必须有一个相应的 ColumnView.EndSort 调用。 要确保这样,则使用 try...finally 块。
批量更改概述 章节提供了关于由 XtraGrid 提供的批量更改方法的信息。 这些方法允许防止过度的可视化更新、表达式排序和选中区更新、以及过度的汇总项和样式条件集合更新。
GridColumnSortInfoCollection.ClearAndAddRange 方法 (在上述某个示例中使用) 调用方法来防止过多的内部重设数据顺序。 因此不需要使用 ColumnView.BeginSort 和 ColumnView.EndSort 封闭该方法。
如果在 ColumnView.BeginSort 和 ColumnView.EndSort 方法中装入改变排序设置的代码,则在 ColumnView.EndSort 方法被调用之后,才对数据排序,并且 ColumnView.EndSorting 事件才发生。
根据取值和显示文本排序。 自定义排序
在默认情况下,GridColumn.SortMode 属性值设置为 ColumnSortMode.Default。 在这种情况下,将根据指派到列的 内置编辑器 的类型,通过编辑值或显示值对列数据排序。
对于使用 LookUpEdit 和 ImageComboBoxEdit 内置编辑器的列,通过显示值 (显示在列的单元格内的字符串) 对数据排序。
对于其他列,通过编辑值 (使用绑定数据源的取值进行同步) 对数据排序。 但是对于某些编辑器 (TextEdit、ComboBoxEdit 等等),编辑值与显示值匹配。
要强制让某个列使用特定的排序模式,则显式地把 GridColumn.SortMode 属性设置为 ColumnSortMode.Value 或 ColumnSortMode.DisplayText。如果标准的排序算法不符合需求,则 自定义排序 模式允许实现自定义排序逻辑。 要启用此模式,则把 GridColumn.SortMode 属性设置为 ColumnSortMode.Custom ,并接管 ColumnView.CustomColumnSort 事件。
在每个事件调用中,应该比较两个取值。 自定义比较的结果应该设置到事件的 CustomColumnSortEventArgs.Result 参数。 另外, CustomColumnSortEventArgs.Handled 参数必须被设置为 true,来指明比较已被处理。 如果此参数设置为 false,则调用默认的比较机制来比较取值。