Bug in VirtualizingStrategy with multiple nested column groups

2 posts, 0 answers
  1. Sam
    Sam avatar
    2 posts
    Member since:
    Feb 2016

    Posted 29 Feb Link to this post

    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.<Window
    03.    x:Class="chartTest.MainWindow"
    08.    mc:Ignorable="d"
    09.    Title="MainWindow"
    10.    Height="350"
    11.    Width="525">
    12.    <telerik:RadGridView
    13.        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:GridViewColumnGroup
    31.                Name = "Outermost Group"
    32.                Header="Outermost Group">
    33.                <!-- These 2 middle groups do not show up when virtualization is used -->
    34.                <telerik:GridViewColumnGroup
    35.                    Name = "Middle 1 Group"
    36.                    Header="Middle 1 Group">
    37.                    <telerik:GridViewColumnGroup
    38.                        Name = "Middle 2 Group"
    39.                        Header="Middle 2 Group">
    40.                        <telerik:GridViewColumnGroup
    41.                            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:GridViewColumn
    50.                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

  2. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1128 posts

    Posted 02 Mar Link to this post

    Hi,

    We managed to reproduce the issue with the project that a colleague of yours sent through the ticketing system. The issue us logged in our tracking system and we will do our best to reslove it as soon as possible. Here is the public item, which you can follow to track our progress with it.

    Regards,
    Ivan Ivanov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top