2015-12-24 105 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> 

去,並提高在該設計!