Charlotte Skardon
Charlotte Skardon

Reputation: 6280

Making a collection of WPF Expanders 'expand' exclusively, i.e. only one expanded at a time

I have a ListBox containing a group of 'Expander' items, and what I would like to do is make the IsExpanded property for each of them exclusive. For example, if I have 10 Expanders in the ListBox, I'd like only one to be open at a time.

Here is what I have so far:

<Window>
    <Window.Resources>
        <DataTemplate x:Key="NormalTemplate">
            <Expander Margin="0" IsExpanded="True" Header="{Binding Model.Name}" Background="Green">
                <Grid>
                    <StackPanel HorizontalAlignment="Stretch">
                        <TextBlock Text="{Binding Model.Description}" TextWrapping="Wrap" HorizontalAlignment="Stretch" Margin="0"/>
                    </StackPanel>
                </Grid>
            </Expander>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <ListBox ItemsSource="{Binding Groups}" 
                 ItemTemplate="{DynamicResource NormalTemplate}"
                 />
    </Grid>
</Window>

Is there any way to do this? I'm not tied to a ListBox or indeed Expanders, heck - I'm not tied to any of it if it needs to change.

Upvotes: 1

Views: 5115

Answers (3)

56ka
56ka

Reputation: 1575

Since Kent Boogaart's answer did not work for me, I did like this:

Note: I am using XAML Material Design and maybe it is the reason it does not work

<Style TargetType="{x:Type Expander}">
    <EventSetter Event="Loaded" Handler="Expander_Loaded" />
    <EventSetter Event="Expanded" Handler="Expander_Expanded" />
</Style>
private readonly List<Expander> allExpanders = new();

private void Expander_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    allExpanders.Add(sender as Expander);
}

private void Expander_Expanded(object sender, System.Windows.RoutedEventArgs e)
{
    foreach (Expander exp in allExpanders.Where(exp => exp != sender))
    {
        exp.IsExpanded = false;
    }
}

Upvotes: 1

Kent Boogaart
Kent Boogaart

Reputation: 178780

What determines whether an Expander is expanded? If it's selection, you could bind the IsExpanded property to the IsSelected property of the ListBoxItem:

<Expander IsExpanded="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" ...>

Upvotes: 7

Crippeoblade
Crippeoblade

Reputation: 4065

This Accordian control maybe what you are looking for

Upvotes: 0

Related Questions