未实现 INotifyPropertyChanged 时未反映数据更改

Data change not reflected when INotifyPropertyChanged is not implemented

先看看下面的代码,它工作正常,当我们更新实体时,更改会自动反映在网格中,但是当我评论这个 INotifyPropertyChanged 和所有其他与通知相关的代码时 属性 然后更改网格未得到更改。

所以我想知道INotifyPropertyChanged扮演什么样的角色? INotifyPropertyChanged 如何与网格通信以显示或反映变化? 请帮助我理解 grid and INotifyPropertyChanged 之间的通信。谢谢

namespace PatternSearch
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void btnBindData_Click(object sender, EventArgs e)
        {
            BindingList<Car> cars = new BindingList<Car>();

            cars.Add(new Car("Ford", "Mustang", 1967));
            cars.Add(new Car("Shelby AC", "Cobra", 1965));
            cars.Add(new Car("Chevrolet", "Corvette Sting Ray", 1965));

            dataGridView1.DataSource = cars;
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (dataGridView1.DataSource != null)
            {
                BindingList<Car> cars = dataGridView1.DataSource as BindingList<Car>;
                cars.Where(d => d.Make == "Ford").First().Make = "My Ford000";
            }
            else
                MessageBox.Show("Grid has no data");
        }
    }


    public class Car : INotifyPropertyChanged
    {
        private string _make;
        private string _model;
        private int _year;

        public event PropertyChangedEventHandler PropertyChanged;

        public Car(string make, string model, int year)
        {
            _make = make;
            _model = model;
            _year = year;
        }

        public string Make
        {
            get { return _make; }
            set
            {
                _make = value;
                this.NotifyPropertyChanged("Make");
            }
        }

        public string Model
        {
            get { return _model; }
            set
            {
                _model = value;
                this.NotifyPropertyChanged("Model");
            }
        }

        public int Year
        {
            get { return _year; }
            set
            {
                _year = value;
                this.NotifyPropertyChanged("Year");
            }
        }

        private void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

这是我评论 INotifyPropertyChanged 及其所有相关代码的代码

namespace PatternSearch
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void btnBindData_Click(object sender, EventArgs e)
        {
            BindingList<Car> cars = new BindingList<Car>();

            cars.Add(new Car("Ford", "Mustang", 1967));
            cars.Add(new Car("Shelby AC", "Cobra", 1965));
            cars.Add(new Car("Chevrolet", "Corvette Sting Ray", 1965));

            dataGridView1.DataSource = cars;
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (dataGridView1.DataSource != null)
            {
                BindingList<Car> cars = dataGridView1.DataSource as BindingList<Car>;
                cars.Where(d => d.Make == "Ford").First().Make = "My Ford000";
            }
            else
                MessageBox.Show("Grid has no data");
        }
    }


    public class Car //: INotifyPropertyChanged
    {
        private string _make;
        private string _model;
        private int _year;

        //public event PropertyChangedEventHandler PropertyChanged;

        public Car(string make, string model, int year)
        {
            _make = make;
            _model = model;
            _year = year;
        }

        public string Make
        {
            get { return _make; }
            set
            {
                _make = value;
                //this.NotifyPropertyChanged("Make");
            }
        }

        public string Model
        {
            get { return _model; }
            set
            {
                _model = value;
                //this.NotifyPropertyChanged("Model");
            }
        }

        public int Year
        {
            get { return _year; }
            set
            {
                _year = value;
                //this.NotifyPropertyChanged("Year");
            }
        }

        private void NotifyPropertyChanged(string name)
        {
            //if (PropertyChanged != null)
            //    PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

网格检查对象是否实现了 INotifyPropertyChanged。如果是,它会订阅 PropertyChanged 事件(该接口的唯一成员),以获知已更改值的属性的名称。

更好的 NotifyPropertyChanged 实现是:

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var handler = PropertyChanged;
    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

和 属性 看起来像:

public int Year
{
    get { return _year; }
    set
    {
        _year = value;
        OnPropertyChanged();
    }
}

这样,代码对 属性 名称重构的 bug 证明会更多。