问题
I've got a StackPanel with a group of expanders in, how do I set it so that only expander is expanded at any one time?
Cheers
AW
回答1:
I didn't really want to do it like this as it required putting code (C#) in the class behind file for the window (I'm trying to avoid this completely by use of ViewModels etc).
Ideally I would have described this in XAML.
I hooked up every Expander 'Expanded' event I was interested in and did the following:
private void HandleExpanderExpanded(object sender, RoutedEventArgs e)
{
ExpandExculsively(sender as Expander);
}
private void ExpandExculsively(Expander expander)
{
foreach (var child in findPanel.Children)
{
if (child is Expander && child != expander)
((Expander)child).IsExpanded = false;
}
}
Cheers
AWC
回答2:
You can add a dependency property whose value is "the expander that is expanded," and then you can bind the "expanded" property to the expression "theExpandedProperty == this" using your favorite expression binding technique (type converter, etc).
回答3:
Here is a more elaborate way to do it in WPF without any code behind:
<UserControl.Resources>
<ResourceDictionary>
...
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="{x:Null}" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer VerticalAlignment="Top" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" VerticalContentAlignment="Top" BorderThickness="0,0,0,0" Grid.RowSpan="1" Grid.Row="0">
<ListBox x:Name="OrdersListBox" BorderThickness="0" ItemContainerStyle="{StaticResource ShellThemeListBoxStyle}"
IsSynchronizedWithCurrentItem="True"
prism:RegionManager.RegionName="{x:Static uiCommon:RegionNames.WorkSheetsRegion}" Background="#00000000">
<ListBox.ItemTemplate>
<DataTemplate DataType="typeData:WorkSheetsDetialsViewModel">
<local:WorkSheetsDetialsView/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
...
</Grid>
<UserControl
x:Class="Module.ExcelDocumentManager.WorkSheets.WorkSheetsDetialsView"
...>
<Expander>
<Expander.Header>
<TextBlock Text="{Binding HeaderInfo}" RenderTransformOrigin=".5,.5">
</TextBlock>
</Expander.Header>
...
</Expander>
</UserControl>
回答4:
User "Dabblernl" posted this as a comment, but it deserves being an answer because it is a perfect XAML-only solution, nicely customizable and without any hacks.
The idea is to place Expander controls in a ListBox, and bind the Expander.IsExpanded
property to the ListBoxItem.IsSelected
property.
Here is a ready-made example that you can just paste into a XAML file and try it out:
<ListBox>
<ListBox.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
</Style>
</ListBox.Resources>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter />
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<Expander Background="Gray" Width="243" Header="Expander1">
<StackPanel>
<RadioButton Content="Eat Me" GroupName="Two" />
<RadioButton Content="Eat Pork" GroupName="Two" />
<RadioButton Content="Eat at Joe's" GroupName="Two" />
</StackPanel>
</Expander>
<Expander Background="Gray" Width="243" Header="Expander2">
<StackPanel>
<RadioButton Content="Pork" GroupName="Two" />
<RadioButton Content="Beef" GroupName="Two" />
<RadioButton Content="Chicken" GroupName="Two" />
</StackPanel>
</Expander>
<Expander Background="Gray" Width="243" Header="Expander3">
<StackPanel>
<RadioButton Content="Grill" GroupName="Two" />
<RadioButton Content="Bake" GroupName="Two" />
<RadioButton Content="Fry" GroupName="Two" />
</StackPanel>
</Expander>
</ListBox>
This used to be here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3061227&SiteID=1 but forums.microsoft.com seems to have gone belly up.
It can still be found on this page: https://social.msdn.microsoft.com/Forums/en-US/a2988ae8-e7b8-4a62-a34f-b851aaf13886/windows-presentation-foundation-faq?forum=wpf under the title "3.4 How to keep only one Expander control opened in a group of Expander controls?"
来源:https://stackoverflow.com/questions/1922723/wpf-how-to-get-only-one-expander-expanded-at-any-one-time