Search code examples
wpfwindows-phone-7.1expander

Collapse opened expanders in `Datatemplate`, when we open new one


My view works like this. I have an Observable Collection, which contains objects put on the list. By clicking on any item, I can open an expander related to that item. Here is the question: How can I collapse (close) the previously opened expander when I open another one? I don't want to have a situation where multiple expanders are opened at the same time.

My WPF code looks like this:

 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <controls:Pivot>
            <controls:PivotItem>
                <ListBox x:Name="PizzaList" SelectionChanged="PizzaList_SelectionChanged" IsSynchronizedWithCurrentItem="false" >
                    <ListBox.ItemTemplate>
                        <DataTemplate x:Name="template">

                            <toolkit:ExpanderView Header="{Binding Name}" x:Name="expander" Style="{StaticResource ExpanderViewStyle}">
                                <toolkit:ExpanderView.Items>
                                   <!--first stack panel would contain all elements which would be showed 
                                    after clicking on listbox item-->
                                    <StackPanel Margin="20,0,0,0" Orientation="Vertical">
                  <!-- here is content of expander-->                    
                                    </StackPanel>
                                </toolkit:ExpanderView.Items>
                                <toolkit:ExpanderView.Expander>
                                    <TextBlock Text="{Binding Name_of_ingredients}" Width="500"></TextBlock>
                                </toolkit:ExpanderView.Expander>
                            </toolkit:ExpanderView>


                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </controls:PivotItem>
        </controls:Pivot>
    </Grid>

I could have a static number of expanders if I were working with a fixed dataset, but when the expander is in a data template, the number of items could change. I'm not sure how to solve this.


Solution

  • I think this can help:

    private void PizzaListSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        foreach (var item in PizzaList.Items)
        {
            var listBoxItem =
                PizzaList.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;
            var itemExpander = (Expander) GetExpander(listBoxItem);
            if (itemExpander != null)
                itemExpander.IsExpanded = false;
        }
    }
    

    and search of Expander

    private static DependencyObject GetExpander(DependencyObject container)
    {
        if (container is Expander) return container;
    
        for (var i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++)
        {
            var child = VisualTreeHelper.GetChild(container, i);
    
            var result = GetExpander(child);
            if (result != null)
            {
                return result;
            }
        }
    
        return null;
    }
    

    More ways to find controls in this question How can I find WPF controls by name or type?