WPF扩展按钮样式化,使其位于扩展头中。

9

你能重新上传图片吗? - Christo S. Christov
2个回答

15

我看到你想要将展开按钮实际移动到HeaderTemplate中,而不仅仅是重新设计它。使用FindAncestor很容易实现这一点:

首先添加一个ToggleButton并使用FindAncestor绑定它的IsChecked属性,就像这样:

<DataTemplate x:Key="MyHeaderTemplate">
  <Border ...>
    <DockPanel>
      <!-- Expander button -->
      <ToggleButton
         IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor,Header,1}}"
         Content=... />

      <!-- Other content here -->
      ...
    </DockPanel>
  </Border>
</DataTemplate>           

这将在头部模板中添加一个展开按钮,但不会隐藏Expander提供的原始按钮。如果要隐藏原始按钮,我建议您替换Expander的ControlTemplate。

以下是Expander的完整ControlTemplate副本,其中ToggleButton被简单的ContentPresenter替换:

<ControlTemplate x:Key="ExpanderWithoutButton" TargetType="{x:Type Expander}">
  <Border BorderBrush="{TemplateBinding BorderBrush}"
          BorderThickness="{TemplateBinding BorderThickness}"
          Background="{TemplateBinding Background}"
          CornerRadius="3"
          SnapsToDevicePixels="true">
    <DockPanel>
      <ContentPresenter
        Content="{TemplateBinding Header}"
        ContentTemplate="{TemplateBinding HeaderTemplate}"
        ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
        DockPanel.Dock="Top"
        Margin="1"
        Focusable="false" />
      <ContentPresenter
        x:Name="ExpandSite"
        Visibility="Collapsed"
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
        Margin="{TemplateBinding Padding}"
        Focusable="false" />
    </DockPanel>
  </Border>
  <ControlTemplate.Triggers>
    <Trigger Property="IsExpanded" Value="true">
      <Setter Property="Visibility" Value="Visible" TargetName="ExpandSite"/>
    </Trigger>
    <Trigger Property="IsEnabled" Value="false">
      <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

它可能被如下使用:

<Expander Template="{StaticResource ExpanderWithoutButton}">

  <Expander.HeaderTemplate>
    <DataTemplate ...>
      <Border ...>
        <DockPanel>
          <ToggleButton ...
            IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor,Header,1}}" />
          ... other header template content here ...

一种更简单的替代方案是在您的HeaderTemplate中设置一个负边距以覆盖展开按钮。 与上面显示的ControlTemplate不同,您的DataTemplate只需包含类似于以下内容:

<DataTemplate ...>
  <Border Margin="-20 0 0 0" ... />

调整负边距以获得所需的外观。这种解决方案更简单,但不够优秀,因为如果您切换到其他系统主题,所需的边距可能会改变,您的展开器可能不再好看。


6

您需要编辑扩展器的模板,而不是标题模板。标题模板不包含展开按钮,只包含其中的内容。

默认控件模板大致如下:

<ControlTemplate TargetType="{x:Type Expander}">
    <Border>
        <DockPanel>
            <ToggleButton x:Name="HeaderSite"
                          ContentTemplate="{TemplateBinding HeaderTemplate}"
                          Content="{TemplateBinding Header}"
                          DockPanel.Dock="Top"
                          IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
            <ContentPresenter x:Name="ExpandSite" />
        </DockPanel>
    </Border>
</ControlTemplate>

我删除了大部分属性,但保留了重要内容。基本上,您需要在ToggleButton周围添加自定义内容。这就包含了展开按钮和标题内容。
如果您使用Expression Blend,则可以更轻松地完成此过程,因为您可以直接编辑原始模板的副本。Visual Studio目前还没有这种能力。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接