Iterate Through Rows and Cells in Code

  • 7 minutes to read

This topic demonstrates how to access data items one by one. Refer to the Processing Group Rows topic for information on how to process group rows.

Iterate Through Rows

The GridControl identifies data rows by their handles or visible indexes. The DataControlBase.VisibleRowCount property returns the total number of visible group and data rows. To iterate through rows, use a counter from 0 to the value of the DataControlBase.VisibleRowCount property. In this code sample, we use the GridControl.GetRowHandleByVisibleIndex method to obtain row handles:

List<int> rowHandles = new List<int>();
for (int i = 0; i < gridControl1.VisibleRowCount; i++) {
    int rowHandle = gridControl1.GetRowHandleByVisibleIndex(i);
    rowHandles.Add(rowHandle);
}

The DataControlBase.VisibleRowCount property does not consider:

NOTE

When you display the New Item Row at the bottom of the GridControl, the DataControlBase.VisibleRowCount property considers it as a regular row.

To iterate through collapsed rows in a group, use the GridControl.GetChildRowCount method. This metod returns the current count of rows in the group. Create a counter similar to the previous one, and use the GridControl.GetChildRowHandle method to obtain handles of rows in the group. Use the GridControl.IsGroupRowHandle method to check that the row is a group row.

The following example shows how to obtain the handles of all data rows (including rows in collapsed groups) in the View, except rows that are filtered out:

private List<int> GetDataRowHandles() {
    List<int> rowHandles = new List<int>();
    for (int i = 0; i < grid.VisibleRowCount; i++) {
        int rowHandle = grid.GetRowHandleByVisibleIndex(i);
        if (grid.IsGroupRowHandle(rowHandle)) {
            if (!grid.IsGroupRowExpanded(rowHandle)) {
                rowHandles.AddRange(GetDataRowHandlesInGroup(rowHandle));
            }
        }
        else
            rowHandles.Add(rowHandle);
    }
    return rowHandles;
}
private List<int> GetDataRowHandlesInGroup(int groupRowHandle) {
    List<int> rowHandles = new List<int>();
    for (int i = 0; i < grid.GetChildRowCount(groupRowHandle); i++) {
        int rowHandle = grid.GetChildRowHandle(groupRowHandle, i);
        if (grid.IsGroupRowHandle(rowHandle)) {
            rowHandles.AddRange(GetDataRowHandlesInGroup(rowHandle));
        }
        else
            rowHandles.Add(rowHandle);
    }
    return rowHandles;
}

Iterate Through Cells

The GridControl defines cells by a row handle and a column object. To iterate through cells, extend the approach described in the Iterate Through Rows section and iterate through the GridControl.Columns or GridViewBase.VisibleColumns / TreeListView.VisibleColumns collection to access visible cells:

for (int i = 0; i < gridControl1.VisibleRowCount; i++) {
    int rowHandle = gridControl1.GetRowHandleByVisibleIndex(i);
    foreach (var column in gridControl1.Columns) {
        var cellValue = gridControl1.GetCellValue(rowHandle, column);
    }
}

To iterate through columns in all bands, use the GridControl.Columns or GridViewBase.VisibleColumns collection. To iterate through columns in the band, obtain it from the GridControl.Bands collection and use the GridControlBand.Columns collection property.

Iterate Through Nodes

The TreeListView represents nodes as rows. You can use the approaches listed above to iterate through visible nodes and their cells. Refer to the Iterate Through Nodes topic for more information.

Iterate Through Detail Rows in the Master-Detail GridControl

The GridControl provides the following types of detail descriptors:

NOTE

The detail GridControl is available only if the master row is expanded.

DataControlDetailDescriptor

To iterate through the detail rows, you need to access detail GridControl's instances. Use the approach described in the Iterate Through Rows section and use the GridControl.IsMasterRowExpanded method to check that a master row is expanded. Use the GridControl.GetDetail method to obtain the expanded detail GridControl and iterate through its rows:

Dictionary<int, List<int>> master_detail = new Dictionary<int, List<int>>();

for (int i = 0; i < masterGridControl.VisibleRowCount; i++) {
    int rowHandle = masterGridControl.GetRowHandleByVisibleIndex(i);
    List<int> details = new List<int>();
    master_detail[rowHandle] = details;
    if (masterGridControl.IsMasterRowExpanded(rowHandle)) {
        var detailGrid = masterGridControl.GetDetail(rowHandle) as GridControl;
        for (int j = 0; j < detailGrid.VisibleRowCount; j++) {
            int detailRowHandle = detailGrid.GetRowHandleByVisibleIndex(j);
            details.Add(detailRowHandle);
        }
    }
}

Use the DataViewBase.FocusedView property to access the focused detail GridControl and iterate through its rows:

var focusedDetail = masterView.FocusedView as TableView;
if (focusedDetail != null) {
    List<int> rowHandles = new List<int>();
    for (int i = 0; i < focusedDetail.Grid.VisibleRowCount; i++) {
        int rowHandle = focusedDetail.Grid.GetRowHandleByVisibleIndex(i);
        rowHandles.Add(rowHandle);
    }
}

ContentDetailDescriptor

In the ContentDetailDescriptor, you can obtain only visible in the GridControl's View content.

To iterate through the detail rows, you need to access detail GridControl's instances. Use the LayoutTreeHelper class to iterate through the master GridControl's visual tree and access the detail GridControl's rows:

var detailGrids = LayoutTreeHelper.GetVisualChildren(masterGridControl).OfType<GridControl>();

foreach(var detailGrid in detailGrids) {
    List<int> rowHandles = new List<int>();
    for (int i = 0; i < detailGrid.VisibleRowCount; i++) {
        int rowHandle = detailGrid.GetRowHandleByVisibleIndex(i);
        rowHandles.Add(rowHandle);
    }
}

TabViewDetailDescriptor

The TabViewDetailDescriptor displays different types of details (ContentDetailDescriptor and DataControlDetailDescriptor) in its tabs. The GridControl creates a visual element only for the selected tab. To iterate through detail rows in the tab, use an approach for the tab’s detail descriptor.

The GridControl.GetDetail method's override accepts the DataControlDetailDescriptor objects. Use this override to obtain the GridControl shown in the TabViewDetailDescriptor’s tabs:

<dxg:GridControl.DetailDescriptor>
    <dxg:TabViewDetailDescriptor>
        <dxg:DataControlDetailDescriptor x:Name="firstDetailDescriptor" ItemsSourceBinding="{Binding Data}">
            <dxg:GridControl AutoGenerateColumns="AddNew" x:Name="detailGridControl">
                <dxg:GridControl.View>
                    <dxg:TableView x:Name="detailView"/>
                </dxg:GridControl.View>
            </dxg:GridControl>
        </dxg:DataControlDetailDescriptor>
    </dxg:TabViewDetailDescriptor>
</dxg:GridControl.DetailDescriptor>
Dictionary<int, List<int>> master_detail = new Dictionary<int, List<int>>();

for (int i = 0; i < masterGridControl.VisibleRowCount; i++) {

    int rowHandle = masterGridControl.GetRowHandleByVisibleIndex(i);

    List<int> details = new List<int>();
    master_detail[rowHandle] = details;

    if (masterGridControl.IsMasterRowExpanded(rowHandle)) {

        var detailGrid = masterGridControl.GetDetail(rowHandle, firstDetailDescriptor) as GridControl;
        if (detailGrid == null)
            return;

        for (int j = 0; j < detailGrid.VisibleRowCount; j++) {
            int detailRowHandle = detailGrid.GetRowHandleByVisibleIndex(j);
            details.Add(detailRowHandle);
        }
    }
}