WPF中的依赖属性
1.创建项目后下载两个NuGet程序包
2.创建一个MyButton类继承Button
MyButton类如下:
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代码如下:
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代码如下:
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);
}
}
}
结果如下: