【问题标题】:Why do I need to type ContentControl.Content and not just Content为什么我需要输入 ContentControl.Content 而不仅仅是 Content
【发布时间】:2015-02-20 13:54:14
【问题描述】:

我正在观看有关 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}" 而不是 &lt;Ellipse Fill="{TemplateBinding Ellipse.Background}" /&gt;

为什么我们声明ContentControl?是因为Button 的属性Content 实际上是ContentControl 类型的对象,而Background 只是Button 的字符串属性?

【问题讨论】:

  • in ControlTemplate 添加TargetType="{x:Type Button}" 否则模板不知道目标类型
  • @dkozl,我相信你,你过去帮了我很多,所以我问这个问题并不粗鲁,但为什么呢?事实上,它运行良好。这更多是关于显式编码还是没有定义它的问题?
  • @dkozl,我测试了它——通过明确输入类型,我不需要 ContentControl...我猜是因为它知道类型,它知道它有什么属性...没有它,我猜它只能访问对象(或控件或框架元素 - 无论它继承自什么)。如果您想输入它,这很容易成为答案?
  • 基本上,如果你不指定TargetType,就像你会为Control类型指定它,但它没有定义Content属性,所以你必须指定包含类型。有关更多信息,请查看例如 here

标签: wpf xaml


【解决方案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...您可以选择。


更新>>>

您可以使用Styles 做到这一点,但使用ControlTemplates,您必须确保应用它的对象也具有相同的基类和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? 页面。

【讨论】:

  • 如果我输入目标类型作为基类(例如 Control),那么我假设我可以将它用于更多控件。 EG,如果我的风格只改变了光标,那么它可以被所有继承自 Control 的控件共享?这是正确的吗?
猜你喜欢
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 2016-02-15
相关资源
最近更新 更多