2012-03-18 14 views
14

Mam listę obiektówC# DataGridView nie są aktualizowane, gdy źródło danych jest zmieniana

List<MobilePhone> results; 

więc dodałem listę do DataGridView

dataGridView.DataSource = phase3Results; 

więc mam kilka pól rozwijanych, które dyktują listę wyniki przy każdej zmianie wybranego elementu w rozwijanych polach, więc wyniki mojej listy zmieniają się, ale na datagridview jej nie odzwierciedlono. czy istnieje sposób na "odświeżenie" zmian?

Odpowiedz

32

Szybki i brudny roztwór:

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

Czyste i poprawne rozwiązanie:

Użyj BindingList<T> zamiast List<T> jako DataSource. List<T> nie wywołuje zdarzeń, gdy zmienia się jego kolekcja.

Ponadto, jeśli dodatkowo wdrożyć INotifyPropertyChanged dla T, BindingList<T> automatycznie subskrybuje zmian własności dla każdego T w kolekcji i umożliwia wgląd wiedzieć o tej zmianie.

+1

Chociaż prawdopodobnie działa, będzie musiał przerysować całą siatkę, rani wydajność, jeśli masz dużo wierszy/kolumn. –

+0

Czy celem nie jest ponowne wypełnienie siatki, ponieważ zestaw wyników się zmienił? – Kevin

+0

Czy można to osiągnąć, gdy DataGridView jest powiązany z DataPropertyName klasy? jeśli tak, to jak można to osiągnąć? –

2

Musisz zaimplementować interfejs INotifyPropertyChanged na obiekcie przechowującym dane. Każda właściwość musi podnieść to zdarzenie podczas ustawionego wywołania właściwości, jeśli wartość została zmieniona. Następnie siatka automatycznie otrzyma aktualizację.

12

Spróbuj użyć BindingList <> zamiast listy <> i (jak już zasugerował Daniel), zaimplementuj INotifyPropertyChanged. Jednak myślę, że możesz również wywołać funkcję .Refesh(), jeśli nie chcesz implementować interfejsu INotifyPropertyChanged.

Oto przykład zgrane z 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; 
+0

.Refresh() tylko przerysuje obszar klienta (farba) i nie będzie ponownie wiązać danych. –

Powiązane problemy