WPF 扩展器按钮的样式使其位于扩展器标头内

发布于 2024-09-02 08:41:31 字数 405 浏览 6 评论 0原文

我正在使用 Expander 控件,并设置了标题样式,如下图所示:

http://www.hughgrice.com/Expander.jpg

我遇到的问题是我希望扩展器按钮包含在标题中,以便标题模板末尾的行与 < 对齐code>Expander 内容,即我最终希望得到类似于下图的内容:

http ://www.hughgrice.com/Expander.gif

提前致谢。

I am using the Expander control and have styled the header as shown in the picture below:

http://www.hughgrice.com/Expander.jpg

The problem I have is that I want the expander button to be contained within the header so that the line for the end of the header template aligns with the Expander content i.e. I ultimatly want to end up with something similar to the image below:

http://www.hughgrice.com/Expander.gif

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠栀 2024-09-09 08:41:31

我发现您想要将扩展器按钮实际移动到 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 中设置负边距以覆盖 Expander 按钮。您的 DataTemplat 将只包含如下内容,而不是上面显示的 ControlTemplate:

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

调整负边距以获得您想要的外观。这个解决方案更简单,但较差,因为如果您切换到不同的系统主题,所需的边距可能会改变,并且您的扩展器可能不再看起来很好。

I see that you want to actually move the expander button into your HeaderTemplate, not just restyle it. This is easily done with FindAncestor:

First add a ToggleButton and bind its IsChecked property using FindAncestor, along these lines:

<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>           

This adds an expand button inside the header template but does not hide the original button provided by the Expander. To do this I recommend you replace the Expander's ControlTemplate.

Here is a complete copy of Expander's ControlTemplate with the ToggleButton replaced with a simple 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>

It might be used as follows:

<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 ...

A simpler alternative would be to just set a negative margin in yourHeaderTemplate to cover the expander button. Instead of the ControlTemplate shown above, your DataTemplat would just contain something like this:

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

Adjust the negative margin to get the look you want. This solution is simpler but inferior in that if you switch to a different system theme the required margin may change and your expander may no longer look good.

×纯※雪 2024-09-09 08:41:31

您将需要编辑 Expander 的模板,而不是 HeaderTemplate。 HeaderTemplate 不包含展开按钮,只包含其中的内容。

默认的控件模板看起来像这样:

<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 还没有真正具备这种能力。

You will need to edit the Expander's Template, not the HeaderTemplate. The HeaderTemplate doesn't contain the expand button, just the content inside of it.

The default control template looks something like this:

<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>

I took out most of the attributes but left in the important stuff. Basically, you will want to add your customizations around the ToggleButton. That is what contains the expand button and the header content.

If you have Expression Blend, it makes this process much easier because you can simply edit a copy of the original template. Visual Studio doesn't really have this ability yet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文