Reputation: 676
I have two expanders, side by side. I want only one to be expanded at a time. So if one is expanded, and the user expands the other, I want the first one to collapse. The user can have both collapsed, and both collapsed is the starting state.
As can be seen in the code, I have included the "Header" property as a test, and it works as expected, but the IsExpanded property is not working.
<Expander x:Name="emailExpander">
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="IsExpanded" Value="False"/>
<Setter Property="Header" Value="Email"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpanded,ElementName=customerExpander}" Value="True">
<Setter Property="IsExpanded" Value="False"/>
<Setter Property="Header" Value="other expanded"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
</Expander>
Upvotes: 2
Views: 12331
Reputation: 77
This can be handled by binding to a view object with a little logic added.
In your WPF bind the IsExpanded property to the EmailExpanded and CustomerExpanded properties of the view.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Expander Grid.Column="0" Header="Email" IsExpanded="{Binding EmailExpanded}">
<TextBlock Text="Email Data"/>
</Expander>
<Expander Grid.Column="1" Header="Customer" IsExpanded="{Binding CustomerExpanded}">
<TextBlock Text="Customer Data"/>
</Expander>
</Grid>
Assign the view in your main Window.
public MainWindow()
{
InitializeComponent();
DataContext = new View();
}
Then make your view class something like the following.
class View : INotifyPropertyChanged
{
private bool _CustomerExpanded;
public bool CustomerExpanded
{
get
{
return _CustomerExpanded;
}
set
{
if (_CustomerExpanded != value)
{
// Add logic to close Email Expander
if (value)
{
EmailExpanded = false;
}
_CustomerExpanded = value;
OnPropertyChanged("CustomerExpanded");
}
}
}
private bool _EmailExpanded;
public bool EmailExpanded
{
get
{
return _EmailExpanded;
}
set
{
if (_EmailExpanded != value)
{
// Add logic to close Customer Expander
if (value)
{
CustomerExpanded = false;
}
_EmailExpanded = value;
OnPropertyChanged("EmailExpanded");
}
}
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
Notice the addition to the setters. Collapsing an expander will have no effect on the other expander, but expanding one will cause the other to collapse. No stack overflow :)
Upvotes: 1
Reputation: 5690
What you're better off doing is use an accordion control released in the WPF Toolkit V2. Very handy and no "Stack Overflow" exceptions. =)
Upvotes: 0
Reputation: 143
I found the answer in this post: WPF Expanders Triggers
Use BoolInverterConverter in the answer above and here is the code snippets for your case
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:BoolInverterConverter x:Key="bic"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Expander x:Name="emailExpander" IsExpanded="{Binding ElementName=customerExpander, Converter={StaticResource bic}, Path=IsExpanded}">
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="Header" Value="Email"/>
</Style>
</Expander.Style>
<StackPanel Margin="10,4,0,0">
<CheckBox Margin="4" Content="Email 1" />
<CheckBox Margin="4" Content="Email 2" />
<CheckBox Margin="4" Content="Email 3" />
</StackPanel>
</Expander>
<Expander x:Name="customerExpander" Grid.Column="1">
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="Header" Value="Customer"/>
</Style>
</Expander.Style>
<StackPanel Margin="10,4,0,0">
<CheckBox Margin="4" Content="Customer 1" />
<CheckBox Margin="4" Content="Customer 2" />
<CheckBox Margin="4" Content="Customer 3" />
</StackPanel>
</Expander>
</Grid>
Upvotes: 0