WPF中的依赖属性

1.创建项目后下载两个NuGet程序包

2.创建一个MyButton类继承Button

MyButton类如下:

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WPF练习15依赖属性
{
    public class MyButton : Button
    {
        // 普通属性
        //public int CornerRadius { get; set; }

        // 依赖属性的包装器:其实就是一个普通属性
        // 依赖属性需要使用普通属性包装起来。
        public CornerRadius CornerRadius
        {
            get
            {
                return (CornerRadius)GetValue(CornerRadiusProperty);
            }
            set
            {
                SetValue(CornerRadiusProperty, value);
            }
        }

        /*
        a、依赖属性所属的类必须继承至DependencyObject类,
        b、依赖属性的声明开头默认 public static readonly,
        c、依赖属性的命名以Property结尾,建议:包装器名称+Property
        d、使用DependencyProperty.Register静态方法注册。
        e、Register方法的三个参数(1、依赖属性包装器的名字,2、依赖属性保存值得类型,3、指明依赖属性的宿主类型)*/
        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register(
                "CornerRadius",
                typeof(CornerRadius),
                typeof(MyButton),
                new PropertyMetadata(default(CornerRadius), CornerRadiusPropertyCallback));

        // 当CornerRadiusProperty依赖属性发生变化时,处理一些业务逻辑
        // d依赖对象,此依赖属性属于哪个控件?MyButton
        private static void CornerRadiusPropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            MyButton button = (MyButton)d;
            button.Content = e.NewValue.ToString();
        }


        // 普通属性
        private Brush myBackground;
        public Brush MyBackground
        {
            get { return myBackground; }
            set
            {
                myBackground = value;
                OnBackgroundChanged();
            }
        }
        // 普通事件
        public event EventHandler BackgroundChanged;
        private void OnBackgroundChanged()
        {
            BackgroundChanged?.Invoke(this, EventArgs.Empty);
        }

        // 路由事件:  公开静态只读的 public static readonly,这一点和依赖属性类似
        // 需要使用RoutedEvent来定义
        public static readonly RoutedEvent MyClickEvent = EventManager.RegisterRoutedEvent(
            "MyClick",
             RoutingStrategy.Bubble,  // 使用的路由策略:冒泡(从内层元素向外层元素执行)  直连(只执行本元素), 隧道(捕获,挖洞)
                                      // 路由事件使用的委托类型RoutedEventHandler public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);
             typeof(RoutedEventHandler),
             typeof(MyButton));

        // 路由事件的包装器,用一个普通事件来包装一下路由事件。
        public event RoutedEventHandler MyClick
        {
            add { AddHandler(MyClickEvent, value); }  // 添加事件
            remove { RemoveHandler(MyClickEvent, value); }  // 移除事件
        }

        // 设置一下MyClick事件的执行时机,在点击的执行
        // 调用MyBackground1ChangedEvent
        protected override void OnClick()
        {
            // 路由事件的参数对象。是哪一个路由事件的参数呢?RoutedEvent = MyClickEvent
            RoutedEventArgs e = new RoutedEventArgs()
            {
                RoutedEvent = MyClickEvent,
            };
            this.RaiseEvent(e);  // 触发路由事件MyClickEvent
        }
    }
}

3.创建MainWindowViewModel

MainWindowViewModel代码如下:

cs 复制代码
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WPF练习15依赖属性.ViewModels
{
    public class MainWindowViewModel: ObservableObject
    {
        private CornerRadius cornerRadius = new CornerRadius(10);
        public CornerRadius CornerRadius
        {
            get { return cornerRadius; }
            set { SetProperty(ref cornerRadius, value); }
        }
    }
}

MainWindow.xaml.cs代码如下:

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF练习15依赖属性
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void myButton_BackgroundChanged(object sender, EventArgs e)
        {
            MyButton myButton = (MyButton)sender;
            Console.WriteLine("修改了MyBackground属性");
            Console.WriteLine(myButton.MyBackground.ToString());
        }

        private void myButton_MyClick(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(e.RoutedEvent.Name);
        }
    }
}

结果如下:

相关推荐
CodeCraft Studio2 小时前
PDF处理控件Aspose.PDF教程:使用 Python 将 PDF 转换为 Base64
开发语言·python·pdf·base64·aspose·aspose.pdf
零点零一2 小时前
VS+QT的编程开发工作:关于QT VS tools的使用 qt的官方帮助
开发语言·qt
lingchen19065 小时前
MATLAB的数值计算(三)曲线拟合与插值
开发语言·matlab
gb42152875 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
一朵梨花压海棠go5 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
蒋星熠5 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
翻滚丷大头鱼6 小时前
Java 集合Collection—List
java·开发语言
aramae6 小时前
C++ -- 模板
开发语言·c++·笔记·其他
胡耀超6 小时前
4、Python面向对象编程与模块化设计
开发语言·python·ai·大模型·conda·anaconda
索迪迈科技7 小时前
java后端工程师进修ing(研一版 || day40)
java·开发语言·学习·算法