Known affected versions: 2015.2.728, 2016.1.217, both net40 and net45
There appears to be a bug in the CommonHeaderPresenter VirtualizingStrategy when there are more than 2 levels of nested column groups.
The following code shows the bug in effect. When EnableColumnGroupsVirtualization is True, the Middle 2 group headers are not displayed. Only the outermost group (not referenced by any column) and the innermost group (referenced by the single column) are visible. (Also see attached image for demonstration)
01.<Window02. xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"03. x:Class="chartTest.MainWindow"05. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"06. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"07. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"08. mc:Ignorable="d"09. Title="MainWindow"10. Height="350"11. Width="525">12. <telerik:RadGridView13. AutoGenerateColumns = "False"14. CanUserDeleteRows="False"15. CanUserSortColumns="False"16. CanUserResizeColumns="False"17. CanUserReorderColumns="False"18. CanUserResizeRows="False"19. CanUserFreezeColumns="False"20. CanUserInsertRows="False"21. CanUserSelect="True"22. CanUserSortGroups="False"23. ShowGroupPanel="False"24. NewRowPosition="None"25. ShowColumnFooters="False"26. RowIndicatorVisibility="Collapsed"27. EnableColumnGroupsVirtualization="True">28. <!-- Switch EnableColumnGroupsVirtualization between True and False to see the bug -->29. <telerik:RadGridView.ColumnGroups>30. <telerik:GridViewColumnGroup31. Name = "Outermost Group"32. Header="Outermost Group">33. <!-- These 2 middle groups do not show up when virtualization is used -->34. <telerik:GridViewColumnGroup35. Name = "Middle 1 Group"36. Header="Middle 1 Group">37. <telerik:GridViewColumnGroup38. Name = "Middle 2 Group"39. Header="Middle 2 Group">40. <telerik:GridViewColumnGroup41. Name = "Innermost Group"42. Header="Innermost Group">43. </telerik:GridViewColumnGroup>44. </telerik:GridViewColumnGroup>45. </telerik:GridViewColumnGroup>46. </telerik:GridViewColumnGroup>47. </telerik:RadGridView.ColumnGroups>48. <telerik:RadGridView.Columns>49. <telerik:GridViewColumn50. Width = "150"51. ColumnGroupName="Innermost Group" />52. </telerik:RadGridView.Columns>53. </telerik:RadGridView>54.</Window>
I have tracked it down to the InitializeVisuals() method on VirtualizingStrategy (Controls\GridView\GridView\GridView\ColumnGroups\CommonHeaderPresenter.VirtualizingStrategy.cs).
At around line 69 it traverses the column groups for the current column group, and sets each child control's ParentGroup property to the TOP LEVEL (outermost) column group. Thus all child groups at all levels are flattened out as they are made direct children of the first level of column groups:
01.foreach (var columnGroup in ParentPresenter.ColumnGroups)02.{03. ...04. 05. this.TraverseColumnGroups(columnGroup,06. new Action<GridViewColumnGroup>((c) =>07. {08. if (!this.GroupNames.Contains(c.Name))09. {10. this.GroupNames.Add(c.Name);11. c.ParentGroup = columnGroup;12. c.DataControl = columnGroup.DataControl;13. }14. }));15.}
I have managed to fix this by creating an overload for TraverseColumnGroups which takes an action which can act on both the Parent AND Child groups. Using this new action in the traversal from above results in the inner column group headers actually showing up in the test code from above.
The changes I had to make can be seen below (unrelated code excluded):
01.internal void TraverseColumnGroups(GridViewColumnGroup group, Action<GridViewColumnGroup, GridViewColumnGroup> action)02.{03. foreach (var childGroup in group.ChildGroups)04. {05. action.Invoke(group, childGroup);06. this.TraverseColumnGroups(childGroup, action);07. }08.}09. 10....11. 12.foreach (var columnGroup in ParentPresenter.ColumnGroups)13.{14. ...15. 16. this.TraverseColumnGroups(columnGroup,17. new Action<GridViewColumnGroup, GridViewColumnGroup>((parentGroup, childGroup) =>18. {19. if (!this.GroupNames.Contains(childGroup.Name))20. {21. this.GroupNames.Add(childGroup.Name);22. childGroup.ParentGroup = parentGroup;23. childGroup.DataControl = parentGroup.DataControl;24. }25. }));26.}
I'm assuming this bug is not "works as designed", because why would only the OUTERMOST\First level column group header show up (even if it isn't directly referenced by any columns).
Thanks,
Sam