Is it possible to mange group expanded state with AutoExpandGroups=false?
I have a 4-levels grid that simulates a treeview. original data is added in code with "radGridView1.Rows.Add( params[])"
The gridview's parameters :
radGridView1.MasterTemplate.ShowFilteringRow =
false
;
radGridView1.MasterTemplate.EnableGrouping =
true
;
radGridView1.MasterTemplate.AllowDragToGroup =
false
;
radGridView1.MasterTemplate.AutoExpandGroups =
false
;
radGridView1.ShowGroupPanel =
false
;
I want only the level 1-2-3 opened, the last one which contains all the leaves must be closed, until user ask to see all the entities.
I add more data with GridViewDataRowInfo rowInfo = new GridViewDataRowInfo(this.radGridView1.MasterView);
Setting cell values with => rowInfo.Cells[0].Value = newentity.Identifier;
and then for the grouping, those lines of code:
radGridView1.Rows.Add(rowInfo);
rowInfo.IsSelected = true;
rowInfo.IsExpanded = true;
My problem is that after adding the new entity, all the groups are collapsed. I tried many ideas but none to success.
If I set the radGridView1.MasterTemplate.AutoExpandGroups to true, then everything gets expanded and the grid takes way to much height.
Any ideas? thanks
12 Answers, 1 is accepted
I believe that you are using groups to create a hierarchy. And in this case, you are setting the IsExpanded property of a data row which is valid for hierarchy rows, not group rows. You need to iterate the ChildRows which contains the group row and expand only the levels you want. The following snippet shows how you can expand the first two levels:
foreach
(var item
in
radGridView1.ChildRows)
{
if
(item
is
GridViewGroupRowInfo)
{
var groupRow = item
as
GridViewGroupRowInfo;
groupRow.IsExpanded =
true
;
if
(groupRow.HasChildRows())
{
foreach
(var childRow
in
groupRow.ChildRows)
{
if
(childRow
is
GridViewGroupRowInfo)
{
childRow.IsExpanded =
true
;
}
}
}
}
}
I hope this will be useful. Let me know if you have additional questions.
Regards,
Dimitar
Progress Telerik

I was using radGridView1.Groups and not ChildRows.
However the result is the same : when adding a row (button click outside of the gridview), everything is collapsing.
I have made a small recursive method that gets called at the end of the add method. It works, but all the other GroupRows that were expanded and not in relation to the newly added one gets collapse (irritating)
Here's the method I made:
private
static
void
RecursivelyExpandParent(Telerik.WinControls.Data.Group<GridViewRowInfo> gridGroupInfo)
{
((Telerik.WinControls.UI.DataGroup)gridGroupInfo).Expand();
if
(gridGroupInfo.Parent !=
null
)
{
RecursivelyExpandParent(gridGroupInfo.Parent);
}
}
and the call to it:
radGridViewByComponents.BeginUpdate();
radGridViewByComponents.Rows.Add(rowInfo);
rowInfo.IsSelected =
true
;
rowInfo.IsExpanded =
true
;
radGridViewByComponents.EndUpdate();
radGridViewByComponents.CurrentRow = rowInfo;
if
(rowInfo.Group.Parent !=
null
&& rowInfo.Group.Parent
is
Telerik.WinControls.Data.Group<GridViewRowInfo>)
{
RecursivelyExpandParent((Telerik.WinControls.Data.Group<GridViewRowInfo>)rowInfo.Group.Parent);
}
I have attached a small example that shows how you can expand to the new row and expand all groups to a particular level.
Let me know if I can assist you further.
Dimitar
Progress Telerik

