DataGridViewで複数の選択されたINofityPropertyChangeオブジェクトを更新する
-
03-07-2019 - |
質問
DataGridView
で作業しています(Windowsフォーム)(ユーザーコントロールに配置されたMultiSelectが有効)。次のコードを実装するパブリックメソッドを呼び出して、ユーザーコントロールの外部から選択したすべての行を更新したいと思います。
foreach(DataGridViewRow dr in dataGridView.SelectedRows)
{
MyBusiness business = (MyBusiness)dr.DataBoundItem;
business.Rating = 5;
}
残念ながら、複数の行が選択された場合、ただ1つのDataGridViewRow
、つまり最後に選択された行だけがすぐに更新されます。基礎となるオブジェクトが変更され、NotifyPropertyChangeイベントが発生します。さらに、更新後に選択を変更すると、すべての行がすぐに更新されるように正確に更新されます。
2番目の非常に奇妙なこと:NotifyPropertyChangeが発生するRating
プロパティのセッターにブレークポイントを設定し、コードの実行を続行する前に数秒間待機すると、すべてが正常に機能します(すべての行がすぐに更新されます)。待機せずにブレークポイントを通過するたびにF5キーを非常にすばやく押すと、上記の効果が得られます。
ビジネスオブジェクトは次のようになります(もちろん大幅に短縮されます):
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
}
この動作に既に気付いている人、または解決策(または回避策)を知っている人もいますか?
解決
DGVが通常のリストにバインドされている場合、現在選択されている行のPropertyChangedイベントのみをサブスクライブします。代わりにBindingListを使用するか、変更された各アイテムに対してBindingSource.ResetItem(n)を呼び出してみてください。
MSDNは例を示します BindingListと(無意味に)ResetItemを呼び出します。それらの例を再生すると、ResetItemの呼び出しを削除するか、BindingListを通常のList <!> lt; <!> gt;に置き換えることがわかります。意図したとおりに動作します。