2015-12-24 104 views
1

我有一个要求,包括将在WPF中的扩展器上触发逻辑的按钮。我在下面列出了一张图片。WPF扩展器与多个按钮

enter image description here

我不确定如何在WPF如果有可能做到这一点,或。按钮需要连接到后端功能来创建对象。每个扩展器都应该在扩展器头部的右侧有这些按钮,无论它们是否扩展。点击后,该按钮应在代码背后调用_Click方法。

这可以用扩展器来完成,我该怎么做到这一点?

+0

仍不清楚乌尔端的要求。 Plz澄清。 – AnjumSKhan

+0

您的图片描绘了两个扩展器,还是一个扩展器内的列表中的两个项目?还是其他什么东西?你是说你想在扩展器的头部添加两个按钮,这样它们就可以在扩展切换按钮的右边看到,不管它是否被扩展? –

+0

是的,每个都是扩展器,无论扩展器的头部是否扩展,都应该在扩展器头部的右边有这些按钮。 – greyfox

回答

2

为了让您的Button显示在最右端,您必须使用DockPanel作为您的Expander.HeaderTemplate。但Expander使用ToggleButton在显示扩展圆圈的顶部。此ToggleButton将其HorizontalAlignment设置为左侧。所以,我们需要ExpanderDownHeaderStyle键更改Style此设置为

<ContentPresenter Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" ... /> 

复制粘贴下面的一块XAML的,因为它是。