Hi Dimitar and thank you for your code.
My problem is that we don't know in what group the added element will be.
I need to go the other way around : Expand all the groups until we reach the added element while keeping the other groups (collapsed/expanded) state.
In your sample code, I tried changing :
ExpandGroup(radGridView1.Groups[0], 0);
by
row.Group.Expand(
true
);
but nothing happens, I would assume that the closest group of the added element would expand and all the above?
Also, in your sample, if you start and only radButton1_Click, the group where the element is added doesn't gets expanded...
It appears that the groups are built as one expands the grid. So at the point where all is collapsed and the row is added, its group is empty. In order this to work you need to expand and then collapse all groups. Here is an example that can be used for specific row:
private
void
radButton1_Click(
object
sender, EventArgs e)
{
radGridView1.BeginUpdate();
var row = radGridView1.Rows.AddNew()
as
GridViewDataRowInfo;
row.Cells[0].Value = 0;
row.Cells[1].Value =
"Row 0"
;
row.Cells[2].Value = 0;
row.Cells[3].Value = 444;
row.IsSelected =
true
;
row.IsExpanded =
true
;
radGridView1.EndUpdate();
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, -1,
true
);
}
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, -1,
false
);
}
ExpandBottomToTop(row.Group);
}
void
ExpandBottomToTop(DataGroup group)
{
group.Expand();
if
(group.Parent !=
null
)
{
ExpandBottomToTop(((DataGroup)group.Parent));
}
}
void
ExpandGroup(DataGroup group,
int
level,
bool
expand)
{
if
(level != group.Level)
{
if
(expand)
{
group.Expand();
}
else
{
group.Collapse();
}
}
if
(group.Groups.Count > 0)
{
foreach
(DataGroup item
in
group.Groups)
{
ExpandGroup(item, level, expand);
}
}
}
private
void
radButton2_Click(
object
sender, EventArgs e)
{
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, 2,
true
);
}
}
Please let me know if there is something else I can help you with.
Regards,
Dimitar
Progress Telerik

We are almost there :D
If I already opened the group "ID:3 Name: Row 3", when invoking "radButton1_Click", the opened group "ID:3 Name: Row 3" doesn't stay expanded.
As mentionned in previous message "I need to go the other way around : Expand all the groups until we reach the added element while keeping the other groups (collapsed/expanded) state. "
With your solution, I am loosing the previous expanded/collapsed state of the groups.
What do you think of keeping the expanded/collapsed state in a Dictionary<DataGroup, bool> where the bool would be "IsExpanded" state?
- Keep group/state in dictionary
- collapse all
- expand all
- ExpandBottomToTop(row.Group);
- ExpandBottomToTop(row.Group) from dictionary

private
void
radButton1_Click(
object
sender, EventArgs e)
{
var previousStates =
new
List<DataGroup>();
AddExpandedGroupsToList(radGridView1.Groups, previousStates);
radGridView1.BeginUpdate();
var row = radGridView1.Rows.AddNew()
as
GridViewDataRowInfo;
row.Cells[0].Value = 0;
row.Cells[1].Value =
"Row 0"
;
row.Cells[2].Value = 0;
row.Cells[3].Value = 444;
row.IsSelected =
true
;
row.IsExpanded =
true
;
radGridView1.EndUpdate();
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, -1,
true
);
}
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, -1,
false
);
}
ExpandBottomToTop(row.Group);
foreach
(var group
in
previousStates)
{
ExpandBottomToTop(group);
}
}
void
AddExpandedGroupsToList(DataGroupCollection group, List<DataGroup> openedGroups)
{
foreach
(DataGroup childGroup
in
group)
{
if
(childGroup.IsExpanded)
{
openedGroups.Add(childGroup);
}
AddExpandedGroupsToList(childGroup.Groups, openedGroups);
}
}
void
ExpandBottomToTop(DataGroup group)
{
group.Expand();
if
(group.Parent !=
null
)
{
ExpandBottomToTop(((DataGroup)group.Parent));
}
}
void
ExpandGroup(DataGroup group,
int
level,
bool
expand)
{
if
(level != group.Level)
{
if
(expand)
{
group.Expand();
}
else
{
group.Collapse();
}
}
if
(group.Groups.Count > 0)
{
foreach
(DataGroup item
in
group.Groups)
{
ExpandGroup(item, level, expand);
}
}
}
You can just expand the groups that were previously collapsed (there is no need to call the ExpandBottomToTop):
foreach
(var group
in
previousStates)
{
group.Expand();
}
Do not hesitate to contact us if you have other questions.
Dimitar
Progress Telerik

