zoukankan      html  css  js  c++  java
  • Freezable 对象(WPF)

    先看下图
    image

    Freezable继承自DependencyObject,同时添加了Freezable方法,用于冻结对象.

    一.冻结对象

    以此为示例

    public class People : Freezable
    {
        public string Name
        {
            get { return (string)GetValue(NameProperty); }
            set { SetValue(NameProperty, value); }
        }
    
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.Register("Name", typeof(string), typeof(People), 
            new UIPropertyMetadata());
    
    
        protected override Freezable CreateInstanceCore()
        {
            throw new NotImplementedException();
        }
    }

    现实生活中,人的名字是不可以随意修改的,作为对象,当名字定下来以后,就把该对象冻结了.那么就不能再修改此对象的属性了,如下
    People entity = new People();
    entity.Name = "Terry";
    entity.Freeze();
    //error
    entity.Name = "Curry";
    在调用Freeze方法后,再次修改Name 会报错

    二.依赖对象与冻结

    当调用Freeze方法后,DependencyObject将成为一个密封类(Saled),一旦DependencyObject成为密封类,那么内部将无法修改依赖属性,
    这也意味着如果定义普通的CLR属性则没有这个问题,在People中添加一个Age属性(人的年龄总是递增的),下面的代码没有问题

    People entity = new People();
    entity.Name = "Terry";
    entity.Freeze(); entity.Age = 1;
    因为Age 并非依赖属性.

    三.冻结状态

    (1)在冻结之前,需要知道该对象是否已经冻结(IsFrozen),当冻结之后IsFrozen为True
    (2)即使继承了Freezable的对象,并非随时都可以冻结,在调用Freeze方法前,需要查看CanFrozen属性判断对象是否可以冻结(如果该对象可以冻结,即使调用Freeze方法后,该属性还是为True),否则会抛错
    (3)冻结后的对象无法解冻,必须采用克隆方法创建一个新的对象.

    四.无法冻结的情况

    1.绑定时.
    当一个dp对象其中有dp有绑定时,无法冻结;当dp解除绑定后则可以(如果进行了绑定就意味着值可能会修改,那么该对象就不是冻结的了)

    People entity = new People();
    BindingOperations.SetBinding(entity, People.NameProperty, new Binding("Name") { Source = entity });
    //first not freeze
    if (entity.CanFreeze)
        entity.Freeze();
    entity.Name = "Terry"; 
    //freeze
    if (entity.CanFreeze)
        entity.Freeze();

    2.Freezable中定义的dp属性类型必须为值类型或者是Freezable类型
    比如在其中定义一个Button类型(非Freezable类型)的dp,当其有值时,则无法冻结

    五.Freezable特性


    1.可子属性变更通知
    现在给People添加一个Skin属性

    public class People : Freezable
    {
        public string Name
        {
            get { return (string)GetValue(NameProperty); }
            set { SetValue(NameProperty, value); }
        }
    
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.Register("Name", typeof(string), typeof(People), 
            new UIPropertyMetadata());
    
        public int Age { get; set; }
    
        public SolidColorBrush Skin
        {
            get { return (SolidColorBrush)GetValue(SkinProperty); }
            set { SetValue(SkinProperty, value); }
        }
    
        public static readonly DependencyProperty SkinProperty =
            DependencyProperty.Register("Skin", typeof(SolidColorBrush), typeof(People), new UIPropertyMetadata(null));
    
        
        protected override Freezable CreateInstanceCore()
        {
            throw new NotImplementedException();
        }
    }

    测试以下代码,将触发两次事件
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        People entity = new People();
        SolidColorBrush brush = new SolidColorBrush();
        entity.Changed += new EventHandler(brush_Changed);
        //execute event
        entity.Skin = brush;
        //execute event
        brush.Color = Colors.Red;
    }
    
    void brush_Changed(object sender, EventArgs e)
    {
    
    }
    2.克隆
    如果定义的属性均为依赖属性
    ,那么克隆就会变的很简单,调用父类方法就行,如
    public SolidColorBrush Clone()
    {
        return (SolidColorBrush) base.Clone();
    }
    3.冻结之后的对象将与UI线程分离
    其会将内部的Dispatcher属性设置为空,这是需要注意的.
    总结:当对象不需要发生改变时,则冻结该对象,减少对象监听,提升性能
  • 相关阅读:
    win7网络共享原来如此简单,WiFi共享精灵开启半天都弱爆了!
    JQUERY UI Datepicker Demo
    Official online document, install svn server in centOS
    JAVE not work in linux
    AMR 转mp3 失败
    XD, XR, DR 股票
    Linux 下MySql 重置密码
    Difinition Of Done
    Apache, Tomcat, JK Configuration Example
    Linux 安装tomcat
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1777328.html
Copyright © 2011-2022 走看看