user1256722
user1256722

Reputation: 133

How to collapse all Group Expander in ListView?

I have a ListView with a GroupStyle on it. And in the style i have an Expander. I want to use a ContextMenu in the ListView to collapse and expand all groups with one click and i want to expand every single group by clicking on the expander. How can i get the Groups and then expand this programmatically?

<Style x:Key="PropertyGroupStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Expander Header="{Binding Name}" IsExpanded="True">                               
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>                    
            </Setter>                
        </Style>



<ListView Name="PropertyChangeList"
                                IsSynchronizedWithCurrentItem="True" Height="Auto"                     

                                ItemsSource="{Binding}"                 
                             >
                                <ListView.GroupStyle>
                                    <GroupStyle ContainerStyle="{StaticResource PropertyGroupStyle}"/>
                                </ListView.GroupStyle>
                                <ListView.ContextMenu>
                                    <ContextMenu>
                                        <MenuItem Name="menuItemPropertyExpanderCollapse"
                                            Header="{Binding Path=labelCollapse, FallbackValue='Collapse'}"
                                            Click="menuItemPropertyExpanderCollapse_Click" 
                                                  />
                                        <MenuItem Name="menuItemPropertyExpanderExpand"
                                            Header="{Binding Path=labelExpand, FallbackValue='Expand'}"

                                  />
                                    </ContextMenu>
                                </ListView.ContextMenu>
                                <ListView.View>
                                    <GridView AllowsColumnReorder="False" >
                                        <GridViewColumn Header="Date Occured"
                                                Width="20"
                                                DisplayMemberBinding="{Binding DateOccured}" />

                                        <GridViewColumn Header="PropertyName"
                                                Width="Auto"
                                                DisplayMemberBinding="{Binding PropertyName}"/>                                          

                                    </GridView>
                                </ListView.View>
                            </ListView>

ICollectionView PropertyListview = CollectionViewSource.GetDefaultView(hPropList);
        PropertyListview.GroupDescriptions.Add(new PropertyGroupDescription("PropertyName"));
        PropertyListview.SortDescriptions.Add(new SortDescription("PropertyName", ListSortDirection.Ascending));
        PropertyListview.SortDescriptions.Add(new SortDescription("DateOccurred", ListSortDirection.Ascending));

        PropertyChangeList.ItemsSource = PropertyListview;

Has anybody an sample code to do the collapse and expand all groups with an ContextMenu? i dont find anything out there.

Upvotes: 3

Views: 2126

Answers (1)

mm8
mm8

Reputation: 169200

You could bind the IsExpanded property to the Tag property of the ListView:

<Style x:Key="PropertyGroupStyle" TargetType="{x:Type GroupItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Expander Header="{Binding Name}"
                          IsExpanded="{Binding Tag, RelativeSource={RelativeSource AncestorType=ListView}, TargetNullValue=true, FallbackValue=true}">
                    <ItemsPresenter />
                </Expander>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

...and set the Tag property in the event handlers:

private void menuItemPropertyExpanderCollapse_Click(object sender, RoutedEventArgs e)
{
    PropertyChangeList.Tag = false;
}

you answered the question right, but i forget to write more details. Yes now i can expand and collapse all groups but i cant expand anymore a single group. it is an all or nothing thing. My question missed some important details :-( I updated my question text.

Change the AncestorType of the binding to GroupItem and set the Tag property of each GroupItem by iterating through them in the visual tree:

private void menuItemPropertyExpanderCollapse_Click(object sender, RoutedEventArgs e)
{
    foreach (GroupItem gi in FindVisualChildren<GroupItem>(PropertyChangeList))
        gi.Tag = false;
}

private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                yield return (T)child;
            }

            foreach (T childOfChild in FindVisualChildren<T>(child))
            {
                yield return childOfChild;
            }
        }
    }
}

XAML:

<Expander Header="{Binding Name}"
          IsExpanded="{Binding Tag, RelativeSource={RelativeSource AncestorType=GroupItem}, TargetNullValue=true, FallbackValue=true}">
    <ItemsPresenter />
</Expander>

Upvotes: 2

Related Questions