Question

I'm working with a DataGridView (Windows Forms) with MultiSelect enabled which is placed in a User Control. I'd like to update all selected rows from outside the User Control by calling a public method that implements the following code:

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

Unfortunately, when multiple rows are selected, only one DataGridViewRow is immediately refreshed, namely the one that was last selected. The underlying objects are changed, and the NotifyPropertyChange-event is fired. Moreover, when I change the selection after update, I see all rows updated exactly as I'd like them to be immediately.

Second thing, very strange: When I set a breakpoint in the Setter of the Rating-property where NotifyPropertyChange is fired and wait there a few seconds before continuing code execution, everything works well (all rows are immediately updated). If I don't wait but press F5 very quickly each time the breakpoint is passed, I get the effect described above.

My business object looks like this (significantly shortened of course):

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
}

Has anybody already noticed this behavior too, or even knows a solution (or a workaround)?

Was it helpful?

Solution

If your DGV is bound to a regular List, it only subscribes to the PropertyChanged event for the currently-selected row. Try using a BindingList instead, or calling BindingSource.ResetItem(n) for each item changed.

MSDN gives an example which uses a BindingList and also (pointlessly) calls ResetItem. Play with their example, and you can see that either removing the call to ResetItem, or replacing the BindingList with a regualr List<> will operate as intended.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top