2012-03-18 29 views
14

tengo una lista de objetosC# DataGridView no se actualiza al origen de datos se cambia

List<MobilePhone> results; 

por lo que añade la lista para el DataGridView

dataGridView.DataSource = phase3Results; 

así que tengo unas cuantas cajas desplegables que dictan la lista resultados en cualquier cambio de elemento seleccionado en los cuadros desplegables, por lo que mi lista resultados cambios, pero en la vista de cuadro de datos no se refleja. ¿Hay alguna forma de "actualizar" los cambios?

Respuesta

32

solución rápida y sucia:

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

solución limpia y correcta:

Utilice un BindingList<T> en lugar de List<T> como su fuente de datos. List<T> no activa eventos cuando cambia su colección.

Además, si se implementa, además, INotifyPropertyChanged para T, BindingList<T> suscribe automáticamente a los cambios de propiedades de cada T en la recogida y permite la vista sabe sobre el cambio.

+1

Si bien esto probablemente funciona, tendrá que volver a dibujar toda la red, perjudicando el rendimiento si tiene una gran cantidad de filas/columnas. –

+0

¿No es el objetivo repoblar la cuadrícula porque el conjunto de resultados ha cambiado? – Kevin

+0

¿Se puede lograr esto cuando DataGridView está vinculado a DataPropertyName de una clase? si es así, ¿cómo se puede lograr? –

2

Debe implementar la interfaz INotifyPropertyChanged en el objeto que está almacenando los datos. Cada propiedad debe plantear ese evento durante la llamada establecida de una propiedad si el valor cambió. Entonces la grilla recibirá automáticamente la actualización.

12

Trate de usar un BindingList <> en lugar de Lista <> y (como ya se ha sugerido por Daniel), implementar INotifyPropertyChanged. Sin embargo, creo que también puede llamar a .Refesh() si no desea implementar la interfaz INotifyPropertyChanged.

He aquí un ejemplo arrancado de 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() solo redibujará el área del cliente (pintura) y no volverá a enlazar los datos. –

Cuestiones relacionadas