Here's the final working code that fits my needs, I think that it should be like that without managing the expended/collapsed states manually!
public
partial
class
RadForm1 : Telerik.WinControls.UI.RadForm
{
public
RadForm1()
{
InitializeComponent();
SetupGridWithHierarchy(
this
, radGridView1);
radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
}
private
void
SetupGridWithHierarchy(Form form, RadGridView gridView)
{
Random r =
new
Random();
DataTable table =
new
DataTable(
"table"
);
table.Columns.Add(
"ID"
,
typeof
(
int
));
table.Columns.Add(
"Name"
,
typeof
(
string
));
table.Columns.Add(
"Value"
,
typeof
(
int
));
table.Columns.Add(
"Option3"
,
typeof
(
int
));
table.Columns.Add(
"DateTime"
,
typeof
(DateTime));
for
(
int
i = 0; i < 5; i++)
{
table.Rows.Add(i,
"Row "
+ i, i, r.Next(), DateTime.Now);
if
(i == 0)
{
table.Rows.Add(i,
"Row "
+ i, i + r.Next(), r.Next(), DateTime.Now);
}
}
DataSet
set
=
new
DataSet();
set
.Tables.Add(table);
gridView.DataSource =
set
;
gridView.DataMember =
"table"
;
radGridView1.GroupDescriptors.Add(
"ID"
, ListSortDirection.Ascending);
radGridView1.GroupDescriptors.Add(
"Name"
, ListSortDirection.Ascending);
radGridView1.GroupDescriptors.Add(
"Value"
, ListSortDirection.Ascending);
}
private
GridViewDataRowInfo _lastAddedRow;
private
void
radButton1_Click(
object
sender, EventArgs e)
{
var previousStates =
new
List<DataGroup>();
AddExpandedGroupsToList(radGridView1.Groups, previousStates);
radGridView1.BeginUpdate();
var row = radGridView1.Rows.AddNew()
as
GridViewDataRowInfo;
row.Cells[0].Value = 0;
row.Cells[1].Value =
"Row 0"
;
row.Cells[2].Value = 0;
row.Cells[3].Value = 444;
row.IsSelected =
true
;
row.IsExpanded =
true
;
_lastAddedRow = row;
radGridView1.EndUpdate();
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, -1,
true
);
}
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, -1,
false
);
}
ExpandBottomToTop(row.Group);
foreach
(var group
in
previousStates)
{
//ExpandBottomToTop(group);
group.Expand();
}
}
void
AddExpandedGroupsToList(DataGroupCollection group, List<DataGroup> openedGroups)
{
foreach
(DataGroup childGroup
in
group)
{
if
(childGroup.IsExpanded)
{
openedGroups.Add(childGroup);
}
AddExpandedGroupsToList(childGroup.Groups, openedGroups);
}
}
void
ExpandBottomToTop(DataGroup group)
{
group.Expand();
if
(group.Parent !=
null
)
{
ExpandBottomToTop(((DataGroup)group.Parent));
}
}
void
ExpandGroup(DataGroup group,
int
level,
bool
expand)
{
if
(level != group.Level)
{
if
(expand)
{
group.Expand();
}
else
{
group.Collapse();
}
}
if
(group.Groups.Count > 0)
{
foreach
(DataGroup item
in
group.Groups)
{
ExpandGroup(item, level, expand);
}
}
}
private
void
radButton2_Click(
object
sender, EventArgs e)
{
foreach
(DataGroup item
in
radGridView1.Groups)
{
ExpandGroup(item, 2,
true
);
}
}
private
void
radButton3_Click(
object
sender, EventArgs e)
{
if
(_lastAddedRow !=
null
)
{
_lastAddedRow.Delete();
_lastAddedRow =
null
;
}
}
}
Thank you for sharing your final solution. In case you will need further assistance on this please let us know.
Regards,
Hristo
Progress Telerik

Two new problems with the same hierarchy grid:
- everything gets collapsed when clicking on an header to set an order by (no code was done here)
- when deleting a row (leaf), everything gets collapsed whatever code I put after the row.Delete() or Rows.Remove(leafRowInfo)
I cannot reproduce any of those 2 problems :(
I can't think that your grid is such difficult to use, so it's my initialisation or loading of the grid the problem... is this the case?
I have tested this as well and no rows are collapsed on my side when deleting or sorting the grid. If you manage to reproduce this just let me know and I will further investigate it.
This is not caused by the loading (unless you are not rebuilding the grid at some point or updating it from another thread).
Regards,
Dimitar
Progress Telerik