2

フォームに を実装DataGridViewし、 を正常に実装しましたVirtualMode。これにより、ローカルキャッシュからセルデータが取得され、グリッド/ページングなどにデータを入力するときにすべてが正しく機能しているように見えますDataGridView.CellValueNeeded。イベントを処理してセルにデータを入力します。

DataGridView で、AutoSizeColumnsModeプロパティを に設定していDataGridViewAutoSizeColumnsMode.DisplayedCellsます。VirtualMode を使用すると、セルにデータを入力した後、DataGridView が AutoSizeColumnsMode を尊重していないように見えることに気付きました。この記事を調べましたが、解決策が見つかりませんでした。

私が最終的にやりたいのは、AutoSizeColumnsModeプロパティに依存するのではなく、.AutoResizeColumn()メソッドをどこかで呼び出してサイズを変更することです。そのため、最初は列のサイズを自動調整しますが、ユーザーがサイズを変更できるようにします。

私は次のことを試しましたが、限定的またはまったく成功しませんでした:

  1. に設定DataGridView.AutoSizeColumnsMode.Noneます。次に、私の .CellValueNeededハンドラーで

    private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        // ... Get cell value from cache
       dataGridView.AutoResizeColumn(e.ColumnIndex, DataGridViewAutoSizeColumnMode.DisplayedCells);
     }
    

    StackOverFlowExceptionこれは、おそらく を繰り返し発生させるため、 をスローし.CellValueNeededます。

  2. .CellFormatting イベントハンドラーを除いて、まったく同じことを試しました。同じを得た StackOverFlowException

  3. ありとなしで試しましたDataGridView.SuspendLayout/ResumeLayout

    private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        // ... Get cell value from cache
       dataGridView.CellValueNeeded -= dataGridView_CellValueNeeded;
       dataGridView.AutoResizeColumn(e.ColumnIndex, DataGridViewAutoSizeColumnMode.DisplayedCells);
       dataGridView.CellValueNeeded += dataGridView_CellValueNeeded;
    }
    

    これにより、すべてのセルが空白になるため、使用できません。

  4. これは実際にはある程度機能しますが、理由はわかりません:

    private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        // ... Get cell value from cache
        dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
    }
    

    列のサイズを正しく変更しますが、必要なすべてのセル値に対して繰り返し呼び出す必要があるのは奇妙に思えます。また、すぐに .None に設定することはできませんStackOverFlowException。したがって、ユーザーが列のサイズを変更できるようにすることはできません。

  5. .UpdateCellValue()私のハンドラーからの記事で述べたように呼び出すと、同様に.CellValueNeededスローStackOverFlowExceptionされます。

では、オーバーフローするまで発生し.AutoResizeColumn()ない場所を呼び出すことは可能ですか? .CellValueNeeded#4には自動サイズ機能を実行する機能があるように見えるので、どこかから手動で呼び出すこともできるようです。

4

2 に答える 2

2

これが解決策かもしれないと思いますが、他の人の意見を聞くことにまだ興味があります。

によって提起された他のイベントのいくつかを引き続き調べたDataGridViewところ、イベントが見つかりました.RowPostPaint。次のハンドラーを作成しました。

private void dataGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    if (dataGridView.AllowUserToResizeColumns) //So not to run unnecessarily
    {
        return;
    }
    var lastIndex = dataGridView.Rows.GetLastRow(DataGridViewElementStates.Displayed);
    if (e.RowIndex == lastIndex) //Only do on the last displayed row
    {
        dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
        dataGridView.AllowUserToResizeColumns = true;  // User has control from here on
    }
}

これにより、最初のデータロード時に列の自動サイズ変更が行われ、ユーザーはそこからサイズを変更できます。これは一度だけ行うため、必要なすべてのセル値よりもはるかに優れています。dataGridView.AllowUserToResizeColumns = false初期データ読み込みの前に設定する必要があります。

これは法案に合っているようです。ユーザーは初期ロード時に適切に適合する列を確認し、そこから微調整できます。ほとんどのデータは行ごとに同等の長さであるため、ほとんどの場合、その後はスペースを切り捨てたり無駄にしたりしないでください。

于 2012-03-05T02:32:43.203 に答える