DataGridViewを強制的にすべてのセルに対してそのセルフォーマットイベントを発射する方法はありますか?

StackOverflow https://stackoverflow.com//questions/10651702

質問

私達は私達のアプリケーション全体にわたって様々なグリッドのカラーコードセルにセルフォーマットイベントを使用します。

Excelへのエクスポートを処理する一般的なコードを持っています(そして印刷)が白黒でそれを行いました。これを変更してグリッドから色を拾いたい。

この質問&答えは(そしてそれが機能します)...拡張されたより大きなグリッドの問題があることを除いて...単一の画面を超えて。画面にまだ表示されていないグリッドの部分は(論理的に)セルフォーマットコードを発射させることはありませんので、その基礎となる色は設定されません。その結果、Excelでは、カラーコーディングの半分の途中でFizzles。

3つの解決策があるようです:

1)Excelへのエクスポートを行う前に、彼がグリッドのすべての部分までスクロールする必要があると伝えます。 ha!深刻な解決策ではない

2)Excelへのエクスポートを実行する前に、グリッドのすべての部分までプログラム的にスクロールします。 (1) より低く恐ろしいのみ恐ろしい

3)Excelコードへのエクスポートで、上部に何かを発射して、地域全体をペイント/フォーマットするようにDataGridViewに告げる。

  MyDataGridView.FormatAllCells()
.

このようなものをするものはありますか???

ああ、4番目のオプションがありますが、これは既存の既存のコードに触れることを含みます:

4)セルフォーマットイベントの使用を停止し、ロード時間でセルをフォーマットします。これに問題があるのは、CellFormattingが1年のドット以来それを行った方法であるため、アプリケーションですべてのグリッドを再利用する必要があります。

役に立ちましたか?

解決 3

@Davidhallが提案すると、Magic .FormatAllCellsはないと仮定しています。

しかしながら、ここでの新しい問題は、負荷中にセルスタイルのフォーマットを適用することは効果がないようであることです。あなたがグーグルした場合、たくさんの投稿がそこにいます。また、フォームのボタンの下に同じコードを置き、ロード後に(ロード内ではなく)をクリックすると、スタイリングが適用できる前にグリッドを表示する必要があるため、グリッドを表示する必要があります)。トピックに関するほとんどのアドバイスは、あなたが使用することをお勧めします... Drumroll ... CellFormatting。アーグ!

グリッドのDataBindingCompleteイベントを使用していることを示唆する投稿を最終的に見つけました。そしてこれは作品です。

確かに、この解決策は私の不要なオプション「4」の変種です。

他のヒント

私は可能な解決策を持っています - あなたのエクスポート関数には、各セルのCell.FormattedValueプロパティにアクセスします。 microsoft によると、これは強制的に火災へのセルフォーマットイベント。

他の回答で述べたように、DataGridViewCell.FormattedValueにアクセスすることは、特定のセルに対してCellFormattingイベントを(再)呼び出されるように強制するための簡単な方法です。ただし、私の場合、このプロパティはまた、カラムの自動サイズ変更を含む望ましくない副作用をもたらしました。作業可能な解決策に長時間検索しながら、私はついに完全に機能する次のマジックメソッドに遭遇しました。

これらの4つの方法は、指定されたスコープ(セル、列、行、または表の全体の表だけ)に対してのみ呼び出されるように、そしてまた厄介な自動サイズ変更アーチファクトを引き起こすことなく、強制的に呼びかけます。

私は同じ問題を抱えていて、私はあなたの解決策#4と非常に似たものに終わりました。 あなたのように、DataBindingCompleteイベントを使用しました。しかし、私は拡張方法を使用していたので、既存のコードの変更は準備ができています:

internal static class DataGridViewExtention
{
    public static void SetGridBackColorMyStyle(this DataGridView p_dgvToManipulate)
    {
        p_dgvToManipulate.RowPrePaint += p_dgvToManipulate_RowPrePaint;
        p_dgvToManipulate.DataBindingComplete += p_dgvToManipulate_DataBindingComplete;
    }

