ListView Control (Draw)

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Steven.

    ListView Control (Draw)

    Moin, ich habe gerade angefangen an einem ListView Control zu arbeiten und wollte dort gerne
    den Hintergrund wo die ColumnHeader drauf sind bearbeiten, ich habe schon mal geschaut aber
    leider nichts weiter dazu gefunden.

    Siehe Bild

    Mein Source Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Class XListView
    2. Inherits ListView
    3. Sub New()
    4. GridLines = False
    5. FullRowSelect = True
    6. HeaderStyle = ColumnHeaderStyle.Nonclickable
    7. View = View.Details
    8. OwnerDraw = True
    9. ResizeRedraw = True
    10. Font = New Font("Arial", 8.25F, FontStyle.Regular)
    11. Size = New Size(300, 200)
    12. BorderStyle = BorderStyle.None
    13. BackColor = Color.FromArgb(245, 245, 245)
    14. SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.OptimizedDoubleBuffer, True)
    15. End Sub
    16. Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
    17. Me.Invalidate()
    18. MyBase.OnDrawItem(e)
    19. End Sub
    20. Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
    21. If Me.SelectedItems.Count = 1 Then
    22. Dim Item As ListViewItem = Me.SelectedItems(0)
    23. Select Case Item.Checked
    24. Case True
    25. Item.Checked = False
    26. Case Else
    27. Item.Checked = True
    28. End Select
    29. End If
    30. MyBase.OnClick(e)
    31. End Sub
    32. Protected Overrides Sub OnDrawColumnHeader(ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
    33. Me.SuspendLayout()
    34. Dim G As Graphics = e.Graphics
    35. Dim Rect As New Rectangle(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height - 3)
    36. G.FillRectangle(New SolidBrush(Color.Black), Rect)
    37. G.DrawRectangle(Pens.Gray, Rect)
    38. Dim TextSizeF As SizeF = G.MeasureString(e.Header.Text, e.Font)
    39. Dim TextSize As Size = New Size(CInt(TextSizeF.Width), CInt(TextSizeF.Width))
    40. Dim TextLeft As Integer = CInt((e.Bounds.Width / 2) - (TextSizeF.Width / 2)) + e.Bounds.Left
    41. Dim TextTop As Integer = CInt((e.Bounds.Height / 2) - (TextSizeF.Height / 2)) + e.Bounds.Top
    42. G.DrawString(e.Header.Text, e.Font, New SolidBrush(Color.White), New Point(TextLeft, TextTop))
    43. Me.ResumeLayout()
    44. MyBase.OnDrawColumnHeader(e)
    45. End Sub
    46. Protected Overrides Sub OnDrawSubItem(ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs)
    47. Me.SuspendLayout()
    48. Dim G As Graphics = e.Graphics
    49. Dim TextSizeF As SizeF = G.MeasureString(e.SubItem.Text, e.SubItem.Font)
    50. Dim TextSize As Size = New Size(CInt(TextSizeF.Width), CInt(TextSizeF.Width))
    51. Dim TextLeft As Integer = CInt((e.Bounds.Width / 2) - (TextSizeF.Width / 2)) + e.Bounds.Left
    52. Dim TextTop As Integer = CInt((e.Bounds.Height / 2) - (TextSizeF.Height / 2)) + e.Bounds.Top
    53. Dim Rect As New Rectangle(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
    54. G.FillRectangle(Brushes.DarkGray, e.Bounds)
    55. G.DrawRectangle(Pens.Gray, Rect)
    56. If Me.SelectedIndices.IndexOf(e.ItemIndex) > -1 Then
    57. Dim HighlightBaseColor As Color = e.Item.BackColor
    58. Dim HighlightColor As Color = Color.FromArgb(255, HighlightBaseColor)
    59. Dim ItemFillRectangle As New Rectangle(e.SubItem.Bounds.Left, e.SubItem.Bounds.Top, e.SubItem.Bounds.Width, e.SubItem.Bounds.Height)
    60. G.FillRectangle(New SolidBrush(HighlightColor), ItemFillRectangle)
    61. End If
    62. If Me.SelectedIndices.IndexOf(e.ItemIndex) > -1 Then
    63. G.DrawString(e.SubItem.Text, e.SubItem.Font, New SolidBrush(e.Item.ForeColor), New Point(TextLeft, TextTop))
    64. Else
    65. G.DrawString(e.SubItem.Text, e.SubItem.Font, New SolidBrush(e.Item.BackColor), New Point(TextLeft, TextTop))
    66. End If
    67. Me.ResumeLayout()
    68. MyBase.OnDrawSubItem(e)
    69. End Sub
    70. Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    71. 'Dim B As New Bitmap(Width, Height)
    72. 'Dim G As Graphics = Graphics.FromImage(B)
    73. 'G.Clear(Parent.BackColor)
    74. 'G.Dispose() : B.Dispose()
    75. End Sub
    76. End Class


    Lg Steve
    @Steven Was soll denn da stehen?
    Setz mal nen Haltepunkt in die einzelnen Draw-Routinen und überzeuge Dich davon, dass das Progeamm da ühaupt vorbeikommt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    @Steven Was soll denn da stehen?
    Setz mal nen Haltepunkt in die einzelnen Draw-Routinen und überzeuge Dich davon, dass das Progeamm da ühaupt vorbeikommt.
    Ich habe gerade noch mal bei den Drei Draw Routinen geschaut, in keiner konnte ich auf den
    besagten Hintergrund Zeichnen. Mir würde dazu noch einfallen ein ListView selbst zu definieren, und dann ein eigenes
    Control zu Zeichnen, das wäre mir dann aber zu umfangreich, gibt es seitens VB also keine Möglichkeit auf der Fläche zu
    zeichnen? in der DotNetBar Lib ist ein Listview enthalten wo der Komplette Header gezeichnet ist.
    Das Tutorial "noch ein coloriertes Datagridview" zeigt, dass man DGV komplett auf ListView stylen kann.
    Ohne Icons braucht man für dieses Styling keinerlei Code - da muß man nur die Gridlines ausblenden und die Zeilenhöhe verringern.
    Der im Tut getriebene Aufwand wäre komplett entbehrlich - er dient ausschließlich der Gestaltung colorierter spalten sowie einer Column mit Icon.

    Langer Rede kurzer Sinn: Vergiss ListView, nimm DatagridView.
    Damit kriegt man ganz nebenbei auch so Drawereien wesentlich besser hin.

    Und vermeide, ein Control selbst basteln zu wollen!
    Controls agieren nicht nur zur Laufzeit, sondern auch zur Design-Zeit - bei letzterem wird recht viel über Attribute gesteuert, und es ist auch mit Extra-Bibliotheken umzugehen, die sich nur mit dem Designer-Verhalten beschäftigen etc.

    Also ich habs jetzt bisserl finster ausgemalt, aber grundsätzlich isses schon so: Stabile Controls selbst entwickeln erfordert recht umfangreiches Spezialwissen, und dann ist man immer noch nicht vor allerlei Überraschungen gefeit.

    Nimm lieber DGV, und verarbeite mw. das CellPainting-Event (wie im Tut gezeigt) - das geht auch für HeaderCells.
    @Steven Darf ich Deine Beiträge so verstehen, dass Du gar nicht weißt, ob Dein Code ühaupt verwendet wird?
    Ansonsten pflichte ich dem @ErfinderDesRades bei, steig auf ein DataGridView um.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ErfinderDesRades schrieb:

    Das Tutorial "noch ein coloriertes Datagridview" zeigt, dass man DGV komplett auf ListView stylen kann.
    Ohne Icons braucht man für dieses Styling keinerlei Code - da muß man nur die Gridlines ausblenden und die Zeilenhöhe verringern.
    Der im Tut getriebene Aufwand wäre komplett entbehrlich - er dient ausschließlich der Gestaltung colorierter spalten sowie einer Column mit Icon.

    Langer Rede kurzer Sinn: Vergiss ListView, nimm DatagridView.
    Damit kriegt man ganz nebenbei auch so Drawereien wesentlich besser hin.

    Und vermeide, ein Control selbst basteln zu wollen!
    Controls agieren nicht nur zur Laufzeit, sondern auch zur Design-Zeit - bei letzterem wird recht viel über Attribute gesteuert, und es ist auch mit Extra-Bibliotheken umzugehen, die sich nur mit dem Designer-Verhalten beschäftigen etc.

    Also ich habs jetzt bisserl finster ausgemalt, aber grundsätzlich isses schon so: Stabile Controls selbst entwickeln erfordert recht umfangreiches Spezialwissen, und dann ist man immer noch nicht vor allerlei Überraschungen gefeit.

    Nimm lieber DGV, und verarbeite mw. das CellPainting-Event (wie im Tut gezeigt) - das geht auch für HeaderCells.


    Viele dank für die Hilfe, ich schau mir mal DGV an, und das Control selbst zu Zeichnen ist mir auch
    ein wenig zu hoch gesteckt, wie du es aber auch schon gesagt hast.

    RodFromGermany schrieb:

    @Steven Darf ich Deine Beiträge so verstehen, dass Du gar nicht weißt, ob Dein Code ühaupt verwendet wird?
    Ansonsten pflichte ich dem @ErfinderDesRades bei, steig auf ein DataGridView um.


    Also die Subs werden geCallt ohne Probleme, nur kann man
    in keinem auf den Hintergrund Zeichnen der auf dem Bild Weiß
    zu sehen ist. Ich werde mir aber DGV mal anschauen, danke auch dir

    LG Steven