模板控件中的ContentPresenter无法正常工作

时间:2018-12-09 22:07:38

标签: c# xaml uwp uwp-xaml

我已经创建了模板控件。我对默认样式所做的只是添加一个内容演示器。我还在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>

enter image description here 我应该怎么做才能使用内容演示器?

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

2 个答案:

答案 0 :(得分:2)

要在自定义模板控件中处理XAML内容,您必须从ContentControl派生您的控件,或者保持从Control继承,实现自定义ContentProperty并绑定{{ 3}}。

使用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设计器页面中的外观

ContentPresenter

答案 1 :(得分:1)

@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>