Jonas Jelonek schrieb:
und zum eigentlichen Thema zurückkommen, und zwar, wie ich jetzt so ein Control in WinForms am besten mache.
Eben das hat mich ja verwirrt. Also war Semitransparenz und Blur eigentlich total offtopic
Zum Thema:
Zuerst mal stellt sich ja die Frage, wie man diesen blauen Hintergrund hinbekommt. Das ist ja scheinbar dem Explorerfenster nachempfunden, dort haben selektierte Einträge auch diesen blauen Verlauf. Nun gibt es eine Möglichkeit, diesen Explorerstyle auch in eigenen Programmen zu nutzen. Man macht folgendes:
Damit wird Windows gesagt, dass für dieses Control nicht der Style des eigenen Programms, sondern der Style des Programms "explorer" benutzt werden soll. Nun wird man feststellen, dass dies keine Veränderung bringt, wenn man sein Control von Listbox erben lässt. Das liegt ganz einfach daran, dass auch der Explorer die Listbox nicht besonders style-t. Der benutzt ein ListView-Element. Wenn wir nun also von Listview erben und die View auf View.Details umstellen, dann haben wir ein Listbox-artiges Aussehen, mit schönem Explorer-Style:
Aber natürlich gibt es einen Haken. Da wir statt einer Listbox eine Listview nehmen müssen, verlieren wir die ItemHeight-Eigenschaft. Damit sind also paktisch keine so hohen Items, wie im Firefox, möglich. Es gibt einen Trick, dass man zum Beispiel die SmallItemView benutzt und dann halt ein Bild benutzt, das so hoch ist, wie man das Item haben will. Aber das ist für uns ja auch nicht sehr geeignet, da das Item im Firefox circa doppelt so hoch wie das Icon der Datei ist.
Also können wir diesen Ansatz eigentlich vergessen. Dann gibt es ja noch den schönen VisualStyleRenderer. Wenn du dann mal ein bisschen damit rumspielst, ungefähr so:
VB.NET-Quellcode
Dann wirst du feststellen, dass all die tollen ListView-Styles im aktuellen Windows-Style gar nicht definiert sind:
Die gegebene Kombination aus "Class", "Part" und "State" wird vom aktuellen visuellen Stil nicht definiert.
Aaaaber, es gibt da ja noch eine Möglichkeit, einen VisualStyleRenderer zu erstellen, nämlich mit
New VisualStyleRenderer(VisualStyleElement.CreateElement(className As String, part As Integer, state As Integer))
. Nun, was hat es mit className, part und state auf sich? Dazu kann man mal einen Blick in die Datei vsstyle.h werfen, die man üblicherweise in \Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include
findet. Dort sind lauter Enums zu finden. Das sind praktisch die Enum-Werte, die hinter den Auflistungen stecken, die wir oben schon verwendet haben, wie zum Beispiel: VisualStyleElement.ListView.Item.Hot
. Nun kann man sich die numerischen Enum-Werte raussuchen und die Style-Elemente praktisch von Hand erstellen. Auch da kommt bei den typischen Kombinationen die Meldung, dass das vom aktuellen Stil nicht definiert wird. Nun finden sich da aber auch noch eine ganze Reihe weiterer Werte in den Enums, die einem im Code gar nicht zugänglich gemacht werden. Und von denen sind einige sehr wohl im aktuellen Stil definiert. Eine dieser Kombinationen sieht zum Beispiel so aus:VB.NET-Quellcode
- Const LVP_GROUPHEADER As Integer = 6
- Const LVGH_OPENSELECTEDNOTFOCUSEDHOT As Integer=6
- Private renderer As New VisualStyleRenderer(VisualStyleElement.CreateElement("LISTVIEW", LVP_GROUPHEADER, LVGH_OPENSELECTEDNOTFOCUSEDHOT))
- Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
- renderer.DrawBackground(e.Graphics, New Rectangle(10, 10, 200, 50))
- End Sub
Tja, und was bekommt man dann? Folgendes:
Das sieht doch schon ganz gut aus, oder?
Setzen wir das auf unser eigenes Control, unter Ausnutzung der ItemHeight einer Listbox, um, dann haben wir folgenden Code:
VB.NET-Quellcode
- Imports System.Windows.Forms.VisualStyles
- Public Class FirefoxListbox
- Inherits ListBox
- Const LVP_GROUPHEADER As Integer = 6
- Const LVGH_OPENSELECTEDNOTFOCUSEDHOT As Integer = 6
- Private renderer As New VisualStyleRenderer(VisualStyleElement.CreateElement("LISTVIEW", LVP_GROUPHEADER, LVGH_OPENSELECTEDNOTFOCUSEDHOT))
- Private Sub FirefoxListbox_DrawItem(sender As Object, e As System.Windows.Forms.DrawItemEventArgs) Handles Me.DrawItem
- e.Graphics.Clip = New Region(e.Bounds)
- e.Graphics.Clear(Color.White)
- renderer.DrawBackground(e.Graphics, e.Bounds)
- End Sub
- Public Sub New()
- Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
- Me.ItemHeight = 72
- Me.IntegralHeight = False 'finde ich einfach besser
- End Sub
- End Class
Das Endergebnis sieht dann so aus:
ich denke, von hier aus lasse ich dich mal alleine weitermachen. Aber als kleiner Hinweis: Das VisualStyle-Gemache ist ja betriebssystemabhängig. Also schau es dir auch mal auf Win 8, XP, Vista an, je nachdem, was du supporten willst. Ein ganz anderer Ansatz wäre auch das vollständige Selbstzeichnen mit Gradients usw. Dann siehts natürlich überall gleich aus, ist aber noch viel mehr Arbeit, bis es gut aussieht.
PS: Für solch ausführliche Antworten sollte man geld verlangen können
Skybird schrieb:
Das sind ja Ubisoftmethoden hier !