zoukankan      html  css  js  c++  java
  • WPF开发进阶

    前一篇 简单的介绍了Fody/PropertyChanged的使用方法, 这一篇,我们详细介绍它的一些比较重要的特性和规则

    1. Attributes

    通过在类或属性上标记这些特性,可以在编译代码时,注入特定的功能

    ImplementPropertyChangedAttribute

    为类标记此特性,可以实现INotifyPropertyChanged接口

    [ImplementPropertyChanged]
    public class Person 
    {
        public string Name { get; set; }
    }
    

    AlsoNotifyForAttribute

    在实现通知时,也同时通知其它属性

    public class Person : INotifyPropertyChanged
    {
       [AlsoNotifyFor("FullName")]
       public string GivenName { get; set; }
    
       [AlsoNotifyFor("FullName")]
       public string FamilyName { get; set; }
    
       public event PropertyChangedEventHandler PropertyChanged;
    
       public string FullName { get; set; }
    }
    

    在GivenName或FamilyName变化时,会同时也通知FullName的变化

    DoNotNotifyAttribute

    顾名思义,就是在编译时,不在此属性中注入变化通知的代码

    public class Person : INotifyPropertyChanged
    {
       public string GivenName { get; set; }
       [DoNotNotify]
       public string FamilyName { get; set; }
       public event PropertyChangedEventHandler PropertyChanged;
    }
    

    DependsOnAttribute

    设置一个属性,在它依赖的属性变化时,通知此属性发生变化

    public class Person : INotifyPropertyChanged
    {
        public string GivenName { get; set; }
    
        public string FamilyName { get; set; }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        [DependsOn("GivenName","FamilyName")]
        public string FullName { get; set; }
    }
    

    DoNotSetChangedAttribute

    通过约定,在实现的类里,如果有一个属性是IsChanged

     public bool IsChanged { get; set; }
    

    在其它类发生变化时,此类的值会自动被设置为True,

    如果希望在某个属性变化时,不响应此规则,可以将属性标记为DoNotSetChangedAttribute

    public class Person: INotifyPropertyChanged
    {
        [DoNotSetChanged]
        public string FullName { get; set; }
        public bool IsChanged { get; set; }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    在FullName变化里,不会将IsChanged设置为True

    DoNotCheckEqualityAttribute

    默认情况下,所有注入的变化响应,都会检查是否相等,如果相等,则不会进行通知;但在某些时候,我们也许需要无论是否相等都进行通知,这个时候,可以在属性上标记DoNotCheckEqualityAttribute以跳过是否相等的检查

    public class Person: INotifyPropertyChanged
    {
       [DoNotCheckEquality]
       public string FullName { get; set; }
       public bool IsChanged { get; set; }
    
       public event PropertyChangedEventHandler PropertyChanged;
    }
    

    这样,在给FullName赋值时,无论是否和之前的值相等,都会进行通知。

    2. BeforeAfter

    有时候,我们需要在值发生变化时,访问变化之前和之后的值,比如做验证时,我们可以通过加入下面的方法实现:

    public void OnPropertyChanged(string propertyName, object before, object after)

    比如,我们写的代码:

    public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public string Name { get; set; }
    
        public void OnPropertyChanged(string propertyName, object before, object after)
        {
            //Perform property validation
            var propertyChanged = PropertyChanged;
            if (propertyChanged != null)
            {
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    在编译时,对应的代码为:

    public class Person : INotifyPropertyChanged
    {
        private string name;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public string Name
        {
            get { return name; }
            set
            {
                object before = Name;
                name = value;
                OnPropertyChanged("Name", before, Name);
            }
        }
    
        public void OnPropertyChanged(string propertyName, object before, object after)
        {
            //Perform property validation
            var propertyChanged = PropertyChanged;
            if (propertyChanged != null)
            {
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    3. EqualityChecking

    在设置属性的值之前,会进行是否相等的检查:

    public string Property1
    {
        get
        {
            return property1;
        }
        set
        {
            if (!String.Equals(property1, value))
            {
                property1 = value;
                OnPropertyChanged("Property1");
            }
        }
    }
    

    用于检查是否相等的方法依赖于属性的数据类型,按照下面的顺序或规则进行比较:

    • 如果类型是Nullable,则使用 Nullable.Equals(T?,T?)方法比较
    • 如果类型包含有静态的方法Equals,则使用静态的方法对比两个参数
    • 如果类型有==方法,则使用==比较参数
    • 使用Object.Equals(object,object)比较

    4.实现IsChanged标志

    在上面我们已经简单的介绍了IsChanged属性,具体的实现代码如下:

    • 书写的代码
    public class Person : INotifyPropertyChanged
    {
      public string Name { get; set; }
      public event PropertyChangedEventHandler PropertyChanged;
      public bool IsChanged { get; set; }
    }
    
    • 编译对应的代码 (省略比较的代码
    public class Person : INotifyPropertyChanged
    {
      string name;
      bool isChanged;
      public event PropertyChangedEventHandler PropertyChanged;
    
      public virtual void OnPropertyChanged(string propertyName)
      {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
          propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
      }
    
      public string Name
      {
        get { return name; }
        set
        {
          name = value;
          IsChanged = true;
          OnPropertyChanged("Name");
        }
      }
    
      public bool IsChanged 
      {
        get { return isChanged; }
        set
        {
          isChanged = value;
          OnPropertyChanged("IsChanged");
        }
      }
    }
    

    这样,在Name设置新值后,IsChanged属性会被设置为True

    当然,在代码逻辑中,在适当的时候需要手动将IsChanged设置为false

    还有一些配置和规则,可以参见https://github.com/Fody/PropertyChanged/wiki

  • 相关阅读:
    Spring Boot 详细简介
    Linux 安装 MySQL 8 数据库(图文详细教程)
    有了这个日期工具类,让日期转化不再烦恼
    Linux常用实用命令
    Java分割中英文,并且中文不能分割一半?
    Spring MVC或Spring Boot配置默认访问页面不生效?
    js如何判断当前页面是否处于激活状态
    博客园 & 陌上花开HIMMR | 脱单倒计时!只能帮你到这了
    博客园 & 陌上花开HIMMR | 距2020年脱单,只剩34天!
    博客园 & 陌上花开HIMMR | 脱单倒计时!刚过完10.24的你,还想一个人过11.11吗?
  • 原文地址:https://www.cnblogs.com/cqgis/p/6360302.html
Copyright © 2011-2022 走看看