none
データグリッドの描画崩れ(onCellPainting) RRS feed

  • 質問

  • 環境:VisualStudio 2010

    現在、ClientのHandlerクラスからonCellPaintingにて
    グリッドの描画処理(セル結合=罫線を消す や 背景色変更)を行っています。

    親画面のボタン押下時にMsgBox関数ダイアログ・他画面のポップアップ表示で、モーダル状態になると
    ペイントしたセルとヘッダーがデフォルトの状態に戻ってしまいます。(子画面のグリッドは正常)

    モーダル中に親画面のグリッドを描画し続けたいのですが、
    なにか良い方法はないでしょうか。

    各画面HandlerのonCellPaintingから参考のペイント処理を呼んでいます。
    ※ヘッダーペイントは別にあります。

    Public Class PaintGrid
    	Private Sub paint(ByRef sender As Object, ByRef e As System.Windows.Forms.DataGridViewCellPaintingEventArgs)
    
    	    Dim isActChange As Boolean = False
    	    Dim sortedGridData As New PaintGridDataClass
    	    Dim changeRowConditionVal As String = String.Empty
    	    Dim changeRowPreRowConditionVal As String = String.Empty
    	    Dim changeRowAftRowConditionVal As String = String.Empty
    	    Dim iUnitEndRow As Integer = 0
    
    	    If e.RowIndex < 0 Then
    	        Return
    	    End If
    
    	    Dim dgv As BaseDataGridView = CType(sender, BaseDataGridView)
    
    	    If dgv.Rows(e.RowIndex).Visible = False Then
    	        Return
    	    End If
    
    	    isActChange = chkTargetRow(dgv, e.RowIndex, e.ColumnIndex, sortedGridData, iUnitEndRow)
    
    	    Dim afterRow As Integer = 0
    	    Dim preRow As Integer = 0
    	    Dim isExistTargetRow As Boolean = False
    
    	    If isActChange = True Then
    
    	        Dim blDel As Boolean = chkDeleteObject(dgv, e.RowIndex, sortedGridData, changeRowConditionVal, changeRowAftRowConditionVal)
    
    	        If e.RowIndex < dgv.RowCount - 1 AndAlso _
    	           e.RowIndex < iUnitEndRow AndAlso _
    	           changeRowConditionVal = changeRowAftRowConditionVal Then
    	            e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None
    	        End If
    
    	        If blDel = True Then
    	            e.PaintBackground(e.CellBounds, CBool(e.State And DataGridViewElementStates.Selected))
    	            e.Handled = True
    	            dgv.Rows(e.RowIndex).Cells(e.ColumnIndex).ReadOnly = True
    	        End If
    	    Else
    	        sortedGridData = Nothing
    	    End If
    	 
    	    If dgv.ColorColumn Is Nothing Then
    	        
    	        If sortedGridData IsNot Nothing Then
    	            changeRowConditionVal = CreateChangeColorConditionVal(dgv, e.RowIndex, sortedGridData)
    	            If e.RowIndex > 0 Then
    	               
    	                For preRow = e.RowIndex - 1 To 0 Step -1
    	                    If dgv.Rows(preRow).Visible = True Then
    	                        isExistTargetRow = True
    	                        Exit For
    	                    End If
    	                Next
    	                If isExistTargetRow = True Then
    	                    changeRowPreRowConditionVal = CreateChangeColorConditionVal(dgv, preRow, sortedGridData)
    	                    isExistTargetRow = False
    	                End If
    	            End If
    	            If e.RowIndex < dgv.Rows.Count - 1 Then
    	              
    	                For afterRow = e.RowIndex + 1 To dgv.Rows.Count - 1 Step 1
    	                    If dgv.Rows(afterRow).Visible = True Then
    	                        isExistTargetRow = True
    	                        Exit For
    	                    End If
    	                Next
    	                If isExistTargetRow = True Then
    	                    changeRowAftRowConditionVal = CreateChangeColorConditionVal(dgv, afterRow, sortedGridData)
    	                    isExistTargetRow = False
    	                End If
    	            End If
    	        End If
    
    	        If e.RowIndex = 0 Then
    	            dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.FromArgb(&HFFFFFFFF)
    	        Else
    	            If preRow > -1 Then
    	                Dim precolor As Color = dgv.Rows(preRow).DefaultCellStyle.BackColor
    
    	                If String.IsNullOrEmpty(changeRowConditionVal) = False Then
    	                    If changeRowConditionVal = changeRowPreRowConditionVal Then
    
    	                        dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = precolor
    	                    Else
    	                     
    	                        If precolor = Color.FromArgb(&HFFFFFFFF) Then
    	                            dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.FromArgb(&HFFE7FCEC)
    	                        Else
    	                            dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.FromArgb(&HFFFFFFFF)
    	                        End If
    	                    End If
    	                End If
    	            End If
    	        End If
    	    End If
    
    	        If dgv.Columns(e.ColumnIndex).GetType.Equals((New DataGridViewButtonColumn).GetType) OrElse _
    	           dgv.Columns(e.ColumnIndex).GetType.Equals((New DataGridViewDisableButtonColumn).GetType) Then
    	            If dgv.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString <> String.Empty Then
    	                e.CellStyle.BackColor = SystemColors.Control
    	            Else
    	                e.PaintBackground(e.CellBounds, CBool(e.State And DataGridViewElementStates.Selected))
    	                e.Handled = True
    	            End If
    	        End If
    	End Sub
    End Class

    2018年1月25日 10:55

回答

  • 私の方で以下の環境で試してみましたが、再現しませんでした。
    Windows 7 pro 64bit, Visual Studio 2010

    基本的にOnCellPaintingは必要な際に自動的に呼ばれるので、まず、OnCellPaintingがちゃんと呼ばれているか確認されてみてはいかがでしょうか? もし呼ばれているのであれば、paintイベントハンドラ内でうまく処理できていないとか、その後の何かの処理が影響しているのかもしれません。
    DataGridViewのInvalidateCellメソッドを子画面から実行し、どのように処理されていくのかデバッグしても良いかもしれません。


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク abc_123_ 2018年1月26日 5:14
    2018年1月26日 1:34
    モデレータ

すべての返信

  • 私の方で以下の環境で試してみましたが、再現しませんでした。
    Windows 7 pro 64bit, Visual Studio 2010

    基本的にOnCellPaintingは必要な際に自動的に呼ばれるので、まず、OnCellPaintingがちゃんと呼ばれているか確認されてみてはいかがでしょうか? もし呼ばれているのであれば、paintイベントハンドラ内でうまく処理できていないとか、その後の何かの処理が影響しているのかもしれません。
    DataGridViewのInvalidateCellメソッドを子画面から実行し、どのように処理されていくのかデバッグしても良いかもしれません。


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク abc_123_ 2018年1月26日 5:14
    2018年1月26日 1:34
    モデレータ
  • 実行して頂いたようでありがとうございます。

    ご指摘の通りOnCellPaintingが呼ばれているか確認したところ、

    Handlerクラスに定義しているグリッドのOnCellPaintingはモーダル中は呼ばれていませんでした。

    しかし、各画面のグリッドが継承している独自のベースグリッドクラスでOnCellPaintingをオーバーライドしたところ

    モーダル中も呼ばれました。

    そのためベースグリッドクラスにてペイント処理を行うことで解決できました。

    HandlerクラスのOnCellPaintingが呼ばれていない原因はわかりませんでしたが、

    「OnCellPaintingは必要な際に自動的に呼ばれるので」というご指摘がかなりヒントになりました。

    ご協力頂きましてありがとうございます。

    2018年1月26日 5:21