私は BindingSource にバインドされた WinForms DataGridView を持っています。これは、100,000 オブジェクトの BindingList にバインドされています。
BindingList<MyObject> myObjectList = new BindingList<MyObject>();
BindingSource bindingSourceForMyObjects = new BindingSource();
bindingSourceForMyObjects.DataSource = myObjectList;
dataGridViewMyObjects.DataSource = bindingSourceForMyObjects;
次のコードを含む DataGridView の CellValueChanged イベントに接続されたイベント ハンドラーがあります。
dataGridViewMyObjects.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
dataGridViewMyObjects.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.White;
したがって、ユーザーが行を変更すると、このイベント ハンドラーが起動し、行を赤地に白に変更して、データが変更されたことを示します。これはうまく機能しますが、基になるリストをプログラムで変更する必要がある場合もあり、それらの変更を DataGridView にも反映させたいと考えています。これを実現するために、私のオブジェクト クラスは INotifyPropertyChanged を実装し、BindingSource の ListChanged イベントに接続されたイベント ハンドラーを用意しました。そのイベント ハンドラーのコードは次のようになります。
if (e.ListChangedType == ListChangedType.ItemChanged)
{
dataGridViewMyObjects.Rows[e.NewIndex].DefaultCellStyle.BackColor = Color.Red;
dataGridViewMyObjects.Rows[e.NewIndex].DefaultCellStyle.ForeColor = Color.White;
}
これも機能しているため、プログラムで 50 個のオブジェクトを変更すると、DataGridView の行も更新されます。ただし、前に述べたように、100,000 個のオブジェクトを扱っており、800 個を超えるオブジェクトを変更する必要がある場合は、オブジェクトで OnPropertyChanged() をすべて呼び出すため、しばらく時間がかかることがあります。最悪の場合、100,000 個のオブジェクトすべてを変更する必要がある場合、これが発生するまでに 1 分近くかかることがあります。
オブジェクト クラスの内部には、プログラムで「一括」更新 (> 800 オブジェクト) を実行しているときに OnPropertyChanged() 呼び出しのトリガーを回避するために使用するブール変数があります。これにより、オブジェクト プロパティの更新が非常に高速になりますが、双方向バインディングがバイパスされるため、DataGridView 内の対応する行の前色/背景色の値が更新されなくなります。変更されたオブジェクトに対応する行はわかっているので、それらをループして ForeColor/BackColor 値を更新しようとしましたが、この操作が完了するまでに約 1 分かかります。
そのループをラップしてみました...
dataGridViewMyObjects.SuspendLayout();
// loop here
dataGridViewMyObjects.ResumeLayout();
しかし、それはパフォーマンスに違いをもたらすようには見えませんでした。多くの行に対して ForeColor/BackColor を設定するより高速な方法はありますか?それとも、私が見ている速度は、単に私が扱っているデータのサイズの問題ですか?