Master-Detail Relationships
- 8 minutes to read
The Grid Control supports master-detail data presentation. This type of data representation requires at least two data tables — master and detail (the number of detail levels is not limited). These tables are linked by a one-to-many relationship (a single row in the first table can be related to one or more rows in the second table, but a row in the second table can be related to only one row in the first table). Master and detail tables are also called parent and child tables.
Get Started: Create a Data Grid with Master and Detail Views
Follow the Data Binding section tutorials to bind a Data Grid to the sample AdventureWorks2014 data base running on a local SQL server. When you choose database objects, select two tables associated with the same key (in the figure below, the “PurchaseOrderID” field links a child “PurchaseOrderDetail” table with a master “PurchaseOrderHeader” table) and use the master table as a Data Grid source.
Run the application. Notice that the row expand/collapse buttons within each row are disabled because the detail data is not yet loaded.
Drag the TableAdapter component associated with the detail data table from the Visual Studio toolbox and add the following code:
public Form1() {
InitializeComponent();
// This line of code is generated by the Data Source Configuration Wizard
purchaseOrderHeaderTableAdapter1.Fill(adventureWorks2014DataSet1.PurchaseOrderHeader);
// Add this line to load detail data
purchaseOrderDetailTableAdapter1.Fill(adventureWorks2014DataSet1.PurchaseOrderDetail);
}
The Data Grid now displays both master and detail tables. The control uses copies of a master View to show detail data. For example, the master View in the figure below has its GridOptionsView.ShowGroupPanel setting disabled. As a result, detail Views are missing their group panels as well.
To replace this auto-generated detail View with your own, click the “Click here to create a new level” link in the Level Designer, then the “Retrieve Details” button. Finally, create a new View assigned to the detail level.
Show Predefined Detail Views
The Data Grid displays the detail views (relationships) that exist in its GridControl.LevelTree. Disable the grid’s ShowOnlyPredefinedDetails option to display all relationships in the bound data source.
Important
The grid retrieves the detail Views by level names that must match real master-detail relation names (or collection property names, if your pattern Views display collection property data). When you click “Retrieve Details” at design time, the level names for all relations found in a data source are set automatically.
For other cases, specify the valid name manually through the GridControl.LevelTree collection. Levels with invalid level names use master View copies instead of your custom Views.
Read the Working with Master-Detail Relationships in Code topic for information about other binding scenarios.
Patterns and Clones
Views that you assign to detail Data Grid levels are pattern Views. When a master row is expanded, the Data Grid dynamically creates a copy of a pattern View to display detail data. This copy is called a clone View. In the example above, “gridView2” is a pattern View whose clones display actual data at runtime.
Pattern Views do not contain any real data. Do not use their API to retrieve columns, rows, cell values, summaries, etc. (for instance, the ColumnView.GetRow(Int32) method). Use this API only with clone Views, which you can access through the following properties and methods:
- GridControl.MainView — returns the top most View.
- GridControl.FocusedView — returns the focused View.
- GridControl.DefaultView — returns the currently maximized View.
- GridView.GetDetailView — returns a detail clone View for a given master row.
- The
sender
parameter of Grid Control events.
Detail View Height
Use the BaseView.DetailHeight property to set the height of a detail View. For Layout Views, this property specifies the maximum allowed height, while Views automatically resize themselves to fit displayed cards.
Rename Detail Tabs
In the example above, the child View level changed its name from the default “Level 1” to “FK_PurchaseOrderDetail_PurchaseOrderHeader_PurchaseOrderID” after the “Retrieve Details” button is clicked at design time. This text is called a level name
Important
A level name must match the name of the master-detail relationship with which the View is associated. If your pattern View displays collection property data, a level name must match this collection property name.
Tabs that contain detail Views have the same captions as corresponding level names. If a level name is written in CamelCase and has no spaces between words (for instance, “ForeignVendorList”), Data Grid adds spaces in front of capital letters to split this name into separate words (“Foreign Vendor List”). To rename these tabs, use one of the following techniques:
- Change the BaseView.ViewCaption property for the detail View.
- Handle the GridView.MasterRowGetRelationDisplayCaption event for the detail View.
HTML-Formatted Tab Captions
You can enable the master view’s AllowHtmlDrawDetailTabs option to parse HTML-inspired tags in detail tab captions.
Custom Images and Appearance Settings for Individual Detail Tabs
The DetailTabStyle event fires for each detail view. This event allows you to assign a custom image to the processed tab and apply custom appearance settings to the tab caption.
Use the Caption event argument to obtain or change the processed tab caption. The following arguments allow you to specify the tab style:
- Appearance — provides access to background and foreground colors, font style, and so forth.
- ImageOptions — provides access to a raster or vector image assigned to the tab.
You can also use the IsSelected argument to apply a specific style depending on whether the tab is selected.
The RefreshDetailTab(Int32) method allows you to update a detail tab at runtime.
Synchronize Clones
Enable the BaseView.SynchronizeClones property to synchronize all clone Views created from the same pattern View. When you group data, resize a column, or perform any other operation that changes the appearance of a clone View, the Data Grid applies the same changes to all detail Views synchronized with the modified View.
Scroll Modes
Every View, whether it is a master or a clone View, has its own scroll bar in Classic mode. Use the GridOptionsDetail.DetailMode property to switch to Embedded mode, where only one master scroll bar is present.
Detail Tooltips
The expand/collapse buttons for master rows can display tooltips that contain clickable links. Users can utilize these links to open required clone Views when View tabs are hidden (the GridOptionsDetail.ShowDetailTabs property).
The GridOptionsDetail.EnableDetailToolTip option turns detail tooltips on or off.
Master-Detail Grouping
The GridOptionsView.ShowChildrenInGroupPanel property allows you to have one group panel for all master and detail Views.
This feature requires clone Views to be synchronized. To specify the level name that a group panel displays for clone View columns, use the GridView.ChildGridLevelName property.
Zoom Details
If the GridOptionsDetail.AllowZoomDetail option is enabled, clone Views display the Zoom/Back button. Users can click this button to maximize details for the current master row. If the master row has multiple related clone Views, they are placed inside tabs.
Related API
- BaseView.ZoomView, BaseView.NormalView — call these methods to manually zoom Views in and out.
The following example shows how to maximize the first detail View for the focused master row, process it, and then restore the layout.
using DevExpress.XtraGrid.Views.Grid; using DevExpress.XtraGrid.Views.Base; GridView View = gridControl1.FocusedView as GridView; if(View.IsMasterRow(View.FocusedRowHandle)) { int detailIndex = 0; View.SetMasterRowExpandedEx(View.FocusedRowHandle, detailIndex, true); ColumnView childView = (ColumnView)View.GetDetailView(View.FocusedRowHandle, detailIndex); if(childView != null) { childView.ZoomView(); // TODO // ... childView.NormalView(); } }
- GridControl.DefaultView — provides access to the currently maximized View. Matches the GridControl.MainView property value if no detail View is currently maximized.
The following code handles the CTRL+Left Arrow/CTRL+Right Arrow to zoom detail Views in and out.
private void gridControl1_ProcessGridKey(object sender, System.Windows.Forms.KeyEventArgs e) { if(e.Control) { if(e.KeyCode == Keys.Right) { gridControl1.FocusedView.ZoomView(); e.Handled = true; } else if(e.KeyCode == Keys.Left) { gridControl1.DefaultView.NormalView(); e.Handled = true; } } }
- GridControl.DefaultViewChanged — fires when a user zooms a detail View.
How to Display Master and Detail Tables in Separate Grid Controls
To display detail data in a separate Grid Control, set this control’s DataMember property to the detail collection property name. See the following articles for examples:
- How to Display Master-Detail Tables in Separate Grid Controls (GitHub)
- How to Use Two XtraGrid Controls to Display Collections of Persistent Objects (XPO) with a One-to-Many Association
Disable Master-Detail Mode
Set the EnableMasterViewMode property to false
to disable the Master-Detail mode.
Master-Detail Mode Limitations
- Master-Detail mode is disabled when pixel-based scrolling is enabled. See the following topic to learn more: GridOptionsBehavior.AllowPixelScrolling.
- Master-Detail mode is not supported in large data sources.
- Master-Detail mode is not supported while the Split Presentation feature is in use.
- Only GridView and its descendants (BandedGridView and AdvBandedGridView) can be master views.
Cheat Sheets and Best Practices
Read the following quick-reference guide for general information and examples:
Master-Detail Mode - DevExpress WinForms Cheat Sheet