DOBON.NETプログラミング道掲示板

No35219 の記事


■35219 / )  Re[2]: DataGridViewの行ヘッダーに行番号を表示した時のエラー
□投稿者/ たこ 一般人(14回)-(2022/11/04(Fri) 22:14:40)
  • アイコンNo35218に返信(魔界の仮面弁士さんの記事)
    > ■No35216に返信(たこさんの記事)

    いつもお世話になります。
    魔界の仮面弁士様、早速のご回答ありがとうございます。



    > ということで、ログ関連の設定情報に問題があるのでは無いでしょうか。
    >
    > プロジェクトの構成が分からないので具体的なアドバイスはできませんが、
    > Log.dll のプロジェクトがあるのなら、確認すべき app.config は Log プロジェクトの app.config ではなく、
    > exe 側のプロジェクト側の app.cofing のはずです。exe 側の .config に対して、Log プロジェクト用の
    > エントリーが正しく記録されているかどうかを確認してみてください。


    exe側のApp.config
    ----------------------------------------------------------------------------------------------------
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
      </configSections>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
      </startup>
    </configuration>
    ----------------------------------------------------------------------------------------------------
    別におかしいところは見当たらず…orz




    > DataGridView1.Rows.Clear() が呼ばれているという事は、DGVDataAdd メソッドの呼び出し元が
    > UI スレッド上からの呼び出しであることは保証されているのですよね?


    InvokeでUIスレッド上からの呼び出しであることは保証されている…と思っています。。。



    > で、引数の List(Of ) は、「別スレッドでも同時に読み書きされる可能性がある」という事でしょうか。


    はい。値渡ししています。


    >>いろんなスレッドに呼ばれるので、エラーが出て最終的に「On Error Resume Next」を付けました^^;
    > え?「いろんなスレッドに呼ばれる」のですか?
    > この実装だと、UI スレッド以外からの呼び出しは NG に見えますが…。


    正確にはいろいろなクラスのメソッドからイベントで呼ばれる…でした^^;



    > ワーカースレッドから呼ばれることを前提としているのであれば、
    > DataGridView に対する読み書き部分を取り除く必要があるでしょう。
    >
    >
    >>  System.Threading.Monitor.Enter(workStr)
    >>  Dim ws As List(Of String()) = workStr
    >>  System.Threading.Monitor.Exit(workStr)
    >>  System.Threading.Monitor.Enter(ws)
    > ・ws は、workStr のコピーでは無く、同一インスタンスへの参照ですよね。
    >  Exit 直後に再 Enterをする実装になっているのは何故ですか?
    >  ループ全体を ws で囲って、ループ内では workStr で囲っている理由が分からないです。
    >  (ReaderWriterLock クラスのような事がしたいわけでも無さそうですし…)
    >
    > ・もしも処理によって粒度の異なるロックを用意したいという意図であれば、
    >  ロック範囲のレベルごとに、別々の「Object インスタンス」を設けた方が良いかもしれません。
    >   Private ReadOnly lockObject As New Object()
    >
    > ・UI スレッドで Monitor を扱う場合は、無制限待機になってしまうことを避けるため、
    >  .Enter ではなく、待機上限時間を指定可能な .TryEnter の方が安全かと思います。
    >  (ロック失敗時にアプリケーション例外とするのか、処理を無視するのか、リトライ判定させるかは要件次第…)


    TryEnterと言うメソッドもあるのですね…
    まだまだスレッドとエラー処理については勉強が必要そうです……


    で、本題の「DataGridViewの行ヘッダーに行番号を表示した時のエラー」について、今回はそこまで厳密にリアルタイムに表示されなくても良い為、
    魔法の言葉「On Error Resume Next」で逃げる事にしました^^;

    最終形
    -----------------------------------------------------------------------------------------------------------------------------------------------------
      Private Sub DataGridView1_CellPainting(ByVal sender As Object, ByVal e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
        On Error Resume Next
        '列ヘッダーかどうか調べる
        If e.ColumnIndex < 0 And e.RowIndex >= 0 Then
          'セルを描画する
          e.Paint(e.ClipBounds, DataGridViewPaintParts.All)

          '行番号を描画する範囲を決定する
          'e.AdvancedBorderStyleやe.CellStyle.Paddingは無視しています
          Dim indexRect As Rectangle = e.CellBounds
          indexRect.Inflate(-2, -2)
          '行番号を描画する
          TextRenderer.DrawText(e.Graphics,
                     (e.RowIndex + 1).ToString(),
                     e.CellStyle.Font,
                     indexRect,
     e.CellStyle.ForeColor,
                     TextFormatFlags.Right Or TextFormatFlags.VerticalCenter)
          '描画が完了したことを知らせる
          e.Handled = True
        End If

        DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray
      End Sub


      Private Sub DGVDataAdd(workStr As List(Of String()))
        DataGridView1.Rows.Clear()
        On Error GoTo ErrorNext
        Dim ws As List(Of String()) = workStr
        Dim x As Integer = 0
        For Each work In ws
          DataGridView1.Rows.Add(work)
          DataGridView1(LogData.LogKinds, x).Style.BackColor = LogKind_ColorChange(work)
          DataGridView1(LogData.Operation, x).Style.ForeColor = Operation_ColorChange(work)
          x += 1
        Next
    ErrorNext:
        DataGridView1.Refresh()
      End Sub

    -----------------------------------------------------------------------------------------------------------------------------------------------------


    板汚し失礼致しました。
    またよろしくお願い致します。
    ありがとうございました。
解決み!
違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -