Style和ControlTemplate之间的区别

时间:2011-05-26 09:12:51

标签: c# .net wpf xaml

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

在我眼里,他们正是非常相同。因为我是初学者,我认为我错了,因此我的问题。

5 个答案:

答案 0 :(得分:71)

在样式中设置控件的属性。

<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}"/>

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

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

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

现在模板使用了应用它的按钮的Background属性的值,因此可以自定义:

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

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

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

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

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

答案 1 :(得分:23)

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

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

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

<强>更新

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

例如:

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

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

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

无论是直接设置控件的属性(Content,Header,ControlTemplate,IsEnabled等)还是通过样式都无关紧要,样式只是方便。

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

答案 2 :(得分:14)

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

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

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

答案 3 :(得分:2)

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

<强>样式: 您可以在样式中设置仅预先存在的属性。例如,您无法为属于添加到模板的新零件的属性设置默认值。

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


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

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

答案 4 :(得分:0)

好的,我有完全相同的问题,我在这个帖子中找到的答案指出我正确的方向,所以我分享,如果只是这样我自己可以更好地理解它。

Style比ControlTemplate更灵活。

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

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

    1. 它为您提供默认模板的效果。例如,默认情况下,当键入的样式应用于元素,并且该样式包含自定义控件模板时,控件模板将在不对这些元素进行任何显式标记的情况下应用。
    2. 它使您能够提供控制模板外观的默认但可覆盖的属性值。换句话说,它使您能够尊重模板化父级的属性,但仍然提供您自己的默认值。“

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

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