在主/从模式中要访问子数据,最终用户可以按下 展开按钮 展开主控行。 这样打开呈现特定主/从关系的细节视图。 如果主控行有几个细节视图,则可以通过 细节标签 或 细节工具提示 允许最终用户切换细节视图。 本主题描述了由 XtraGrid 提供的折叠和展开主控行,以及打开特定细节视图的方法。 本主题包含下列小节:
展开/折叠特定的主控行
用于展开/折叠主控行的方法需要 行句柄 作为参数。 行句柄表示唯一的整数值,并标识网格视图中的行。
在主/从模式中,主表网格视图可以显示下列行类型: 主控行、分组行、新建项行 和 自动筛选行。 要确定行是否为主控行,可以使用 GridView.IsMasterRow 方法。
每个主控行都可以有多个主/从关系,并且都显示在相应的细节视图中。 每个主控行一次只能显示一个细节视图。 在单击 展开按钮 展开主控行时,网格执行下列操作:- 确定默认的主/从关系。
默认的主/从关系由 GridView.DefaultRelationIndex 属性标识,此属性指定特定关系在其他关系之间的从零开始的索引。 在默认情况下,此属性值被设置为 0。
- 检查默认的细节视图 (对应于默认的主/从关系的细节视图) 是否包含数据。
如果细节视图不包含任何记录,并且 GridOptionsDetail.AllowExpandEmptyDetails 属性值设置为 true,则网格控件允许展开这个细节视图。 否则,网格控件尝试查找第一个非空的细节视图并且展开它。 注意,在默认情况下,不展开空细节视图。
注意 在主/从模式中,当通过 事件 使用数据装载网格控件时,需要接管 GridView.MasterRowEmpty 事件,以提供关于特定细节视图是否为空的信息。
- 创建和显示呈现所需细节数据的细节视图。
当最终用户折叠主控行时,所有为该行打开的细节视图都被销毁。
要通过代码展开和/或折叠主控行,可以使用下列方法:
- GridView.ExpandMasterRow
- GridView.CollapseMasterRow
- GridView.SetMasterRowExpanded
- GridView.SetMasterRowExpandedEx
这些方法提供了许多重载,可以用于为所需的主控行打开或关闭默认的或特定的细节视图。
可以通过索引或相关联的主/从关系名称标识细节视图。 关系的索引是一个介于 0 和 GridView.GetRelationCount - 1 范围内的值。 要通过索引获取关系名称,则使用 GridView.GetRelationName 方法。 GridView.GetRelationIndex 方法则执行反向的操作。要获取行的当前展开状态,则调用 GridView.GetMasterRowExpanded 或 GridView.GetMasterRowExpandedEx 方法。
示例 1
下列代码切换当前获得焦点视图中获得焦点行的展开状态:
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Grid; //... GridView View = gridControl1.FocusedView as GridView; int rHandle = View.FocusedRowHandle; view.SetMasterRowExpanded(rHandle, !view.GetMasterRowExpanded(rHandle)); |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Grid '... Dim View As GridView = CType(GridControl1.FocusedView, GridView) Dim rHandle As Integer = View.FocusedRowHandle view.SetMasterRowExpanded(rHandle, Not View.GetMasterRowExpanded(rHandle)) |
下表详细说明了调用 GridView.ExpandMasterRow、GridView.SetMasterRowExpanded 或 GridView.SetMasterRowExpandedEx 方法打开特定细节视图的可能情形:
原状态 | 结果 |
---|---|
主控行被初始折叠。 | 此方法展开主控行,创建特定的细节视图并使它可视。 |
初始时主控行被展开。 | 如果特定的细节视图不存在,则此方法创建细节视图,然后在细节区中显示它。 否则,此方法只把焦点切换到细节视图。 |
下表详细说明了调用 GridView.CollapseMasterRow、GridView.SetMasterRowExpanded 或 GridView.SetMasterRowExpandedEx 方法关闭特定细节视图的可能情形:
原状态 | 结果 |
---|---|
指定的细节视图不存在,或主控行被折叠。 | 此方法不作处理。 |
行中只有指定的细节视图存在。 所有其他细节视图没有被打开,或已经被销毁。 | 此方法折叠行。 |
在行中存在几个细节视图,包含指定的细节视图在内。 | 此方法销毁指定的细节视图,并把焦点切换到第一个可用的视图中。 |
要获得已打开细节视图的索引,则使用 GridView.GetVisibleDetailRelationIndex 方法。 可以通过 GridView.GetVisibleDetailView 方法获取细节视图自身。 通过 GridView.GetDetailView 方法, 可以访问细节视图 (不仅仅是打开的视图)。 注意,此方法仅当需要引用的细节视图存在时才工作。 如果指定的细节视图不存在,此方法返回 null。 在下列条件下会出现这种情况:
- 已经通过代码销毁了细节视图 (例如,传递引用细节视图的 relationName 参数调用了 GridView.CollapseMasterRow 方法)
- 最终用户折叠主控行,导致细节视图被销毁
- 还没有打开此细节视图 (例如,主控行已经被展开,但打开了其他细节视图)。
示例 2
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Grid; //... public void RecursExpand(GridView masterView, int masterRowHandle) { // Prevent excessive visual updates. masterView.BeginUpdate(); try { // Get the number of master-detail relationships. int relationCount = masterView.GetRelationCount(masterRowHandle); // Iterate through relationships. for(int index = relationCount - 1; index >= 0; index--) { // Open the detail View for the current relationship. masterView.ExpandMasterRow(masterRowHandle, index); // Get the detail View. GridView childView = masterView.GetDetailView(masterRowHandle, index) as GridView; if(childView != null) { // Get the number of rows in the detail View. int childRowCount = childView.DataRowCount; // Expand child rows recursively. for(int handle = 0; handle < childRowCount; handle ++) RecursExpand(childView, handle); } } } finally { // Enable visual updates. masterView.EndUpdate(); } } |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Grid Imports DevExpress.XtraGrid.Views.Base '... Public Sub RecursExpand(ByVal masterView As GridView, ByVal masterRowHandle As Integer) ' Prevent excessive visual updates. masterView.BeginUpdate() Try ' Get the number of master-detail relationships. Dim relationCount As Integer = masterView.GetRelationCount(masterRowHandle) ' Iterate through relationships. Dim index As Integer For index = relationCount - 1 To 0 Step -1 ' Open the detail View for the current relationship. masterView.ExpandMasterRow(masterRowHandle, index) ' Get the detail View. Dim childView As ColumnView = masterView.GetDetailView(masterRowHandle, index) If TypeOf childView Is GridView Then ' Get the number of rows in the detail View. Dim childRowCount As Integer = CType(childView, GridView).DataRowCount ' Expand child rows recursively. Dim handle As Integer For handle = 0 To childRowCount - 1 RecursExpand(childView, handle) Next End If Next Finally ' Enable visual updates. masterView.EndUpdate() End Try End Sub |
在默认情况下,如果主控行的细节视图不包含数据,则不展开主控行。 要允许打开空细节视图,则把 GridOptionsDetail.AllowExpandEmptyDetails 属性设置为 true。 GridView.IsMasterRowEmptyEx 方法返回特定的细节视图是否包含数据。
展开/折叠所有主控行
XtraGrid 没有提供为单个视图展开所有主控行的方法。 但是,可以编写程序来实现,如下所示:
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Grid; //... public void ExpandAllRows(GridView view) { View.BeginUpdate(); try { int dataRowCount = View.DataRowCount; for(int rHandle = 0; rHandle < dataRowCount; rHandle ++) View.SetMasterRowExpanded(rHandle, true); } finally { View.EndUpdate(); } } |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Grid '... Public Sub ExpandAllRows(ByVal View As GridView) View.BeginUpdate() Try Dim dataRowCount As Integer = View.DataRowCount Dim rHandle As Integer For rHandle = 0 To dataRowCount - 1 View.SetMasterRowExpanded(rHandle, True) Next Finally View.EndUpdate() End Try End Sub |
ExpandAllRows 方法可能要耗用一些时间,特别是视图和它的打开子视图中包含大量数据时。
事件
在展开主控行之前,网格控件产生 GridView.MasterRowExpanding 事件。 在细节视图被显示在 细节区 之前 (通过 细节标签 或 细节工具提示 或通过代码切换),此事件也发生。 此事件提供了 Allow 参数,可以用于防止细节视图在屏幕上显示。 此事件的其他参数标识主控行和受影响的细节视图。
如果仅当细节视图被创建时 (而不是重新获得焦点时),才需要执行某些操作,则可以接管 GridControl.ViewRegistered 事件。
在细节视图被显示之后,GridView.MasterRowExpanded 事件发生。 此事件只用作通知。当试图折叠主控行时,或者当尝试通过 GridView.CollapseMasterRow 或 GridView.SetMasterRowExpandedEx 方法销毁细节视图时,GridView.MasterRowCollapsing 事件发生。 此事件的 Allow 参数允许取消该操作。 RelationIndex 参数标识正被关闭的细节视图。 如果 RelationIndex 被设置为 -1,则推定整个主控行正要被折叠,并且它的所有细节视图都应该被销毁。
在主控行被折叠之后,或在细节视图被销毁之后,用作通知的 GridView.MasterRowCollapsed 事件发生。要阻止特定细节视图被销毁,可以接管 GridControl.ViewRemoved 事件。