WPF:谈谈INotifyPropertyChanged中获取属性名字符串

一、介绍

在WPF中使用MVVM方式进行数据绑定时需要继承并实现INotifyPropertyChanged接口,当属性的值发生修改时触发PropertyChanged事件的执行,PropertyChanged执行需要传递PropertyChangedEventArgs类型参数,而PropertyChangedEventArgs参数需要一个字符串类型的参数,这个参数就是调用属性的名称。

属性名字符串的获取方式在不断演变,文章列出几种属性名获取的实现方式,希望在开发中对大家有所帮助。

    /// <summary>
    /// Provides data for the <see langword='PropertyChanged'/> event.
    /// </summary>
    public class PropertyChangedEventArgs : EventArgs
    {
        /// <summary>
        /// Initializes a new instance of the <see cref='System.ComponentModel.PropertyChangedEventArgs'/>
        /// class.
        /// </summary>
        public PropertyChangedEventArgs(string? propertyName)
        {
            PropertyName = propertyName;
        }

        /// <summary>
        /// Indicates the name of the property that changed.
        /// </summary>
        public virtual string? PropertyName { get; }
    }

二、第一种

    public class MainViewModel : System.ComponentModel.INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler? PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion INotifyPropertyChanged
    }

这种实现方式是开始学习WPF MVVM时最多使用的,简单直接,属性名字符串用硬编码方式写进代码中,应用方式如下:

    public class MainViewModel : System.ComponentModel.INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler? PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion INotifyPropertyChanged

        bool _isChecked1;
        public bool IsChecked1
        {
            get { return _isChecked1; }
            set { _isChecked1 = value; OnPropertyChanged("IsChecked1"); }
        }
    }

开发者需要在属性的Set方法中将属性名字符串传递到OnPropertyChanged方法,字符串的值必须要和属性名完全一致,多一个空格也会导致失败。这种写法的缺点是容易写错属性名字符串,并且需要修改属性名时还需要开发者手动修改对应的属性名字符串,因此这种实现方式一般不推荐在开发中使用。

三、第二种

    public class MainViewModel : System.ComponentModel.INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler? PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void OnPropertyChanged(Expression<Func<MainViewModel, object>> propertyExpression)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(NameForProperty(propertyExpression)));
        }

        private string NameForProperty<TDelegate>(Expression<TDelegate> propertyExpression)
        {
            Expression body;
            var expression = propertyExpression.Body as UnaryExpression;
            if (expression != null)
                body = expression.Operand;
            else
                body = propertyExpression.Body;

            var member = body as MemberExpression;
            if (member == null)
                throw new ArgumentException("Property must be a MemberExpression");

            return member.Member.Name;
        }
        #endregion INotifyPrope
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值