C# 理解XAML/WPF中的样式和模板
我将从代码开始。下面是一个简单的按钮:C# 理解XAML/WPF中的样式和模板,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我将从代码开始。下面是一个简单的按钮: <Grid> <Button Height="20" Width="100" Background="Brown" BorderBrush="Blue" Foreground="Aqua">Test button</Button> </Grid> 所以,我的问题是:为什么在声明模板时,我必须在按钮的边框内设置按钮的背景 这
<Grid>
<Button Height="20" Width="100"
Background="Brown"
BorderBrush="Blue"
Foreground="Aqua">Test button</Button>
</Grid>
所以,我的问题是:为什么在声明模板时,我必须在按钮的边框内设置按钮的背景
这个带有按钮的示例只是一个示例。更一般的回答/解释会更好 当您覆盖控件的模板时
就像按钮
一样,您基本上控制了该控件的整个外观。您正在替换该控件的可视树
因此,当您在应用程序中放置按钮时,它将包含在其控制模板中找到的子树
这可以在Visual Studio 2015的Live Visual树窗格或Snoop中观察到:
按钮
是一个内容控件
,这意味着其内容属性
被设置为“内容”
。ContentControl
的ControlTemplate
中的ContentPresenter
将拾取您在ContentControl
的Content
属性中放入的任何内容(您甚至不需要ContentPresenter
的模板绑定)。如果您使用一个简单的字符串Content
,如
,它将被转换为
,从而在图片的可视树中显示文本块
在您提供的示例中,边框
元素用于让用户能够为按钮
设置背景。由于ContentPresenter
没有Background
属性,因此您必须将其包装在边框
元素中,并在边框
上设置Background
我认为名称Border
可能令人困惑,它并不总是严格用于渲染边框(尽管在本例中,它也用于背景)
我希望这有点道理,如果您还有其他问题,请随时提问。谢谢,但我不明白这一点:“(在您的案例中,您甚至不需要ContentPresenter内容的TemplateBinding)。如果您使用一个简单的字符串内容,它将被转换为,因此图片中可视树中的TextBlock。”如果删除此项:
将完全没有内容。如果我更改为
,它将始终是“Foo”。我的意思是如果您只有
而没有内容=“{TemplateBinding Content}”
部分,它仍然会显示您在按钮的内容
属性中输入的任何内容。另一方面,我的意思是,当您清楚地将内容
设置为如下字符串时:
。将被呈现为
。所以它基本上等同于
。
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Content" Value="foo"></Setter>
<Setter Property="BorderBrush" Value="Blue"></Setter>
<Setter Property="Background" Value="Brown"></Setter>
<Setter Property="Foreground" Value="Aqua"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}"></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Height="20" Width="100">
Test button
</Button>
</Grid>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}"></ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>