<Window.Resources> 
     <SolidColorBrush x:Key="Expander.MouseOver.Circle.Stroke" Color="#FF3C7FB1"/> 
     <SolidColorBrush x:Key="Expander.MouseOver.Circle.Fill" Color="Transparent"/> 
     <SolidColorBrush x:Key="Expander.MouseOver.Arrow.Stroke" Color="#222"/> 
     <SolidColorBrush x:Key="Expander.Pressed.Circle.Stroke" Color="#FF526C7B"/> 
     <SolidColorBrush x:Key="Expander.Pressed.Circle.Fill" Color="Transparent"/> 
     <SolidColorBrush x:Key="Expander.Pressed.Arrow.Stroke" Color="#FF003366"/> 
     <SolidColorBrush x:Key="Expander.Disabled.Circle.Stroke" Color="DarkGray"/> 
     <SolidColorBrush x:Key="Expander.Disabled.Circle.Fill" Color="Transparent"/> 
     <SolidColorBrush x:Key="Expander.Disabled.Arrow.Stroke" Color="#666"/> 
     <SolidColorBrush x:Key="Expander.Static.Circle.Fill" Color="Transparent"/> 
     <SolidColorBrush x:Key="Expander.Static.Circle.Stroke" Color="DarkGray"/> 
     <SolidColorBrush x:Key="Expander.Static.Arrow.Stroke" Color="#666"/> 
     <Style x:Key="ExpanderRightHeaderStyle" TargetType="{x:Type ToggleButton}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type ToggleButton}"> 
         <Border Padding="{TemplateBinding Padding}"> 
          <Grid Background="Transparent" SnapsToDevicePixels="False"> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="19"/> 
            <RowDefinition Height="*"/> 
           </Grid.RowDefinitions> 
           <Grid> 
            <Grid.LayoutTransform> 
             <TransformGroup> 
              <TransformGroup.Children> 
               <TransformCollection> 
                <RotateTransform Angle="-90"/> 
               </TransformCollection> 
              </TransformGroup.Children> 
             </TransformGroup> 
            </Grid.LayoutTransform> 
            <Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/> 
            <Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/> 
           </Grid> 
           <ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/> 
          </Grid> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsChecked" Value="true"> 
           <Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/> 
          </Trigger> 
          <Trigger Property="IsMouseOver" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsPressed" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/> 
           <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsEnabled" Value="false"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <Style x:Key="ExpanderUpHeaderStyle" TargetType="{x:Type ToggleButton}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type ToggleButton}"> 
         <Border Padding="{TemplateBinding Padding}"> 
          <Grid Background="Transparent" SnapsToDevicePixels="False"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="19"/> 
            <ColumnDefinition Width="*"/> 
           </Grid.ColumnDefinitions> 
           <Grid> 
            <Grid.LayoutTransform> 
             <TransformGroup> 
              <TransformGroup.Children> 
               <TransformCollection> 
                <RotateTransform Angle="180"/> 
               </TransformCollection> 
              </TransformGroup.Children> 
             </TransformGroup> 
            </Grid.LayoutTransform> 
            <Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/> 
            <Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/> 
           </Grid> 
           <ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/> 
          </Grid> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsChecked" Value="true"> 
           <Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/> 
          </Trigger> 
          <Trigger Property="IsMouseOver" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsPressed" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/> 
           <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsEnabled" Value="false"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <Style x:Key="ExpanderLeftHeaderStyle" TargetType="{x:Type ToggleButton}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type ToggleButton}"> 
         <Border Padding="{TemplateBinding Padding}"> 
          <Grid Background="Transparent" SnapsToDevicePixels="False"> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="19"/> 
            <RowDefinition Height="*"/> 
           </Grid.RowDefinitions> 
           <Grid> 
            <Grid.LayoutTransform> 
             <TransformGroup> 
              <TransformGroup.Children> 
               <TransformCollection> 
                <RotateTransform Angle="90"/> 
               </TransformCollection> 
              </TransformGroup.Children> 
             </TransformGroup> 
            </Grid.LayoutTransform> 
            <Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/> 
            <Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/> 
           </Grid> 
           <ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/> 
          </Grid> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsChecked" Value="true"> 
           <Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/> 
          </Trigger> 
          <Trigger Property="IsMouseOver" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsPressed" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/> 
           <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsEnabled" Value="false"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <Style x:Key="ExpanderHeaderFocusVisual"> 
      <Setter Property="Control.Template"> 
       <Setter.Value> 
        <ControlTemplate> 
         <Border> 
          <Rectangle Margin="0" SnapsToDevicePixels="true" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2"/> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type ToggleButton}"> 
         <Border Padding="{TemplateBinding Padding}"> 
          <Grid Background="Transparent" SnapsToDevicePixels="False"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="19"/> 
            <ColumnDefinition Width="*"/> 
           </Grid.ColumnDefinitions> 
           <Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/> 
           <Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/> 
           <ContentPresenter Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/> 
          </Grid> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsChecked" Value="true"> 
           <Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/> 
          </Trigger> 
          <Trigger Property="IsMouseOver" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsPressed" Value="true"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/> 
           <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/> 
          </Trigger> 
          <Trigger Property="IsEnabled" Value="false"> 
           <Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/> 
           <Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/> 
           <Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <Style x:Key="ExpanderStyle1" TargetType="{x:Type Expander}"> 
      <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
      <Setter Property="Background" Value="Transparent"/> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
      <Setter Property="VerticalContentAlignment" Value="Stretch"/> 
      <Setter Property="BorderBrush" Value="Transparent"/> 
      <Setter Property="BorderThickness" Value="1"/> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Expander}"> 
         <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true"> 
          <DockPanel> 
           <ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" MinWidth="0" MinHeight="0" Padding="{TemplateBinding Padding}" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> 
           <ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
          </DockPanel> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsExpanded" Value="true"> 
           <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/> 
          </Trigger> 
          <Trigger Property="ExpandDirection" Value="Right"> 
           <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/> 
           <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/> 
           <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderRightHeaderStyle}"/> 
          </Trigger> 
          <Trigger Property="ExpandDirection" Value="Up"> 
           <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/> 
           <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/> 
           <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderUpHeaderStyle}"/> 
          </Trigger> 
          <Trigger Property="ExpandDirection" Value="Left"> 
           <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/> 
           <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/> 
           <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderLeftHeaderStyle}"/> 
          </Trigger> 
          <Trigger Property="IsEnabled" Value="false"> 
           <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources>  

扩展器使用

<Expander Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Style="{DynamicResource ExpanderStyle1}">    
    <Expander.HeaderTemplate> 
     <DataTemplate> 
      <DockPanel LastChildFill="False" Background="LimeGreen"> 
       <TextBlock Text="Expander1"/> 
       <Button Content="Press" DockPanel.Dock="Right"/> 
       <Button Content="Press" DockPanel.Dock="Right"/> 
      </DockPanel> 
     </DataTemplate> 
    </Expander.HeaderTemplate> 
    <StackPanel Background="LightSteelBlue"></StackPanel> 
</Expander> 

输出:

Expander with buttons at right

+0

这太棒了!非常感谢! – greyfox

1

我建议你制作一个专门为你做这项工作的班级,这里是一个沿着解释的原始骨架。

在顶部有一种面包屑棒,这是实际的按钮,当按下将扩大目标部分。

enter image description here

ExpanderGroup类,负责渲染和一些UI逻辑

有2点集合,一个用于面包屑杆的头部,其他都为Expanderš自己。

