在使用 XtraGrid 时,可能需要使用代码对行/卡片执行操作。 在这种情况下,需要获取一个行/卡片标识符,并把它指派到适当的属性,或者把它作为方法的参数。 可以通过读取属性或通过调用方法来获取行/卡片值。 也可能需要识别行的类型、位置等。 此主题涵盖了这些任务。
在网格视图及其子类中,数据记录通过行来呈现,而在卡片视图和布局视图中则通过卡片来呈现。 在本主题中,为了简化起见,术语 行 一般用于通指网格视图中的行,也指卡片视图/布局视图中的卡片。
识别行
视图 中的行是使用被称为 行句柄 的整数值来标识。 每个视图都使用下列规则把它的行与这些值相关联:
- 每个行都有一个行句柄,而不管当前是否可视 (由于滚动会导致某个行不可视,它也可以被隐藏在已折叠的 组 (网格视图 中) 内。
- 数据行句柄从零开始。 行句柄零被指派到视图内的第一个数据行。 这里“第一个”是指可视的行顺序,而不是记录在绑定数据源内的位置。 然后,连续的整数值被指派到其他数据行。 第二个数据行的句柄是 1,等等。 注意,修改行的顺序,则修改指派给行的句柄。 例如,这可以是对视图数据 排序 的结果。 因此,在不同的时刻,特定的行句柄可能会指向不同的行。
- 分组行的句柄都是负数。 第一个可视的分组行由 -1 行句柄标识。 第二个可视的分组行的句柄是 -2,等等。 此外,当行被重新排序时,分组行的句柄会改变。
- 每个细节视图的 克隆 都提供独立于其他克隆的行句柄。 因此只有在 GridControl.MainView 中或在一个细节视图克隆内的行句柄是唯一的。 请参阅 模式视图与克隆视图 主题获得关于克隆视图的细节。
在视图内的可视行也可以通过其 可视索引 标识。 这些索引也从零开始。 连续的整数被指派到其他可视行。 注意,也只有在 GridControl.MainView 中或在一个细节视图克隆内的可视索引是唯一的。
我们考虑用于比较行句柄和可视索引的行布局示例。 这将举例说明分配规则,以及在行句柄与可视索引之间的关系。 首先是最简单的示例: 单个视图,没有应用分组。 在这种情况下, 可视索引与行句柄相匹配。 请参阅下面的插图。
下面是一个更复杂的示例。 它展示了数据行句柄和分组行句柄。 在这种情况下,可视索引与行句柄不匹配。
在本例中,“City: Salzburg”分组行包含了两个内嵌的数据行 (译者注: 其行句柄分别为 2 和 3)。 因此最底部的数据行(“Ipoh Coffee - 30 - $1,104.00”)的行句柄等于 4,而不是 2。
最后,我们考虑一个呈现了主/从关系的示例网格控件。 按照上面的说明,GridControl.MainView 中及每个细节视图克隆中的可视索引和行句柄都是唯一的。 下面的插图举例说明了这一点。
使用行句柄和可视索引
通常,视图通过行句柄来标识它们的行。 例如,ColumnView.FocusedRowHandle 属性通过句柄指定获得焦点的行。 ColumnView.FocusedRowChanged 事件传递以前和当前获得焦点的行的句柄作为参数。 当访问或更改单元格取值时,需要提供适当的行句柄。 在展开一个分组行时,GridView.GroupRowExpanding 事件也通过句柄来标识受影响的分组行。 还有非常多的示例。
视图也使用可视索引来引用行。 例如,网格视图的 GridView.TopRowIndex 属性把视图滚动到由可视索引指定的行。 ColumnView.GetNextVisibleRow 方法返回由前一行的可视索引指定的可视索引。
视图提供了把行句柄转换为可视索引的方法,反之亦然。 使用 ColumnView.GetVisibleIndex 和 ColumnView.GetVisibleRowHandle 方法来达到此目的。
获取数据源中的数据行和行索引
行句柄和可视索引反映了行在视图中的可视顺序,并且在改变行的位置或可视化状态时,会改变行句柄和可视索引。 在许多情形中,恒定引用特定行的最佳解决方案是使用行对象 (在绑定数据源中表示记录的对象,例如 DataRow 对象 —— 数据源是 DataTable 时)。
考虑下面的示例。 假设需要在特定列中更改行子集的取值。 要设置列的取值,可以使用 ColumnView.SetRowCellValue 方法,此方法需要传递一个行句柄作为参数。 要使用此方法,首先要存储被修改行的行句柄。 其次,要为每个行句柄调用 SetRowCellValue 方法。 但是,使用这种方式,如果数据根据目标列被排列或筛选,则可能会错误地更改不恰当的记录,因此而导致不可预期的结果。 如果数据根据目标列进行了排序或筛选,则修改单个行可能会影响后续行的句柄。 结果,已经存储的行句柄将指向不恰当的行。 后续调用 SetRowCellValue 方法将会修改不恰当的行。在本例中的正确方法是使用行对象,而不是行句柄。 首先,获取目标行对象。 然后,使用由行对象提供的方法来修改它们。
要获取与特定行句柄对应的行对象,则使用 ColumnView.GetRow 或 ColumnView.GetDataRow 方法。 使用 GetRow 方法时,不需要考虑绑定数据源的类型,而 GetDataRow 方法仅适用于绑定数据源是 DataTable 或 DataView 对象的情形。
在特定情况下,可能需要获取行在绑定数据源中的索引,它与视图中的特定行句柄相对应。 要执行此操作,则使用 ColumnView.GetDataSourceRowIndex 方法。 要通过行在绑定数据源中的索引来获取行句柄,则使用 ColumnView.GetRowHandle 方法。
特殊的行句柄
行 | 行句柄 | 说明 |
---|---|---|
自动筛选行
(由网格视图及其子类支持) |
GridControl.AutoFilterRowHandle | 使用 自动筛选行,最终用户可以即刻筛选数据。 在该行内键入文本,则自动为视图创建和应用一个筛选。 请参阅 自动筛选行 获得更多信息。 |
新建项行/卡片
(由网格视图、卡片视图、布局视图及其子类支持) |
GridControl.NewItemRowHandle | 假如允许把行添加到数据源中,则 新建项行/卡片 允许最终用户添加新记录到数据源中。 请参阅 添加和删除记录 主题来获得更多信息。
请参阅 新建项行/卡片 获得关于这种行的细节。 |
无效的行
(由网格视图、卡片视图、布局视图及其子类支持) |
GridControl.InvalidRowHandle | 通常,该行句柄对应于在视图中不存在的行。
GridControl 在特定情况下,也传递这种行句柄作为其事件处理程序的参数。 例如,这种行句柄被传递到 GridView.GroupRowCollapsing 事件处理程序 (当使用 GridView.CollapseAllGroups 方法同时折叠所有分组行时)。 |
使用这些行句柄与使用常规行句柄非常相似,但是有一些限制。 例如,如果自动筛选行或新建项行/卡片可视,并且需要把焦点设置到其中任一行,则把视图的 ColumnView.FocusedRowHandle 属性设置为 GridControl.AutoFilterRowHandle 或 GridControl.NewItemRowHandle。 注意,不能通过把 ColumnView.FocusedRowHandle 属性设置为 GridControl.InvalidRowHandle 来清除焦点。
对于常规数据行和自动筛选行,可以使用 ColumnView.SetRowCellValue 方法来设置单元格取值。 对于新建项行/卡片,此方法仅当新行/卡片正在添加时有效 (在 ColumnView.AddNewRow 方法已经被调用之后,或者在内建导航器中的“添加”按钮已经被单击之后马上调用)。