【问题标题】:Difference between Style and ControlTemplateStyle 和 ControlTemplate 的区别
【发布时间】:2011-09-02 10:23:48
【问题描述】:

您能告诉我 Style 和 ControlTemplate 之间的主要区别是什么吗? 何时或为何使用其中一种?

在我看来,它们完全相同。由于我是初学者,我认为我错了,所以我的问题。

【问题讨论】:

标签: c# .net wpf xaml


【解决方案1】:

在样式中,您可以设置控件的属性。

<Style x:Key="MyButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Red"/>
</Style>

<Button Style="{StaticResource MyButtonStyle}"/>

所有使用此样式的按钮都将其背景设置为红色。

在模板中定义控件的 UI(结构)。

<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
    <Grid>
        <Rectangle Fill="Green"/>
        <ContentPresenter/>
    </Grid>
</ControlTemplate>

<Button Template="{StaticResource MyButtonTemplate}"/>

使用此模板的所有按钮都将具有无法更改的绿色背景。

模板中设置的值只能通过替换整个模板来替换。 style 中的值可以通过在使用控件时显式设置值来替换。这就是为什么通过使用 TemplateBinding 而不是编码值来更好地使用控件的属性的原因。

<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
    <Grid>
        <Rectangle Fill="{TemplateBinding Background}"/>
        <ContentPresenter/>
    </Grid>
</ControlTemplate>

现在模板使用它应用到的按钮的背景属性的值,所以可以自定义:

<Button Template="{StaticResource MyButtonTemplate}" Background="Yellow"/>

另一个有用的功能是控件可以选择默认样式,而无需为其分配特定样式。模板无法做到这一点。

只需删除样式的 x:Key 属性(同样:您不能对模板执行此操作)。样式下方可视树中的所有按钮都将应用此样式。

结合模板和样式更加强大:您可以在样式中设置模板属性:

<Style TargetType="Button">
    <Setter Property="Background" Value="Red"/>
    <Setter Property="Template">
        <Setter.Value>
             <ControlTemplate TargetType="Button">
                 <Grid>
                     <Rectangle Fill="{TemplateBinding Background}"/>
                     <ContentPresenter/>
                 </Grid>
             </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

【讨论】:

  • 所以你的例子完全符合我想知道的问题......控制模板和只定义一个控制模板的样式有什么区别?总是用 Styles 封装 controltemplate 是不是很常见?
  • 我在谷歌上搜索了一个小时才明白这一点,你用几句话解释了这一点,我直接明白了!教学的力量!
【解决方案2】:

不,你确实错了。 样式集属性在控件上。 ControlTemplate 是大多数控件共享的属性,用于指定它们的呈现方式。

详细地说,您可以使用一种样式对一组属性的设置进行分组,以便您可以重复使用它来标准化您的控件。样式可以在控件上显式设置,也可以应用于某个类型。

控件模板可以通过样式设置或在控件上显式设置以更改其显示方式。所有控件都具有嵌入在 .net wpf 程序集中的默认模板(和样式)。看到这些并了解 wpf 开发人员如何实现所有控件的正常版本是非常有启发性的。如果您安装了 Expression blend,请查看其“SystemThemes”文件夹。

更新:

了解 Styles 和 ControlTemplates 如何“添加控件”。在某种程度上,ControlTemplate 是定义控件组成的控件的唯一方法。但是,一些默认的 .net 控件允许您使用控件代替文本。

例如:

<GroupBox>
  <GroupBox.Header>
    <CheckBox/>
  </GroupBox.Header>
</GroupBox>

这会在不更改ControlTemplate 的情况下向组框“添加”一个复选框,但这是因为GroupBox 的默认ControlTemplate 允许将任何内容作为标题。这是通过使用特殊控件(例如ContentPresenter)来完成的。

但是,有时控件的默认 ControlTemplate 不允许您更改要通过属性更改的内容。然后您必须更改 ControlTemplate。

