模板控件中的 ContentPresenter 不起作用

ContentPresenter in Templated Control not working

我创建了一个模板化控件。我对默认样式所做的只是添加一个内容展示器。我还在 App.xaml 文件中引用了 Generic.xaml。

<Style TargetType="local2:TestingControl" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local2:TestingControl">
                <Border
                    Height="200px"
                    Background="Green">

                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>


public sealed class TestingControl : Control
{
    public TestingControl()
    {
        this.DefaultStyleKey = typeof(TestingControl);
    }

}

我没有对控件的.cs代码做任何修改。 我尝试设置内容,但被告知该控件不允许直接内容。

 <StackPanel>
        <local1:TestingControl >
            Testing
        </local1:TestingControl>

    </StackPanel>

我应该如何使用内容展示器?

如果我尝试使用用户控件,同样的方法非常有效。

要处理自定义模板控件中的 XAML 内容,您必须从 ContentControl or stay inherited from a Control, implement a custom ContentProperty and bind a ContentPresenter 派生控件。

使用 ContentControl 更容易一些,这是您可能最终得到的代码。

样式定义在Themes/Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="using:SmallTests2018">

    <Style TargetType="local:TemplatedControlWithContent" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TemplatedControlWithContent">
                    <Border
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Viewbox>
                            <Grid>
                                <Viewbox HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                                    <Ellipse Width="10" Height="10" Fill="#80808080" />
                                </Viewbox>
                                <ContentPresenter />
                            </Grid>
                        </Viewbox>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
  • 我更喜欢将 Border 绑定到模板化控件属性,这样使用它的开发人员可以更好地控制外观。
  • 此处的椭圆是一些额外自定义内容的示例。

TemplatedControlWithContent.cs

using System;
using Windows.UI.Xaml.Controls;

namespace SmallTests2018
{
    public sealed class TemplatedControlWithContent : ContentControl
    {
        public TemplatedControlWithContent()
        {
            DefaultStyleKey = typeof(TemplatedControlWithContent);
        }
    }
}
  • 请注意,这里唯一的变化是控制来自 ContentControl

一个测试页TemplatedControlWithContentPage.xaml

<Page
    x:Class="SmallTests2018.TemplatedControlWithContentPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SmallTests2018"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <local:TemplatedControlWithContent>
        <TextBlock>Hello World!</TextBlock>
    </local:TemplatedControlWithContent>
</Page>

它在页面中的外观 XAML 设计师

而@DK 发布的答案。非常完美,我试图使用 Control 而不是 ContentControl。原因是因为我只是在尝试熟悉 UWP。

他的回答对我解决继承自 Control 的控件的问题非常有帮助。

TestingControl.cs

[ContentProperty(Name = "Content")]
public sealed class TestingControl : Control
{
    public TestingControl()
    {
        this.DefaultStyleKey = typeof(TestingControl);
    }

    public object Content
    {
        get { return (string)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(string), typeof(TestingControl), new PropertyMetadata(string.Empty));

}

风格

<Style TargetType="local2:TestingControl" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local2:TestingControl">
                <Border
                    Height="200px"
                    Background="Green"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">

                    <ContentPresenter Content="{TemplateBinding Content}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

用法

    <StackPanel>
        <local1:TestingControl >                
                Testing                
        </local1:TestingControl>
    </StackPanel>