当前位置 博文首页 > OneByOneDotNet:Fody,告别烦人的INotifyPropertyChanged,最简

    OneByOneDotNet:Fody,告别烦人的INotifyPropertyChanged,最简

    作者:OneByOneDotNet 时间:2021-01-30 11:36

    Fody,告别烦人的INotifyPropertyChanged,最简方式实现通知!

    INotifyPropertyChanged

    我不是针对谁,我是说在座的各位

    相信所有学wpf的,都写过类似下面的代码:
    实现INotifyPropertyChanged

    public class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    调用

    
        private string _userName = string.Empty;
        /// <summary>
        ///     用户名
        /// </summary>
        public string UserName
        {
          get => _userName;
          set
        {
          _userName = value;
          OnPropertyChanged();
        }
      }
    

    当属性多起来时,这就很烦人了····
    于是乎,我们的PropertyChanged.Fody就登场了

    通过nuget安装PropertyChanged.Fody

    这是一个附加组件库。我们可以通过nuget安装,也可以通过在程序包管理控制台输入以下内容:

    PM> Install-Package Fody
    PM> Install-Package PropertyChanged.Fody
    

    手动添加FodyWeavers.xml文件

    安装完成后,我们需要手动添加名为FodyWeavers.xml的文件,右键项目添加项选择xml文件即可。
    注:该文件是Fody配置文件,更多信息请参考配置
    如果仅仅实现通知,我们只需要在文件内添加一下内容

    <Weavers>
      <PropertyChanged/>
    </Weavers>
    

    完成以上操作后,所有实现 INotifyPropertyChanged 的类都将通知代码注入到属性设置器中。
    例如:

    public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        
        public string GivenNames { get; set; }
        public string FamilyName { get; set; }
        public string FullName => $"{GivenNames} {FamilyName}";
    }
    

    在编译后就会成为:

    public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        string givenNames;
        public string GivenNames
        {
            get => givenNames;
            set
            {
                if (value != givenNames)
                {
                    givenNames = value;
                    OnPropertyChanged(InternalEventArgsCache.GivenNames);
                    OnPropertyChanged(InternalEventArgsCache.FullName);
                }
            }
        }
    
        string familyName;
        public string FamilyName
        {
            get => familyName;
            set 
            {
                if (value != familyName)
                {
                    familyName = value;
                    OnPropertyChanged(InternalEventArgsCache.FamilyName);
                    OnPropertyChanged(InternalEventArgsCache.FullName);
                }
            }
        }
    
        public string FullName => $"{GivenNames} {FamilyName}";
    
        protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
        {
            PropertyChanged?.Invoke(this, eventArgs);
        }
    }
    
    internal static class InternalEventArgsCache
    {
        internal static PropertyChangedEventArgs FamilyName = new PropertyChangedEventArgs("FamilyName");
        internal static PropertyChangedEventArgs FullName = new PropertyChangedEventArgs("FullName");
        internal static PropertyChangedEventArgs GivenNames = new PropertyChangedEventArgs("GivenNames");
    }
    

    特性

    我们自然有些特殊需求,例如我需要更新A属性通知B属性,需要某些属性不通知等等需求。于是Fody给我们提供了标记特性。

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

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

    后记

    本人不是大佬,只是道路先行者,在落河后,向后来的人大喊一声,这里有坑,不要过来啊!

    纵然如此,依旧有人重复着落河,重复着呐喊······


    个人博客网站 Blog

    技术交流Q群: 1012481075 群内有各种流行书籍资料
    在这里插入图片描述

    文章后续会在公众号更新,微信搜索 OneByOneDotNet 即可关注。

    你的一分鼓励,我的十分动力,点赞免费,感恩回馈。喜欢就点赞评论吧,双击66~