一、依赖属性
1.依赖属性所属的类必须继承至DependencyObject类
2.依赖属性必须是public static readonly,且需要DependencyProperty来定义
3.包装器:依赖属性需要普通属性的包装
4.依赖属性的命名以Property结尾
3.依赖属性支持数据绑定
4.依赖属性与普通属性的区别:
资源绑定:依赖属性支持数据绑定;普通属性不支持
资源管理:依赖属性内部使用哈希表存储机制,对多个相同控件的相同属性的值都只保存一份,从而节约资源;普通属性每次使用都会赋予初始值,消耗更多内存
值传递:依赖属性的值可以通过多个提供者(如动画、父元素、绑定、样式等)决定,并能够及时响应变化;普通属性的值通常由对象自身管理
内存管理:依赖属性在没有使用时不会占用额外内存,因为它可以从其他对象获取值,临时创建内存空间;普通属性则会一直占用内存
二、路由事件
1.路由事件必须是public static readonly,且需要RoutedEvent来定义。
2.包装器:路由事件需要普通事件的包装。
三、案例
路由事件
1.创建一个类存放自定义的控件——MyButton
2.xaml中创建视图
<Window
xmlns:vm="clr-namespace:依赖属性_路由事件.ViewModel"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
WindowStartupLocation="CenterScreen">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<Grid>
<StackPanel HorizontalAlignment="Left">
<local:MyButton
Width="100"
Height="30"
Content="路由事件"
CornerRadius="{Binding MyCornerRadius}"
MyClick="MyButton_MyClick">
<local:MyButton.Template>
<ControlTemplate TargetType="local:MyButton">
<Border Background="Red" CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter RecognizesAccessKey="True" />
</Border>
</ControlTemplate>
</local:MyButton.Template>
</local:MyButton>
</StackPanel>
</Grid>
</Window>
3.MainWindow.xaml.cs中完善点击按钮事件的逻辑
private void MyButton_MyClick(object sender, RoutedEventArgs e)
{
MessageBox.Show(e.RoutedEvent.Name);
}
4. MyButton中填写对控件的定义
public class MyButton : Button
{
//依赖属性的包装器:其实就是一个普通属性
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
//依赖属性
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(
"CornerRadius", //依赖属性包装器的名字
typeof(CornerRadius), //依赖属性保存值得类型
typeof(MyButton), //指明依赖属性的宿主类型
new PropertyMetadata(default(CornerRadius), CornerRadiusPropertyCallback));
//回调
private static void CornerRadiusPropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyButton button = (MyButton)d;
button.Content = e.NewValue.ToString();
}
// 路由事件
public static readonly RoutedEvent MyClickEvent = EventManager.RegisterRoutedEvent(
"MyClick",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MyButton));
// 路由事件的包装器
public event RoutedEventHandler MyClick
{
add { AddHandler(MyClickEvent, value); } // 添加事件
remove { RemoveHandler(MyClickEvent, value); } // 移除事件
}
// 设置一下MyClick事件的执行时机,在点击的执行
protected override void OnClick()
{
// 路由事件的参数对象。是哪一个路由事件的参数呢?RoutedEvent = MyClickEvent
RoutedEventArgs e = new RoutedEventArgs()
{
RoutedEvent = MyClickEvent,
};
this.RaiseEvent(e);
}
}
5.ViewModel视图模型中公开一个私有字段
public class MainViewModel : ObservableObject
{
private CornerRadius myCornerRadius = new CornerRadius(10);
public CornerRadius MyCornerRadius
{
get { return myCornerRadius; }
set { SetProperty(ref myCornerRadius, value); }
}
}