locked
How to create a set of expanders in which only one is opened at a (burringo) - 2/14/2007 5:19 AM PST RRS feed

  • Question

  • By: burringo

    Hello everybody,
    I want to create a set of expanders, in which when you click one of them 
    this opens and the one opened previously is closed, so it is only one opened 
    at a time. It´s there any way to do it without code?
    Thanks a lot.
    Tuesday, February 19, 2008 8:12 PM

Answers

  • By: Unni Ravindranathan (MS)


    Yes, it is possible to do this without code, but needs some minor tweaking
    by hand to setup the Binding.

    Without code, what you can do is restyle a ListBox such that each item in
    the ListBox is an expander. A ListBox is a control that maintains a contract
    of single selection. When you bind the IsExpanded of the Expander to the
    IsSelected of the ListBoxItem, you do get what you want - only one expander
    will be expanded at a time.

    Markup is attached.

    Thanks,
    -Unni

    <Window
    xmlns="
    http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="
    http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Accordion.Window1"
    x:Name="Window"
    Title="Window1"
    Width="640" Height="480">

    <Window.Resources>
    <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template" Value="{DynamicResource
    ListBoxItemControlTemplate1}"/>
    </Style>
    <ControlTemplate x:Key="ListBoxItemControlTemplate1" TargetType="{x:Type
    ListBoxItem}">
    <Expander Header="Expander" IsExpanded="{Binding IsSelected, Mode=TwoWay,
    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type
    ListBoxItem}}}">
    <Grid Height="100" Background="#FFC32C2C"/>
    </Expander>
    </ControlTemplate>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
    <ListBox Margin="194,74,188,107" ItemContainerStyle="{DynamicResource
    ListBoxItemStyle1}" IsSynchronizedWithCurrentItem="True">
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    </ListBox>
    </Grid>
    </Window>

    "burringo" <burringo@discussions.microsoft.com> wrote in message
    news:109F95E5-F83B-4D1B-8D41-EDEA367E6511@microsoft.com...
    > Hello everybody,
    > I want to create a set of expanders, in which when you click one of them
    > this opens and the one opened previously is closed, so it is only one
    > opened
    > at a time. It´s there any way to do it without code?
    > Thanks a lot.

    Tuesday, February 19, 2008 11:45 PM

All replies

  • By: Unni Ravindranathan (MS)


    Yes, it is possible to do this without code, but needs some minor tweaking
    by hand to setup the Binding.

    Without code, what you can do is restyle a ListBox such that each item in
    the ListBox is an expander. A ListBox is a control that maintains a contract
    of single selection. When you bind the IsExpanded of the Expander to the
    IsSelected of the ListBoxItem, you do get what you want - only one expander
    will be expanded at a time.

    Markup is attached.

    Thanks,
    -Unni

    <Window
    xmlns="
    http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="
    http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Accordion.Window1"
    x:Name="Window"
    Title="Window1"
    Width="640" Height="480">

    <Window.Resources>
    <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template" Value="{DynamicResource
    ListBoxItemControlTemplate1}"/>
    </Style>
    <ControlTemplate x:Key="ListBoxItemControlTemplate1" TargetType="{x:Type
    ListBoxItem}">
    <Expander Header="Expander" IsExpanded="{Binding IsSelected, Mode=TwoWay,
    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type
    ListBoxItem}}}">
    <Grid Height="100" Background="#FFC32C2C"/>
    </Expander>
    </ControlTemplate>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
    <ListBox Margin="194,74,188,107" ItemContainerStyle="{DynamicResource
    ListBoxItemStyle1}" IsSynchronizedWithCurrentItem="True">
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    <ListBoxItem Content="ListBoxItem"/>
    </ListBox>
    </Grid>
    </Window>

    "burringo" <burringo@discussions.microsoft.com> wrote in message
    news:109F95E5-F83B-4D1B-8D41-EDEA367E6511@microsoft.com...
    > Hello everybody,
    > I want to create a set of expanders, in which when you click one of them
    > this opens and the one opened previously is closed, so it is only one
    > opened
    > at a time. It´s there any way to do it without code?
    > Thanks a lot.

    Tuesday, February 19, 2008 11:45 PM
  • By: burringo


    Thanks a lot Unni!!
    
    
    "Unni Ravindranathan (MS)" wrote:
    
    > Yes, it is possible to do this without code, but needs some minor tweaking 
    > by hand to setup the Binding.
    > 
    > Without code, what you can do is restyle a ListBox such that each item in 
    > the ListBox is an expander. A ListBox is a control that maintains a contract 
    > of single selection. When you bind the IsExpanded of the Expander to the 
    > IsSelected of the ListBoxItem, you do get what you want - only one expander 
    > will be expanded at a time.
    > 
    > Markup is attached.
    > 
    > Thanks,
    > -Unni
    > 
    > <Window
    >  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    >  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >  x:Class="Accordion.Window1"
    >  x:Name="Window"
    >  Title="Window1"
    >  Width="640" Height="480">
    > 
    >  <Window.Resources>
    >   <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
    >    <Setter Property="Template" Value="{DynamicResource 
    > ListBoxItemControlTemplate1}"/>
    >   </Style>
    >   <ControlTemplate x:Key="ListBoxItemControlTemplate1" TargetType="{x:Type 
    > ListBoxItem}">
    >    <Expander Header="Expander" IsExpanded="{Binding IsSelected, Mode=TwoWay, 
    > RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type 
    > ListBoxItem}}}">
    >     <Grid Height="100" Background="#FFC32C2C"/>
    >    </Expander>
    >   </ControlTemplate>
    >  </Window.Resources>
    > 
    >  <Grid x:Name="LayoutRoot">
    >   <ListBox Margin="194,74,188,107" ItemContainerStyle="{DynamicResource 
    > ListBoxItemStyle1}" IsSynchronizedWithCurrentItem="True">
    >    <ListBoxItem Content="ListBoxItem"/>
    >    <ListBoxItem Content="ListBoxItem"/>
    >    <ListBoxItem Content="ListBoxItem"/>
    >    <ListBoxItem Content="ListBoxItem"/>
    >    <ListBoxItem Content="ListBoxItem"/>
    >   </ListBox>
    >  </Grid>
    > </Window>
    > 
    > "burringo" <burringo@discussions.microsoft.com> wrote in message 
    > news:109F95E5-F83B-4D1B-8D41-EDEA367E6511@microsoft.com...
    > > Hello everybody,
    > > I want to create a set of expanders, in which when you click one of them
    > > this opens and the one opened previously is closed, so it is only one 
    > > opened
    > > at a time. It´s there any way to do it without code?
    > > Thanks a lot. 
    > 
    > 
    > 
    Tuesday, February 19, 2008 11:45 PM
  • By: Ayana


    THis is exactly what I am trying to do, have expanders that only one is 
    expanded at a time, but I am dynamically loading my list elements and once I 
    use your code it doesn't seem like I can access the properties of the 
    expander like"Header" anymore. Can you advice??
    
    
    "burringo" wrote:
    
    > 
    > Thanks a lot Unni!!
    > 
    > 
    > "Unni Ravindranathan (MS)" wrote:
    > 
    > > Yes, it is possible to do this without code, but needs some minor tweaking 
    > > by hand to setup the Binding.
    > > 
    > > Without code, what you can do is restyle a ListBox such that each item in 
    > > the ListBox is an expander. A ListBox is a control that maintains a contract 
    > > of single selection. When you bind the IsExpanded of the Expander to the 
    > > IsSelected of the ListBoxItem, you do get what you want - only one expander 
    > > will be expanded at a time.
    > > 
    > > Markup is attached.
    > > 
    > > Thanks,
    > > -Unni
    > > 
    > > <Window
    > >  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    > >  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    > >  x:Class="Accordion.Window1"
    > >  x:Name="Window"
    > >  Title="Window1"
    > >  Width="640" Height="480">
    > > 
    > >  <Window.Resources>
    > >   <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
    > >    <Setter Property="Template" Value="{DynamicResource 
    > > ListBoxItemControlTemplate1}"/>
    > >   </Style>
    > >   <ControlTemplate x:Key="ListBoxItemControlTemplate1" TargetType="{x:Type 
    > > ListBoxItem}">
    > >    <Expander Header="Expander" IsExpanded="{Binding IsSelected, Mode=TwoWay, 
    > > RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type 
    > > ListBoxItem}}}">
    > >     <Grid Height="100" Background="#FFC32C2C"/>
    > >    </Expander>
    > >   </ControlTemplate>
    > >  </Window.Resources>
    > > 
    > >  <Grid x:Name="LayoutRoot">
    > >   <ListBox Margin="194,74,188,107" ItemContainerStyle="{DynamicResource 
    > > ListBoxItemStyle1}" IsSynchronizedWithCurrentItem="True">
    > >    <ListBoxItem Content="ListBoxItem"/>
    > >    <ListBoxItem Content="ListBoxItem"/>
    > >    <ListBoxItem Content="ListBoxItem"/>
    > >    <ListBoxItem Content="ListBoxItem"/>
    > >    <ListBoxItem Content="ListBoxItem"/>
    > >   </ListBox>
    > >  </Grid>
    > > </Window>
    > > 
    > > "burringo" <burringo@discussions.microsoft.com> wrote in message 
    > > news:109F95E5-F83B-4D1B-8D41-EDEA367E6511@microsoft.com...
    > > > Hello everybody,
    > > > I want to create a set of expanders, in which when you click one of them
    > > > this opens and the one opened previously is closed, so it is only one 
    > > > opened
    > > > at a time. It´s there any way to do it without code?
    > > > Thanks a lot. 
    > > 
    > > 
    > > 
    Tuesday, February 19, 2008 11:46 PM
  • I have a similar need and this idea seemed very promising and I can indeed get the behavior I'm looking for using the above code snippet.

    However, If I place buttons (or other simple controls) inside the 'listboxitem' that has been modified/styled to be an expander, I can't get the buttons to show up when the expander expands.

    I don't have control over the header of the expander either - all of them say "expander". It seems like there are some other binding tricks that would solve this - so if anyone has thoughts on how to do this, I'd appreciate it.

    Saturday, August 28, 2010 12:25 AM