WinUI 3 如何创建可插入外部XAML内容的自定义控件?
WinUI 3 实现支持外部内容注入的自定义控件
方法一:基于 ContentControl 扩展
ContentControl 本身自带 Content 属性,完美匹配你的需求,只需自定义控件模板即可:
- 创建自定义控件类
在项目中新建继承自ContentControl的类:
using Microsoft.UI.Xaml.Controls; namespace YourNamespace { public sealed class MyComponent : ContentControl { public MyComponent() { DefaultStyleKey = typeof(MyComponent); } } }
- 定义控件样式(Generic.xaml)
在项目的Themes/Generic.xaml文件中添加默认样式,把预设样式的 Grid 作为容器,用ContentPresenter做内容占位符:
<Style TargetType="local:MyComponent"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:MyComponent"> <!-- 你预设样式的 Grid --> <Grid Background="#F0F0F0" Padding="10" BorderBrush="Gray" BorderThickness="1"> <!-- 内容占位符,绑定到 ContentControl 的 Content 属性 --> <ContentPresenter Content="{TemplateBinding Content}" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
方法二:在 UserControl 中自定义内容属性
如果习惯用 UserControl 开发,可自行定义依赖属性承载外部内容,再通过 ContentPresenter 绑定:
- UserControl 的 XAML 布局
<UserControl x:Class="YourNamespace.MyComponent" 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:local="using:YourNamespace" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <!-- 你预设样式的 Grid --> <Grid Background="#F0F0F0" Padding="10" BorderBrush="Gray" BorderThickness="1"> <!-- 内容占位符,绑定到自定义的 Content 属性 --> <ContentPresenter Content="{x:Bind Content, Mode=OneWay}" /> </Grid> </UserControl>
- UserControl 后台代码(定义依赖属性)
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; namespace YourNamespace { public sealed partial class MyComponent : UserControl { public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(MyComponent), new PropertyMetadata(null)); public object Content { get => GetValue(ContentProperty); set => SetValue(ContentProperty, value); } public MyComponent() { this.InitializeComponent(); } } }
使用方式
两种方法最终都能按你期望的方式使用:
<local:MyComponent> <!-- 这里放置任意外部 XAML 内容 --> <StackPanel> <TextBlock Text="自定义内容" FontSize="18" /> <Button Content="点击按钮" Margin="0,10,0,0" /> </StackPanel> </local:MyComponent>
补充说明
- 方法一更轻量,ContentControl 本身就是为承载自定义内容设计的,无需额外定义依赖属性。
- 方法二更适合已基于 UserControl 开发的场景,还能扩展多个内容占位符(比如 Header、Body、Footer)。
内容的提问来源于stack exchange,提问作者Clyde
相关产品推荐
相关产品推荐

