C# wpf 依赖属性、路由事件

一、依赖属性

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值