我正在观看有关DataTemplates的在线视频教程
演示代码如下
<StackPanel.Resources>
<ControlTemplate x:Key="MyButton">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" />
<ContentControl Content="{TemplateBinding ContentControl.Content}" /><!--why this-->
</Grid>
</ControlTemplate>
</StackPanel.Resources>
<Button Content="Click me" Background="Green" Width="100" Height="50" Template="{StaticResource MyButton}" />
</StackPanel>
我丢失的位是
<ContentControl Content="{TemplateBinding ContentControl.Content}" />
为什么ControlControl.Content
而不只是Content
。如果我们在此之前审核代码行,则会显示Ellipse Fill="{TemplateBinding Background}"
而不是<Ellipse Fill="{TemplateBinding Ellipse.Background}" />
为什么我们说ContentControl
?是因为Content
的属性Button
实际上是ContentControl
类型的对象,而Background
只是Button
的字符串属性?
答案 0 :(得分:1)
如果指定ControlTemplate
的类型(Style
也相同),那么编译器将知道要查找的对象以查找Content
属性:
<ControlTemplate x:Key="MyButton" TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" />
<ContentControl Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
如果您没有指定类型,编译器将要求您输入TemplateBinding
路径中的类型。
但是,有时您也可以指定属性来自哪个基类,因为Content
属性实际上是从Button
类的ContentControl
类中继承的。 ..您可以点击MSDN上Button
Class页面中的Content
媒体资源看到此信息,该信息会转到ContentControl.Content
Property页面。
您应该会发现,在这种情况下,您还可以使用Button.Content
,因为该属性是在Button
类中继承的。因此,要回答您的问题,您实际上需要才能使用ContentControl.Content
...您可以选择。
更新&gt;&gt;&gt;
您可以使用Style
执行此操作,但使用ControlTemplate
s时,您必须确保应用它的对象也具有相同的基类和所有属性在ControlTemplate
中使用。从理论上讲,你可以这样做:
<ControlTemplate x:Key="MyButton" TargetType="{x:Type ContentControl}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" />
<ContentControl Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
...
<RadioButton Template="{StaticResource MyButton}" Content="Hey" />
但是,我认为实际需要使用ContentPresenter
代替ContentControl
:
<ControlTemplate x:Key="MyButton" TargetType="{x:Type ContentControl}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" />
<ContentPresenter />
</Grid>
</ControlTemplate>
您可能还想阅读Stack Overflow上的What's the difference between ContentControl and ContentPresenter?页面。