【问题标题】:Why define a Template inside a Style in xaml, WPF?为什么要在 xaml、WPF 的样式中定义模板?
【发布时间】:2011-06-19 20:11:51
【问题描述】:

自从我开始使用 MS 的控件模板示例作为构建自定义控件的基础以来,我一直在想这个问题。

以标签为例:http://msdn.microsoft.com/en-us/library/ms752327.aspx

为什么它是这样定义的:

<Style x:Key="{x:Type Label}" TargetType="Label">
  <Setter Property="HorizontalContentAlignment" Value="Left" />
  <Setter Property="VerticalContentAlignment" Value="Top" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Label">
        <Border>
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            RecognizesAccessKey="True" />
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground">
              <Setter.Value>
                <SolidColorBrush Color="{DynamicResource DisabledForegroundColor}" />
              </Setter.Value>
            </Setter>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

而不是直接这样:

<ControlTemplate x:Key="{x:Type Label}" TargetType="Label">
    <Border>
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                        RecognizesAccessKey="True" />
    </Border>
    <ControlTemplate.Triggers>
      <Trigger Property="IsEnabled" Value="false">
        <Setter Property="Foreground">
          <Setter.Value>
            <SolidColorBrush Color="{DynamicResource DisabledForegroundColor}" />
          </Setter.Value>
        </Setter>
      </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

然后直接作为模板调用而不是通过样式属性?

做这样的事情有什么我看不到的隐藏原因吗?还是它只是一种做事方式,仅此而已?

(注意:不要告诉我这是因为水平和垂直对齐设置器!我们都知道这些是标签的默认值,如果保留这些值,这基本上是无用的)

【问题讨论】:

    标签: wpf templates xaml styles


    【解决方案1】:

    如果不使用样式,就不可能自动将模板分配给特定控件类型的所有实例。为控件模板设置x:Key="{x:Type Label}" 不会自动将此模板应用于Label 类型的所有控件。

    您可以通过将TargetType 设置为Button 来使样式应用于可视树中声明下方的所有按钮,但是如果您不将模板包装在样式 具有模板的 Setter

    另外,请注意,在您的示例中,您可以交换

    <Style x:Key="{x:Type Label}" TargetType="Label">
    

    <Style TargetType="Label">
    

    如果 x:Key 定义被省略,x:Key 将设置为 TargetType

    【讨论】:

    • oy,我虽然它对模板和样式的工作方式相同。我会试着用我自己的眼睛看它(我不能相信这两个行为不同......)至于你答案的第二部分,我不得不不同意(你看到了我关于这个主题的另一个问题) .仍然没有找到我得到的行为的有效解释,但是删除 x:key 并不总是像它应该的那样工作(至少对我来说......)
    • 它是专门为样式制作的,如果没有定义控件的样式,它将遍历可视化树,直到找到 x:Key 等于它自己的类型的样式定义,然后它会将该样式应用于自身。模板(或任何其他类型的资源)没有实现相同的逻辑,所以这并不奇怪;)
    • 好的,我亲眼看到了。在实际询问之前应该尝试过。实际上比这更糟糕:编译后你会得到一个错误,说不可能将 Style 转换为 ControlTemplate。所以这对你写的东西很有意义。我原以为这适用于模板和样式......(为什么不呢?)
    • 为什么不我不确定。但是所有功能都需要时间和金钱来实现,因此与其他更重要的功能相比,这个功能可能被认为不够重要。从技术上讲,我认为没有理由不能以这种方式实施。但是话又说回来,将它包装在样式中的代码也没有那么多。
    猜你喜欢
    • 2016-04-14
    • 2014-10-15
    • 2012-11-30
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    相关资源
    最近更新 更多