更改数据源时 C# DataGridView 未更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9758577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 08:44:32  来源:igfitidea点击:

C# DataGridView not updated when datasource is changed

c#winforms

提问by edelweiss

I have a list of object

我有一个对象列表

List<MobilePhone> results;

so i added the list to the datagridview

所以我将列表添加到 datagridview

dataGridView.DataSource = phase3Results;

so i have a few dropdown boxes which dictate the list results at any change of selected item in the dropdown boxes, so my list results changes, but on the datagridview its not reflected. is there any way to "refresh" the changes?

所以我有几个下拉框,它们在下拉框中选定项目的任何更改时指示列表结果,所以我的列表结果发生了变化,但在 datagridview 上它没有反映。有什么方法可以“刷新”更改吗?

采纳答案by Saeb Amini

Quick and dirty solution:

快速而肮脏的解决方案

dataGridView.DataSource = null;
dataGridView.DataSource = phase3Results;

Clean and correct solution:

清洁和正确的解决方案

Use a BindingList<T>instead of List<T>as your DataSource. List<T>does not fire events when its collection changes.

使用BindingList<T>代替List<T>作为您的数据源。List<T>当其集合更改时不会触发事件。

Also, if you additionally implement INotifyPropertyChangedfor T, BindingList<T>automatically subscribes to property changes for each Tin the collection and lets the view know about the change.

此外,如果您另外实现INotifyPropertyChangedfor T,则BindingList<T>自动订阅T集合中每个属性的更改,并让视图知道更改。

回答by Daniel Lorenz

You need to implement the INotifyPropertyChanged interface on the object that is storing the data. Each property needs to raise that event during the set call of a property if the value changed. Then the grid will automatically get the update.

您需要在存储数据的对象上实现 INotifyPropertyChanged 接口。如果值更改,则每个属性都需要在属性的 set 调用期间引发该事件。然后网格将自动获取更新。

回答by Chris Gessler

Try using a BindingList<> instead of List<> and (as already suggested by Daniel), implement INotifyPropertyChanged. However, I think you can also call .Refesh() if you didn't want to implement the INotifyPropertyChanged interface.

尝试使用 BindingList<> 而不是 List<> 并且(正如 Daniel 已经建议的那样),实现 INotifyPropertyChanged。但是,如果您不想实现 INotifyPropertyChanged 接口,我认为您也可以调用 .Refesh() 。

Here's an example ripped from here

这是从这里撕下的一个例子

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

_dgCars.AutoGenerateColumns = false;

DataGridViewTextBoxColumn makeColumn = new DataGridViewTextBoxColumn();
 makeColumn.DataPropertyName = "Make";
 makeColumn.HeaderText = "The Car's Make";

DataGridViewTextBoxColumn modelColumn = new DataGridViewTextBoxColumn();
 modelColumn.DataPropertyName = "Model";
 modelColumn.HeaderText = "The Car's Model";

DataGridViewTextBoxColumn yearColumn = new DataGridViewTextBoxColumn();
 yearColumn.DataPropertyName = "Year";
 yearColumn.HeaderText = "The Car's Year";

_dgCars.Columns.Add(makeColumn);
 _dgCars.Columns.Add(modelColumn);
 _dgCars.Columns.Add(yearColumn);

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

_dgCars.DataSource = cars;