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

结果如下:

相关推荐
Python×CATIA工业智造8 分钟前
Frida RPC高级应用:动态模拟执行Android so文件实战指南
开发语言·python·pycharm
我叫小白菜1 小时前
【Java_EE】单例模式、阻塞队列、线程池、定时器
java·开发语言
狐凄1 小时前
Python实例题:基于 Python 的简单聊天机器人
开发语言·python
weixin_446122462 小时前
JAVA内存区域划分
java·开发语言·redis
悦悦子a啊2 小时前
Python之--基本知识
开发语言·前端·python
QuantumStack3 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法
whoarethenext3 小时前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
代码的奴隶(艾伦·耶格尔)4 小时前
后端快捷代码
java·开发语言
Jay_5154 小时前
C++多态与虚函数详解:从入门到精通
开发语言·c++
路来了5 小时前
Python小工具之PDF合并
开发语言·windows·python