也许,我理解一些根本错误的东西,但根据我所读到的,ControlTemplate-Property允许我完全定义Control的外观而不改变它的逻辑,比如事件等。
对于某些测试,我创建了一个空的UWP-Project,并创建了一个带有拉伸的按钮:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button HorizontalAlignment="Stretch"
Background="Red">
</Button>
</Grid>
正如预期的那样,Button会拉伸整个Window。 现在,我用基本上完全相同的Button覆盖模板,但是模板:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button>
<Button.Template>
<ControlTemplate>
<Button HorizontalAlignment="Stretch"
Background="Red" />
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
在这种情况下,HorizontalAlignment将被忽略。 由于我基本上使用默认按钮模板,按钮覆盖Button的外观,因此我预计会出现相同的行为。我可以通过在Button本身上定义HorizontalAlignment然后使用TemplateBinding来修复它,但我不明白为什么它不会像预期的那样被覆盖。
答案 0 :(得分:2)
如果我们查看Button的默认模板,它本质上是这样的(有些东西比如省略了视觉状态):
<Grid>
<ContentPresenter/>
</Grid>
检查Live Visual Tree中的按钮确认了这一点:
所以你看到Grid没有替换 Button元素,Button仍然是可视树中的Button,而模板定义了Button的直接子节点是什么
如果您将模板设置为以下内容:
<Button HorizontalAlignment="Stretch" Background="Red"/>
然后你会得到这个可视树:
HorizontalAlignment不以这种方式工作的原因是因为它应用于内部按钮而不是外部按钮。作为布局过程的一部分,外部Button(父级)决定了内部Button(子级)的大小和位置,并且由于父级没有被拉伸,因此它只能容纳所需的最小大小。展示孩子。
它就像你在尝试这样做:
<Grid>
<Button>
<!-- This button won't stretch to the width of the Grid -->
<Button HorizontalAlignment="Stretch"/>
<Button>
</Grid>
将按钮的模板设置为按钮没有意义。看起来你要做的就是设置一个Style,然后你可以为Template和父对象的HorizontalAlignment设置一个setter。
<Style x:Name="MyCustomButton" TargetType="Button">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
....
</ControlTemplate>
</Setter>
</Setter>
</Style>
如果要调整控件的模板,可以在XAML设计器中右键单击它&gt;编辑模板&gt;编辑副本。这会将该控件的默认样式引入到您可以修改的页面中。
修改强>
因此,即使没有模板,每个Control都在VisualTree中出现,因此需要进行定位?
我不确定你的意思是&#34;有针对性的&#34;,但是,是的,每个Control和Control派生类都有一个可以指定的模板。每个Control都有一个default style,用于设置控件的模板(以及其他属性)。如果您对这些风格感兴趣,我会推荐您Default control styles and templates。
模板然后只覆盖&#34;内容&#34;控制?
没有。 ContentControl(例如按钮)的内容与模板不同。可以将模板视为定义控件的整个视觉外观,将内容视为仅定义模板中某个外观的子集。例如,当你设置按钮的内容时,你并没有改变按钮的整个外观(按钮仍然有边框和背景),你只改变了按钮内部显示的内容。按钮的可视树中的特定点。它是显示内容的ContentPresenter控件(请参阅我的第一个屏幕截图)。
我不知道我可以看到Visual Tree,我需要特殊版本吗?
Visual Studio已经有一段时间的Live Visual Tree功能(至少从2015年开始),所以除非你有一个过时的Visual Studio版本,否则你应该拥有该功能。