UWP 如何创建托管内容的用户控件?
UWP How to create user control that hosts content?
我在尝试实现一件非常琐碎的事情时感到非常沮丧(或者至少,我期望的事情应该是琐碎的......)
我有一个需要自定义切换按钮的要求,为此我需要制作一个托管切换按钮的用户控件,并托管该用户控件中描述的内容。我制作了一个小型迷你应用程序来演示 "requirement".
<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 问答,但我仍然不知道如何按照我想要的方式让它工作。
您的代码应该可以正常工作,只是在 ContentPropertyAttribute
应该显示的位置没有显示任何行。您能否确保 MyUserControl1
的内容 属性 已被识别,看看是否有帮助。
[ContentProperty(Name = "MainContent")]
public sealed partial class MyUserControl1 : UserControl
...
更新
下面是使用 Win 10 Pro 1803、内部版本 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设计师截图
我在尝试实现一件非常琐碎的事情时感到非常沮丧(或者至少,我期望的事情应该是琐碎的......)
我有一个需要自定义切换按钮的要求,为此我需要制作一个托管切换按钮的用户控件,并托管该用户控件中描述的内容。我制作了一个小型迷你应用程序来演示 "requirement".
<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 问答,但我仍然不知道如何按照我想要的方式让它工作。
您的代码应该可以正常工作,只是在 ContentPropertyAttribute
应该显示的位置没有显示任何行。您能否确保 MyUserControl1
的内容 属性 已被识别,看看是否有帮助。
[ContentProperty(Name = "MainContent")]
public sealed partial class MyUserControl1 : UserControl
...
更新
下面是使用 Win 10 Pro 1803、内部版本 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>