Other DevExpress WinForms Cheat Sheets
In master detail mode, the Data Grid does not use Views assigned to detail Data Grid levels to display detail data (we call these Views as Pattern Views). Instead, it dynamically creates copies of these View when a master row expands (these copies are called Clone Views), and copies property settings, columns, summaries, event handlers from Patterns to Clones.
Pattern Views only store settings - property values, filters, columns, summaries, etc. and they are never connected to data. As a result, their data-related methods, properties and settings have no effect.
If you wish to use a view configured at design time as a pattern view, the corresponding level name must match real master-detail relation names (or collection property names if your pattern Views display collection property data).
To access detail data and settings of detail views, you need to use methods and properties of Clone Views. This also applies to columns, summaries and data-related settings like filtering, sorting, grouping, etc. To access Clone Views, you can use the following API:
- GridControl.MainView - returns the top most View;
- GridControl.FocusedView - returns the focused View;
- GridControl.DefaultView - returns the currently maximized View;
- GridView.GetDetailView(Int32, Int32) - returns a detail clone view for a given master row;
- the
sender
parameter of the Clone View's event handlers.
To learn how to create a master detail relation using the designer or in code, refer to the following documentation:
Examples
How to obtain detail rows of a collapsed master row?
To obtain detail rows for a single master row, expand it with the GridView.ExpandMasterRow method (refer to Expand and Collapse Rows for more info), obtain detail rows, and collapse it back. If you perform these steps inside the GridControl.BeginUpdate/ GridControl.EndUpdate block, it will not affect performance and will go unnoticed by end-users (see the Batch Modifications help article) .
To retrieve detail rows for two or more master rows, we recommend that you use your data source API rather than Data Grid methods.
How to post detail View edits to a data source?
Use methods of clones, not patterns. To access a clone, you can use GridView.GetDetailView as demonstrated in the following section of the "Working with Master-Detail > Relationships in Code" help article: Access Views. Then, use the BaseView.CloseEditor and BaseView.UpdateCurrentRow methods as described in the following articles: Post Data to an Underlying Data Source, How to Update a Database.
How to save only modified detail View's cells or rows to a database?
DevExpress data-aware controls do not interact with an underlying database directly. Refer to the Database Interaction article for more information on this concept. Call the Clone View's BaseView.CloseEditor and BaseView.UpdateCurrentRow methods to ensure that all changes made in a detail view are pushed to the underlying data source. Then, use methods of your data source to post changes to the database.
How to access summary values in detail Views?
Obtain a required Clone View and access its summary. To access the clone, you can use GridView.GetDetailView or other methods described above.
How to display details as items available for selection in a separate column?
You can disable the EnableMasterViewMode setting and add a new Unbound Column. Handle the GridView.CustomRowCellEdit event to supply a separate instance of an editor (configured as required) to the column. See Replace Default Cell Editors to learn more. Finally, handle ColumnView.CustomUnboundColumnData to supply data to the column as we shown in this help article: Editable Unbound Columns with Custom Data:
C#masterGridView.OptionsDetail.EnableMasterViewMode = false;
GridColumn colDetails = masterGridView.Columns.AddVisible("Details");
colDetails.UnboundType = DevExpress.Data.UnboundColumnType.Object;
masterGridView.CustomUnboundColumnData += MasterGridView_CustomUnboundColumnData;
masterGridView.CustomRowCellEdit += MasterGridView_CustomRowCellEdit;
...
Dictionary<int, RepositoryItemGridLookUpEdit> editors = new Dictionary<int, RepositoryItemGridLookUpEdit>();
private void MasterGridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) {
GridView view = sender as GridView;
if (e.Column.FieldName == "Details") {
int key = view.GetDataSourceRowIndex(e.RowHandle);
RepositoryItemGridLookUpEdit ri = null;
if (!editors.TryGetValue(key, out ri)) {
ri = new RepositoryItemGridLookUpEdit();
ri.DisplayMember = nameof(Detail.Name);
ri.ValueMember = nameof(Detail.ID);
Master masterRow = view.GetRow(e.RowHandle) as Master;
ri.DataSource = Master.Details;
editors[key] = ri;
}
else
e.RepositoryItem = ri;
}
}
Dictionary<int, string> unboundData = new Dictionary<int, string>();
private void MasterGridView_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e) {
if (e.Column.FieldName == "Details") {
if (e.IsGetData) {
if (unboundData.ContainsKey(e.ListSourceRowIndex))
e.Value = unboundData[e.ListSourceRowIndex];
}
if (e.IsSetData && e.Value != null) {
unboundData[e.ListSourceRowIndex] = e.Value.ToString();
}
}
}
See also:
How to Display Master-Detail Tables in Separate Grid Controls