UWP Как создать пользовательский элемент управления, который содержит контент? - PullRequest
0 голосов
/ 07 декабря 2018

Я очень расстроен, пытаясь достичь очень тривиальной вещи (или, по крайней мере, чего-то, что я ожидал, должно быть тривиально ...)

У меня есть требование, где нужно настроить кнопку переключения, для которого мне нужно сделать пользовательский элемент управления, который размещает кнопку переключения, и разместить контент, который описан в этом пользовательском элементе управления.Я сделал небольшое мини-приложение, чтобы продемонстрировать «требование».

<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);
    }

Когда я запускаю приложение, отображается текст, но стиль / кнопка переключения игнорируется / не применяется / что угодно.

enter image description here

Визуальное дерево подтверждает, что я что-то не так делаю:

enter image description here

Я просмотрел много других связанных с этим вопросов и ответов, но до сих пор не знаю, как сделать так, как я хочу.

1 Ответ

0 голосов
/ 08 декабря 2018

Ваш код должен работать, за исключением того, что там не отображаются строки, где должно быть ContentPropertyAttribute.Не могли бы вы убедиться, что у MyUserControl1 определено свойство содержимого, и посмотрите, поможет ли это.

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

Обновление

Ниже приведен полный код, протестированный с Win 10 Pro1803, сборка 17134, NETCore 6.2.2.

Обратите внимание, что вы можете определить шаблон элемента управления либо в UserControl.Resources, либо во внешних ресурсах, чтобы отделить его от «основного» макета пользовательского интерфейса, либо оставить его в 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-конструктора страницы

enter image description here

...