You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3如何将自定义Button UserControl转为原生Button并复用其事件

解决方案

方式一:直接继承原生Button(推荐)

不需要用UserControl包裹,直接创建自定义Button类继承Microsoft.UI.Xaml.Controls.Button,天然拥有原生Button的所有属性(包括Background)和事件(包括Click),完全匹配你的需求:

代码示例

using Microsoft.UI.Xaml.Controls;

namespace MyControls
{
    public sealed class CustomButton : Button
    {
        public CustomButton()
        {
            // 可添加自定义初始化逻辑,比如默认样式、额外功能
            this.DefaultStyleKey = typeof(Button); // 保留原生Button样式,也可替换为自定义样式
        }

        // 如需扩展自定义属性或方法,直接在此添加即可
    }
}

主页面XAML使用:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mycontrols="using:MyControls">

    <mycontrols:CustomButton Click="Test_Click" Background="Red" Content="自定义按钮"/>
</Page>

后台事件处理:

private void Test_Click(object sender, RoutedEventArgs e)
{
    var btn = sender as Button;
    if (btn != null)
    {
        btn.Background = new SolidColorBrush(Colors.Green);
    }
}

方式二:基于UserControl改造(需保留内部原生Button结构时使用)

如果因为布局需求必须用UserControl包裹原生Button,需完成以下两步:

1. 绑定属性并转发事件

在UserControl后台代码中定义与原生Button一致的Background依赖属性,绑定到内部Button的对应属性,同时转发内部Button的Click事件:

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;

namespace MyControls
{
    public sealed partial class CustomButtonUserControl : UserControl
    {
        public CustomButtonUserControl()
        {
            this.InitializeComponent();
            // 绑定内部Button的Background到自定义控件的Background属性
            MyButton.SetBinding(Button.BackgroundProperty, new Binding
            {
                Source = this,
                Path = new PropertyPath(nameof(Background)),
                Mode = BindingMode.TwoWay
            });
        }

        // 定义Background依赖属性,与原生Button保持一致
        public Brush Background
        {
            get => (Brush)GetValue(BackgroundProperty);
            set => SetValue(BackgroundProperty, value);
        }

        public static readonly DependencyProperty BackgroundProperty =
            DependencyProperty.Register(nameof(Background), typeof(Brush), typeof(CustomButtonUserControl), new PropertyMetadata(null));

        // 转发内部Button的Click事件
        public event RoutedEventHandler Click;

        private void MyButton_Click(object sender, RoutedEventArgs e)
        {
            // 触发自定义控件的Click事件,sender传入当前UserControl实例
            Click?.Invoke(this, e);
        }
    }
}

2. UserControl的XAML布局

<UserControl
    x:Class="MyControls.CustomButtonUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Button x:Name="MyButton" Click="MyButton_Click" Content="自定义按钮"/>
</UserControl>

主页面使用方式

和原生Button完全一致:

<mycontrols:CustomButtonUserControl Click="Test_Click" Background="Blue"/>

后台事件处理:

private void Test_Click(object sender, RoutedEventArgs e)
{
    var customBtn = sender as CustomButtonUserControl;
    if (customBtn != null)
    {
        customBtn.Background = new SolidColorBrush(Colors.Yellow);
    }
}

关键说明

  • 方式一的继承方案最简洁,完全复用原生Button的所有特性,无需额外属性转发和事件处理,优先推荐。
  • 方式二适合需要在Button周围添加额外UI元素(如图标、标签)的场景,通过属性绑定和事件转发,让自定义UserControl表现得和原生Button一致。

内容的提问来源于stack exchange,提问作者holycreeper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:43:18