    // for the first part - Coloring the whole grid I used the `DataGridView.DataBindingComplete` event:
    private static void p_dgvToManipulate_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        foreach (DataGridViewRow objCurrRow in ((DataGridView)sender).Rows)
        {
            // Get the domain object from row 
            DomainObject objSelectedItem = (DomainObject)objCurrRow.DataBoundItem;

            // if item is valid ....
            if objSelectedItem != null)
            {
                // Change backcolor of row using my method
                objCurrRow.DefaultCellStyle.BackColor = GetColorForMyRow(objSelectedItem);
            }
        }
    }

    // for the second part (disabling the Selected row from effecting the BackColor i've setted myself, i've used `DataGridView.RowPrePaint` event:
    private static void p_dgvToManipulate_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
    {
        // If current row about to be painted is selected by user
        if (((DataGridView)sender).Rows[e.RowIndex].Selected)
        {
            // Get current grid row
            var objGridRow = ((DataGridView)sender).Rows[e.RowIndex];

            // Get selectedItem
            DomainObject objSelectedItem = (DomainObject)objGridRow.DataBoundItem;

            // if item is valid ....
            if (objSelectedItem != null && objSelectedItem.ObjectId != 0)
            {
                // Set color for row instead of "DefaultCellStyle" (same color as we used at DataBindingComplete event)
                objGridRow.DefaultCellStyle.SelectionBackColor = GetColorForMyRow(objSelectedItem);
            }

            // Since the selected row is no longer unique, we need to let the used to identify it by making the font Bold
            objGridRow.DefaultCellStyle.Font = new Font(((DataGridView)sender).Font.FontFamily, ((DataGridView)sender).Font.Size, FontStyle.Bold);
        }
        // If current row is not selected by user
        else
        {
            // Make sure the Font is not Bold. (for not misleading the user about selected row...)
            ((DataGridView)sender).Rows[e.RowIndex].DefaultCellStyle.Font = new Font(((DataGridView)sender).Font.FontFamily,
                                                                                   ((DataGridView)sender).Font.Size, FontStyle.Regular);
        }
    }
}
.

セルフォーマットイベントの間に提供されているフォーマットを再利用したい場合(例えば、FontBoldとBackgroundColorのようなCellStyle-Elements)。これらのセルスタイルは、「Cellformatting」と「CellPainting」イベントの間でのみ利用可能であるように見えますが、DataGridView - Cellのスタイル自体ではありません。

セルファルイベントの間にセルスタイルをキャプチャします。

  1. ExportModuleでは、CellStylesを保存するために共有リスト、配列または辞書を追加します。

    Dim oDataGridFormattingDictionary as  Dictionary(Of String, DataGridViewCellStyle) = nothing
    

  2. 辞書を初期化し、印刷コードまたはエクスポートコードのDataGridViewに2番目のハンドラを追加します。 vb.netでは、このようなもの:

     oDataGridFormattingDictionary = New Dictionary(Of String, DataGridViewCellStyle)
     AddHandler MyDatagridviewControl.CellFormatting, AddressOf OnPrintDataGridView_CellFormatting
    

  3. ハンドラのコードを追加する

    Private Sub OnPrintDataGridView_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs)
    If e.RowIndex > -1 AndAlso e.ColumnIndex > -1 AndAlso Not e.CellStyle Is Nothing Then
       If Not oDataGridFormattingDictionary Is Nothing andalso oDataGridFormattingDictionary.ContainsKey(e.RowIndex & "_" & e.ColumnIndex) = False Then
        oDataGridFormattingDictionary.Add(e.RowIndex & "_" & e.ColumnIndex, e.CellStyle)
       End If
    End If
    End Sub
    

  4. 非常に重要な:実際には、実際にあなたが実際にあなたが呼び出されなければならないことを確認するために、 formattedvalue を要求する必要があることを確認するために印刷したい各セルについて(例:

    oValue = Datagridview.rows(printRowIndex).Cells(printColumnIndex).FormattedValue)
    
    .

  5. 印刷するときは、セルにフォーマットがあるかどうかを確認できるようになりました。 e.g。:

    if not oDataGridFormattingDictionary is nothing andalso oDataGridFormattingDictionary.ContainsKey(printRowIndex & "_" & printColumnIndex) Then
    ... the cellstyle is accesible via:
    oDataGridFormattingDictionary(printRowIndex & "_" & printColumnIndex)
    end if 
    

  6. エクスポートまたはPrintCodeの終わりにハンドラを削除し、辞書を何もしないように設定します

    RemoveHandler DirectCast(itemToPrint.TheControl, DataGridView).CellFormatting, AddressOf OnPrintDataGridView_CellFormatting
    oDataGridFormattingDictionary = nothing
    

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