Question

Je travaille avec un DataGridView (Windows Forms) avec MultiSelect activé, qui est placé dans un contrôle utilisateur. Je souhaite mettre à jour toutes les lignes sélectionnées de l'extérieur du contrôle utilisateur en appelant une méthode publique qui implémente le code suivant:

foreach(DataGridViewRow dr in dataGridView.SelectedRows)
{
    MyBusiness business = (MyBusiness)dr.DataBoundItem;
    business.Rating = 5;
}

Malheureusement, lorsque plusieurs lignes sont sélectionnées, une seule DataGridViewRow est immédiatement actualisée, à savoir celle qui a été sélectionnée en dernier. Les objets sous-jacents sont modifiés et l'événement NotifyPropertyChange est déclenché. De plus, lorsque je modifie la sélection après la mise à jour, toutes les lignes sont mises à jour exactement comme je le souhaiterais.

Deuxième chose très étrange: lorsque je définis un point d'arrêt dans le Setter de la propriété Rating - où NotifyPropertyChange est déclenché et que j'attends quelques secondes avant de poursuivre l'exécution du code, tout fonctionne correctement (toutes les lignes sont immédiatement mises à jour). Si je n'attends pas, mais si vous appuyez très rapidement sur la touche F5 à chaque passage du point d'arrêt, j'obtiens l'effet décrit ci-dessus.

Mon objet métier se présente comme suit (considérablement raccourci bien sûr):

public class MyBusiness : INotifyPropertyChanged
{
    private int _rating;
    public int Rating
    {
        get { return _rating; }
        set
        {
            if(_rating != value)
            {
                _rating = value;
                NotifyPropertyChanged("Rating");
            }
        }
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;

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

Quelqu'un at-il déjà remarqué ce comportement ou connaît même une solution (ou une solution de contournement)?

Était-ce utile?

La solution

Si votre DGV est lié à une liste normale, il ne souscrit qu'à l'événement PropertyChanged de la ligne actuellement sélectionnée. Essayez plutôt d’utiliser une BindingList ou d’appeler BindingSource.ResetItem (n) pour chaque élément modifié.

MSDN donne un exemple qui utilise BindingList et également ( inutilement) appelle ResetItem. Jouez avec leur exemple, et vous pouvez constater que l’appel de ResetItem est supprimé ou la BindingList remplacée par une liste régualr & Lt; & Gt; fonctionnera comme prévu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top