質問

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;に置き換えることがわかります。意図したとおりに動作します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top