首页 > 解决方案 > UWP 如何创建承载内容的用户控件?

问题描述

我在尝试实现一件非常微不足道的事情时感到非常沮丧(或者至少,我期望的事情应该是微不足道的......)

我有一个需要自定义切换按钮的要求,为此我需要创建一个承载切换按钮的用户控件,并承载该用户控件中描述的内容。我做了一个小迷你应用程序来演示“要求”。

<local:MyUserControl1>
    <TextBlock>Just an example</TextBlock>
</local:MyUserControl1>

MyUserControl1外观如下:

<UserControl
    x:Class="App2.MyUserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Name="Bla" d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <Style TargetType="ToggleButton">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Grid>
                            <Ellipse Width="300" Height="300" Fill="Blue"/>
                            <ContentPresenter Content="{Binding ElementName=Bla, Path=MainContent}"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <ToggleButton/>
</UserControl>

后面的代码:

    public static DependencyProperty MainContentProperty = DependencyProperty.Register(
        "MainContent",
        typeof(object),
        typeof(MyUserControl1),
        null);

    public object MainContent
    {
        get => GetValue(MainContentProperty);
        set => SetValue(MainContentProperty, value);
    }

当我运行应用程序时,会显示文本,但样式/切换按钮被忽略/未应用/无论如何。

在此处输入图像描述

视觉树确认我做错了什么:

在此处输入图像描述

我查看了许多其他相关的 SO Q&A,但我仍然不知道如何以我想要的方式让它工作。

标签: c#uwpcontroltemplate

解决方案


您的代码应该可以工作,除了没有显示ContentPropertyAttribute应该在哪里的行。您能否确保MyUserControl1已识别其内容属性并查看是否有帮助。

[ContentProperty(Name = "MainContent")]
public sealed partial class MyUserControl1 : UserControl
...

更新

下面是使用 Win 10 Pro 1803、build 17134、NETCore 6.2.2 测试的完整代码。

请注意,您可以在UserControl.Resources或外部资源中定义控件模板,以将其与“主”UI 布局分开,或将其保留在ToggleButton.Template少几行 XAML 中。

UserControlWithContent.xaml

<UserControl
    x:Class="SmallTests2018.UserControlWithContent"
    x:Name="Self"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ToggleButton>
        <ToggleButton.Template>
            <ControlTemplate>
                <Grid>
                    <Ellipse Width="300" Height="300" Fill="Blue"/>
                    <ContentPresenter
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Content="{Binding MainContent, ElementName=Self, FallbackValue='{}{ content }'}" />
                </Grid>
            </ControlTemplate>
        </ToggleButton.Template>
    </ToggleButton>
</UserControl>

UserControlWithContent.xaml.cs

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;

namespace SmallTests2018
{
    [ContentProperty(Name = "MainContent")]
    public sealed partial class UserControlWithContent : UserControl
    {
        public UserControlWithContent()
        {
            this.InitializeComponent();
        }

        public static DependencyProperty MainContentProperty =
            DependencyProperty.Register("MainContent", typeof(object), typeof(UserControlWithContent), null);

        public object MainContent
        {
            get => GetValue(MainContentProperty);
            set => SetValue(MainContentProperty, value);
        }
    }
}

UserControlWithContentPage.xaml

<Page
    x:Class="SmallTests2018.UserControlWithContentPage"
    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}">

    <Viewbox>
        <local:UserControlWithContent>
            <TextBlock FontSize="32" Foreground="Yellow">Just an example</TextBlock>
        </local:UserControlWithContent>
    </Viewbox>
</Page>

页面 XAML 设计器屏幕截图

在此处输入图像描述


推荐阅读