Wie man ein benutzerdefiniertes Kombinationsfeld (OwnerDrawFixed) in 3D wirkt wie die standard-ComboBox?
Mache ich ein benutzerdefiniertes Kombinationsfeld, geerbt von Winforms standard ComboBox. Für meine eigene ComboBox, ich DrawMode
zu OwnerDrawFixed
und DropDownStyle
zu DropDownList
. Dann Schreibe ich meine eigene OnDrawItem
Methode. Aber ich endete wie folgt:
Wie mache ich meine eigene ComboBox zu schauen, wie der Standard?
Update 1: ButtonRenderer
Nach der Suche überall, ich fand die ButtonRenderer
Klasse. Es bietet eine DrawButton
static/shared-Methode, die-wie der name schon sagt -- zieht die richtigen 3D-Taste. Ich experimentiere mit es jetzt.
Update 2: Was überschreibt meine Steuerung?
Habe ich versucht mithilfe der Grafik die Eigenschaften der verschiedenen Objekte kann ich mir vorstellen, aber ich habe immer scheitern. Schließlich habe ich versucht, die Grafiken in der form, und scheinbar etwas ist das überschreiben von mein-button.
Hier der code:
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
Dim TextToDraw As String = _DefaultText
__Brush_Window.Color = Color.FromKnownColor(KnownColor.Window)
__Brush_Disabled.Color = Color.FromKnownColor(KnownColor.GrayText)
__Brush_Enabled.Color = Color.FromKnownColor(KnownColor.WindowText)
If e.Index >= 0 Then
TextToDraw = _DataSource.ItemText(e.Index)
End If
If TextToDraw.StartsWith("---") Then TextToDraw = StrDup(3, ChrW(&H2500)) ' U+2500 is "Box Drawing Light Horizontal"
If (e.State And DrawItemState.ComboBoxEdit) > 0 Then
'ButtonRenderer.DrawButton(e.Graphics, e.Bounds, VisualStyles.PushButtonState.Default)
Else
e.DrawBackground()
End If
With e
If _IsEnabled(.Index) Then
.Graphics.DrawString(TextToDraw, Me.Font, __Brush_Enabled, .Bounds.X, .Bounds.Y)
Else
'.Graphics.FillRectangle(__Brush_Window, .Bounds)
.Graphics.DrawString(TextToDraw, Me.Font, __Brush_Disabled, .Bounds.X, .Bounds.Y)
End If
End With
TextToDraw = Nothing
ButtonRenderer.DrawButton(Me.Parent.CreateGraphics, Me.ClientRectangle, VisualStyles.PushButtonState.Default)
'MyBase.OnDrawItem(e)
End Sub
Und hier ist das Ergebnis:
Ersetzen Me.Parent.CreateGraphics
mit e.Graphics
hab mir das:
Und dabei die oben + ersetzen Me.ClientRectangle
mit e.Bounds
hab mir das:
Kann jemand Punkt mich , deren Grafiken ich verwenden muss für die ButtonRenderer.DrawButton
Methode?
PS: Die bläulich-Grenze ist durch meine mithilfe PushButtonState.Default anstelle von PushButtonState.Normal
Ich Eine Antwort Gefunden! (siehe unten)
- Ich denke, Sie haben das Recht, Grafik (e.Grafik). Auf den ersten Blick würde ich vermuten e.Grenzen nicht zu geben Sie den gesamten Bereich von der ComboBox, sondern nur die Grenzen des Textes, und das ist, warum Sie werden immer ein kleiner button gezeichnet.
- problem ist, e.Grafik hat einen Clip, das ist ReadOnly. Ich bin immer noch auf der Jagd für die Veranstaltung/code, der zieht das weiße Feld mit dropdown-Pfeil
- Ich habe versucht, mit Mir.CreateGraphics statt e.CreateGraphics, die Ihnen die Grafiken für die ComboBox selbst, statt einfach die Elemente-Bereich. Es hat nicht ganz funktioniert, aber was ich bemerkte war, dass das richtige Feld gezogen wurde, wenn ich klickte auf das Kombinationsfeld, aber dann wurde sofort entfernt, wenn die Elemente angezeigt wurden. So, im folgenden gibt Sie die richtige box, wenn Sie herausfinden können, wie Sie es bekommen dort zu bleiben (muss wahrscheinlich in einem anderen Fall, dass die Farben der ComboBox selbst). ButtonRenderer.DrawButton(Mich.- Grafik, Mir.Grenzen, VisualStyles.PushButtonState.Normal)
- ja, war die Jagd für dieses Ereignis den ganzen Tag 🙁 ... naja, ich werde einfach sagen meine Kunden "nicht gemacht werden Können" 🙂 vielen Dank für Ihre Hilfe!
- Hurra! Es gefunden! ... nun zu denken, was zu sagen zu meinen Kunden, dass es getan werden kann, nachdem alle 😛
- Warum Microsoft?????
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich vergessen, wo ich die Antwort gefunden... ich werde Bearbeiten Sie diese Antwort, wenn ich daran denke.
Aber anscheinend, ich brauche, um die
Systems.Windows.Forms.ControlStyles
flags. Vor allem dieControlStyles.UserPaint
Flagge.So, meine
New()
sieht nun wie folgt aus:Und jetzt kann ich die Haken in die
OnPaint
Veranstaltung:Hinweis: ja, die
_ButtonArea
Rechteck muss vergrößert werden um 1 pixel in alle Richtungen (oben, unten, Links, rechts), oder aber es wird ein 1-pixel 'Umkreis' um die ButtonRenderer, die zeigt Müll an. Machte mich verrückt für eine Weile, bis ich gelesen habe, dass Ich muss vergrößern, die Kontrolle rect für ButtonRenderer.OnDrawItem
wird einfach überschrieben mit derDrawMode
Eigenschaft; warum muss ich Tauchen Sie ein inSetStyle
überschreibenOnPain
? seufz ... naja, job-Sicherheit, glaube ich 😀e.Graphics
.Ich hatte dieses problem selbst und die Antwort von pepoluan habe mich begonnen. Ich denke immer noch ein paar Dinge, die fehlen, um eine ComboBox mit Aussehen und Verhalten ähnlich zu den standard-ComboBox mit DropDownStyle=DropDownList obwohl.
DropDownArrow
Wir müssen auch ziehen die DropDownArrow. Ich spielte mit der ComboBoxRenderer, aber es zieht einen dunklen Rand rund um den Bereich der drop-down-Pfeil (), dass hat nicht funktioniert.
Meine Letzte Lösung war einfach zeichnen ein ähnliches Pfeil und Rendern Sie auf die Schaltfläche in der OnPaint-Methode.
Heiße Element Verhalten
Wir müssen auch sicherstellen, dass unsere ComboBox hat eine heiße Element Verhalten ähnlich wie die standard-ComboBox. Ich kenne keine einfache und zuverlässige Methode, zu wissen, Wann eine Maus ist nicht mehr über die Steuerung. Daher schlage ich vor, mit einem Timer, der überprüft bei jedem tick, ob sich die Maus noch über der Kontrolle.
Bearbeiten
Soeben ein KeyUp-event-handler, um sicherzustellen, dass die Kontrolle korrekt aktualisiert, wenn eine Auswahl getroffen wurde mithilfe der Tastatur. Auch eine kleine Korrektur, wo der text gerendert wurde, um sicherzustellen, dass es ist ähnlich wie die Vanille combobox' text-Positionierung.
Unten ist der komplette code von meiner ComboBox angepasst. Es ermöglicht Ihnen die Anzeige Bilder für jedes Element und wird immer dargestellt, als in den DropDownList-style, aber hoffentlich sollte es leicht sein, um Platz für den code, um Ihre eigene Lösung.