public partial class ExpanderGroup : UserControl 
{ 
    public static readonly DependencyProperty ChildrenProperty = DependencyProperty.Register(
     "Children", typeof (ObservableCollection<Expander>), typeof (ExpanderGroup), 
     new PropertyMetadata(default(ObservableCollection<Expander>))); 

    public static readonly DependencyProperty ChildrenHeadersProperty = DependencyProperty.Register(
     "ChildrenHeaders", typeof (ObservableCollection<string>), typeof (ExpanderGroup), 
     new PropertyMetadata(default(ObservableCollection<string>))); 

    public ExpanderGroup() 
    { 
     InitializeComponent(); 
     Children = new ObservableCollection<Expander>(); 
     ChildrenHeaders = new ObservableCollection<string>(); 
    } 

    public ObservableCollection<Expander> Children 
    { 
     get { return (ObservableCollection<Expander>) GetValue(ChildrenProperty); } 
     set { SetValue(ChildrenProperty, value); } 
    } 

    public ObservableCollection<string> ChildrenHeaders 
    { 
     get { return (ObservableCollection<string>) GetValue(ChildrenHeadersProperty); } 
     set { SetValue(ChildrenHeadersProperty, value); } 
    } 

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
    { 
     // find the corresponding expander to toggle button clicked 
     // it is very primitive as it expects an exact mapping by name 
     var button = (ToggleButton) sender; 
     var text = (string) button.Content; 
     var expander = Children.Single(s => (string) s.Header == text); 

     // toggle expansion status 
     expander.IsExpanded = button.IsChecked != null && (bool) button.IsChecked; 

     // little helper that expands the root expander 
     // (though its template should be changed for better UX) 
     RootExpander.IsExpanded = Children.Any(s => s.IsExpanded); 
    } 
} 

注:

  • 我用一个非常简单的逻辑,即我找回根据其报头对应的Expander,可以提高其进一步,无论是通过参照其索引或任何其他方式。
  • 有第二个集合ChildrenHeaders,因为如果您尝试从两个来源获取扩展程序,它们将仅出现在其中一个容器上,因为UIElement只能有一个父级。
  • 您可能还想制作一个机制,以便当直接操纵Expander时,面包屑中的相应按钮会切换或不切换。提示:此的好去处将是ChildrenPropertyChangedCallback在那里你会建立一个切换按钮且有针对性的扩展

ExpanderGroup XAML部分

<UserControl x:Class="delme.ExpanderGroup" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:delme" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:system="clr-namespace:System;assembly=mscorlib" 
      x:Name="Root" 
      d:DesignHeight="300" 
      d:DesignWidth="300" 
      mc:Ignorable="d"> 
    <Grid> 
     <StackPanel> 

      <ItemsControl Background="LightBlue" ItemsSource="{Binding ElementName=Root, Path=ChildrenHeaders}"> 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <StackPanel IsItemsHost="True" Orientation="Horizontal" /> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate DataType="system:String"> 
         <ToggleButton Width="75" 
             Height="22" 
             Margin="2" 
             Click="ButtonBase_OnClick" 
             Content="{Binding}" /> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 

      <Expander x:Name="RootExpander"> 
       <ItemsControl Background="LightCyan" ItemsSource="{Binding ElementName=Root, Path=Children}"> 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <StackPanel IsItemsHost="True" /> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
       </ItemsControl> 
      </Expander> 

     </StackPanel> 
    </Grid> 
</UserControl> 

之间什么都没有一点点更加振奋的关系在这里非凡,只是为了举例而保持最低限度。你可能会稍微调整一下,尤其是将RootExpander的模板重新定义为IMO,以便为了更好的用户体验而简单地隐藏小箭头。您可以/应该使用Blend来轻松调整其模板。

使用例如

<Window x:Class="delme.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:delme" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:system="clr-namespace:System;assembly=mscorlib" 
     Title="MainWindow" 
     Width="525" 
     Height="350" 
     mc:Ignorable="d"> 
    <Grid> 

     <local:ExpanderGroup> 
      <local:ExpanderGroup.ChildrenHeaders> 
       <system:String>Expander1</system:String> 
       <system:String>Expander2</system:String> 
      </local:ExpanderGroup.ChildrenHeaders> 
      <local:ExpanderGroup.Children> 
       <Expander Header="Expander1"> 
        <TextBlock Text="abcd" /> 
       </Expander> 
       <Expander Header="Expander2"> 
        <TextBlock Text="efgh" /> 
       </Expander> 
      </local:ExpanderGroup.Children> 
     </local:ExpanderGroup> 

    </Grid> 
</Window> 

去,并提高在该设计!