With C1TrueDbGrid in GroupBy mode, many users wish to select all child rows within a certain Group, when they click on that GroupHeader. And, a few have reported having a hard time implementing this. With the grid in GroupBy mode, any row being clicked on, may/may not have the same index in the underlying DataTable. Hence, the Row selection gets a bit tricky.

In this blog, we talk about how to achieve this.

To begin with, we need to listen to the MouseUp event, and using the zero-based index of the display row, containing the Y specified coordinate, get the ViewRow of the Split.

var vr = this.c1TrueDBGrid1.Splits[0].Rows[this.c1TrueDBGrid1.RowContaining(e.Y)];


The selection needs to be made only if the user clicked on an expanded GroupRow.  We need to figure out if the user clicked on such a Row; and if so, we type-cast the ViewRow ( created in previous step) to a GroupRow. This is to get the StartIndex and EndIndex of the ChildRows.


var vr = this.c1TrueDBGrid1.Splits[0].Rows[displayrow_index];
C1.Win.C1TrueDBGrid.GroupRow gr = vr as C1.Win.C1TrueDBGrid.GroupRow;

//Verify GroupRow state and child nodes' visibility
if (vr.RowType == C1.Win.C1TrueDBGrid.RowTypeEnum.ExpandedGroupRow && this.c1TrueDBGrid1.Splits[0].Rows[gr.StartIndex].Visible)
{
for (int j = 1; j <= (gr.EndIndex - gr.StartIndex) + 1; j++)
{
c1TrueDBGrid1.SelectedRows.Add(displayrow_index + j);
}
}


Now, here’s the trick. Using a for-loop, we compute the number of ChildRows of the current Group (gr.EndIndex - gr.StartIndex). And, add all display-row indices beginning from the row next to the GroupRow i.e first ChildRow, to the Last ChildRow.

Also, we need to take care of the possiblity of Column Headers being clicked on; and if this happens, we need to exclude them from selection.

Finally, this is the code that we need to use in MouseUp event:


void c1TrueDBGrid1_MouseUp(object sender, MouseEventArgs e)
{
//Clear previous selections.
this.c1TrueDBGrid1.SelectedRows.Clear();

//Get the index of the display row.
int displayrow_index = this.c1TrueDBGrid1.RowContaining(e.Y);

//Exclude row headers
if (displayrow_index != -1)
{
var vr = this.c1TrueDBGrid1.Splits[0].Rows[displayrow_index];

C1.Win.C1TrueDBGrid.GroupRow gr = vr as C1.Win.C1TrueDBGrid.GroupRow;
//Verify GroupRow state and child nodes' visibility
if (vr.RowType == C1.Win.C1TrueDBGrid.RowTypeEnum.ExpandedGroupRow && this.c1TrueDBGrid1.Splits[0].Rows[gr.StartIndex].Visible)
{
for (int j = 1; j <= (gr.EndIndex - gr.StartIndex) + 1; j++)
{
c1TrueDBGrid1.SelectedRows.Add(displayrow_index + j);
}
}
else
{
//don't select invisible child nodes
this.c1TrueDBGrid1.SelectedRows.Clear();
}
c1TrueDBGrid1.Refresh();
}
}


Eventually, this is how the grid looks like, with all child rows in a particular Group selected.



Download Sample