1

ユーザーコントロールに配置されたマルチセレクトが有効になっているDataGridView(Windowsフォーム)を使用しています。次のコードを実装するパブリック メソッドを呼び出して、ユーザー コントロールの外部から選択したすべての行を更新したいと思います。

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

残念ながら、複数の行が選択された場合、DataGridViewRowすぐに更新されるのは 1 つ、つまり最後に選択された行だけです。基礎となるオブジェクトが変更され、NotifyPropertyChange イベントが発生します。さらに、更新後に選択を変更すると、すべての行がすぐに更新されたように正確に更新されます。

2 つ目は、非常に奇妙です: RatingNotifyPropertyChange が発生する -property の Setter にブレークポイントを設定し、コードの実行を続行する前に数秒待機すると、すべてが正常に機能します (すべての行がすぐに更新されます)。待たずに、ブレークポイントを通過するたびに 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
}

誰かがすでにこの動作に気付いているか、解決策 (または回避策) を知っていますか?

4

1 に答える 1

2

DGV が通常のリストにバインドされている場合、現在選択されている行の PropertyChanged イベントのみをサブスクライブします。代わりに BindingList を使用するか、変更された項目ごとに BindingSource.ResetItem(n) を呼び出してみてください。

MSDN は、BindingList を使用し、(無意味に) ResetItem を呼び出す例を示しています。彼らの例を試してみると、ResetItem への呼び出しを削除するか、BindingList を通常の List<> に置き換えると、意図したとおりに動作することがわかります。

于 2009-06-10T05:16:28.843 に答える