无论您是直接设置控件的属性(Content、Header、ControlTemplate、IsEnabled 等)还是通过样式设置都无所谓,样式只是一种方便。

希望这能更清楚地回答您的问题。

【讨论】:

  • 好的,但是在我工作的项目中,两者都用于将其他控件添加到某些控件...以及设置属性...所以我看不出它们的区别采用 ? ? ?
【解决方案3】:

您可以将样式视为将一组属性值应用于多个元素的便捷方式。您可以通过直接在每个 TextBlock 元素上设置属性(例如 FontSize 和 FontFamily)来更改默认外观。但是,如果您希望 TextBlock 元素共享某些属性,则可以在 XAML 文件的资源部分中创建样式。

另一方面,ControlTemplate 指定控件的视觉结构和视觉行为。您可以通过给它一个新的 ControlTemplate 来自定义控件的外观。创建 ControlTemplate 时,您替换现有控件的外观而不更改其功能。例如,您可以将应用程序中的按钮设为圆形而不是默认的方形,但按钮仍会引发 Click 事件。

参考:http://msdn.microsoft.com/en-us/library/ms745683.aspx

【讨论】:

    【解决方案4】:

    我发现了一些有趣的差异 The difference between styles and templates (msdn)

    风格: 您可以在样式中设置仅预先存在的属性。例如,您不能为属于您添加到模板的新部件的属性设置默认值。

    模板: 修改模板时,您可以访问控件的更多部分,而不是修改样式时。例如,您可以更改弹出列表在组合框中的显示方式,或者通过修改项目模板来更改触发组合框中弹出列表的按钮的外观。


    风格: 您可以使用样式来指定控件的默认行为。例如,在按钮的样式中,您可以指定触发器,以便当用户将鼠标指针移到按钮上时,背景颜色会发生变化。这些属性更改是瞬时的(它们不能逐渐动画)。

    模板: 您可以使用触发器指定模板中任何新部件和现有部件的行为。例如,您可以指定一个触发器,以便当用户将鼠标指针移到按钮上时,其中一个部分的颜色会发生变化。这些属性更改可以是瞬时的或逐渐动画化以产生平滑的过渡。

    【讨论】:

      【解决方案5】:

      好的,我有完全相同的问题,我在这个帖子中找到的答案为我指明了正确的方向,所以我分享一下,如果我自己能更好地理解它。

      Style 比 ControlTemplate 更灵活。

      来自 Windows Presentation Foundation Unleashed,Adam Nathan 和帮派(作家)声明:

      • “除了将模板 [与使用 Style 的 ControlTemplate 设置器的样式] 与任意属性设置组合起来很方便之外,这样做[在样式上设置 ControlTemplate 设置器] 还有一些重要的优点:

        1. 它为您提供默认模板的效果。例如,当类型化样式默认应用于元素,并且该样式包含自定义控件模板时,将应用控件模板而无需在这些元素上显式标记。
        2. 它使您能够提供控制模板外观的默认但可覆盖的属性值。换句话说,它使您能够尊重模板化父级的属性,但仍提供您自己的默认值。”

      换句话说,创建样式允许样式模板设置器的用户覆盖设置的值,即使他们没有使用 TemplateBinding(例如 {TemplateBinding Width})。如果您在样式中硬编码 Width,则 Style 的用户仍然可以覆盖它,但如果您在模板中硬编码 Width 属性,用户就会被它卡住。

      此外,(这有点令人困惑)当使用带有 TemplateBinding 的 ContentTemplate 时,用户有责任设置该属性,否则它将使用 TargetType 的默认属性。如果使用样式,则可以通过使用属性的 setter 并应用 TemplateBinding 引用回该 setter 来覆盖 TargetType 的默认属性。这本书更好地解释了它,第 338 页(将模板与样式混合)

      【讨论】:

        猜你喜欢
        • 2011-05-26
        • 1970-01-01
        • 2013-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-03
        • 1970-01-01
        • 2016-01-02
        相关资源
        最近更新 更多