3

私はCellFormattingイベントに苦労してきました、それはとても遅いです。

私は次のようなDataGridViewを持っています:

ここに画像の説明を入力してください

ヘッダーのチェックボックスをクリックすると起動する関数を作成しました。これにより、すべてのチェックボックスがその列にチェックインされます。

private void checkboxHeader_CheckedChanged(object sender, EventArgs e)
    {
        for (int i = 0; i < dataGridView1.RowCount; i++)
        {
            dataGridView1[0, i].Value = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]).Checked;
        }
        //dataGridView1.EndEdit();
    }  

この関数は、10行の場合は完全に機能しますが、300行の場合は、必要なものがあります...すべてのチェックボックスをオンにするのに9秒の遅延があることがわかりました。 CellFormatingイベントが原因です。

私のCellFormatingイベントコードは次のとおりです。

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {

            DataGridViewCellStyle _myStyle = new DataGridViewCellStyle();
            int index = gdv_row.FindIndex(p => p.log == (string)dataGridView1.Rows[e.RowIndex].Cells[1].Value);
            if (index != -1 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewTextBoxColumn && e.RowIndex != -1)
            {
                //e.CellStyle = _myStyle;
                _myStyle.Font = gdv_row[index].font;
                _myStyle.BackColor = gdv_row[index].backgroundcolor_color;
                _myStyle.ForeColor = gdv_row[index].foregroundcolor_color;
                dataGridView1.Rows[e.RowIndex].Cells[1].Style = _myStyle;
            }
        }

そして私はDataGridViewにDoubleBufferingを使用しました。今、私はこのCellFormattingイベントで何をすべきか分かりません...

4

3 に答える 3

4

すでにSuspendLayout()ResumeLayout ()を試しましたか?

これにより、コントロールのレイアウトロジックが一時的に一時停止されるため、データの入力中にグリッドが再描画されることはありません。

DoubleBufferingを使用する場合でも、グリッドはそれ自体を再描画しますが、それでも低速ではありません。ただし、グリッドにデータを入力しているときにまったく再描画しない場合は、劇的な改善が見られます。

最初の関数は次のようになります。

private void checkboxHeader_CheckedChanged(object sender, EventArgs e)
    {
        dataGridView1.SuspendLayout();

        for (int i = 0; i < dataGridView1.RowCount; i++)
        {
            dataGridView1[0, i].Value = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]).Checked;
        }

        dataGridView1.ResumeLayout();
    }  

[編集1]

コードサンプルを追加しました。

[編集2]DataGridViewCellStyle行の必要な描画を最小限に抑えるには、行ごと に新しいオブジェクトを作成するのではなく、既存のスタイルのプロパティを直接設定してみてください。

    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        int index = gdv_row.FindIndex(p => p.log == (string)dataGridView1.Rows[e.RowIndex].Cells[1].Value);
        if (index != -1 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewTextBoxColumn && e.RowIndex != -1)
        {
            dataGridView1.Rows[e.RowIndex].Cells[1].Style.Font = gdv_row[index].font;
            dataGridView1.Rows[e.RowIndex].Cells[1].Style.BackColor = gdv_row[index].backgroundcolor_color;
            dataGridView1.Rows[e.RowIndex].Cells[1].Style.ForeColor = gdv_row[index].foregroundcolor_color;
        }
    }

最後に、いくつかの解決策を探して、このMSDN記事ドキュメントを見つけました: WindowsフォームDataGridViewコントロールをスケーリングするためのベストプラクティス

[編集3](以下のEhsanのコメントへの回答)

これは、「a」がグリッドに表示される値であり、元の行が重要な作業を行っているためです。*すべての子コントロールを含む目的の値の検索を実行します*見つかった結果を含む配列を作成します*作成しますオブジェクトからチェックボックスへのキャスト*グリッド内のすべての行ごとにこれらすべてを実行します

これにより、DataGridViewにあるアイテムが増えるほど時間がかかることが明らかになります。

私があなたのコードを正しく理解していれば、メソッドを次のように変更するのに役立つはずです。

  CheckBox headerBox = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]);
  for (int i = 0; i < dataGridView1.RowCount; i++)
  {
    dataGridView1[0, i].Value = headerBox.Checked;
  }

これを行うことにより、検索を1回だけ実行します。

于 2012-01-03T12:12:29.637 に答える
0

すべての行をチェックしているときにコントロールのペイントを停止したい場合は、DrawingControlこの投稿のクラスを確認する必要があります:https://stackoverflow.com/questions/487661/...

于 2012-01-03T12:31:17.593 に答える
0

私の場合、問題はDataGridViewプロパティAutoSizeColumnsMode=AllCellsが原因で発生しました。おそらく、セルをフォーマットした後、列とヘッダーのセル内の他のすべてのセルを再描画して、それらの寸法を新しいセルの寸法に合わせる必要がありました。プロパティ値をデフォルト値「なし」に変更した後、グリッドはすぐにペイントされます。

于 2019-08-26T11:28:09.897 に答える