Comment personnaliser un ComboBox (OwnerDrawFixed) regarde en 3D comme la norme de zone de liste déroulante?
Je fais un custom zone de liste déroulante, hérité de Winforms standard de zone de liste déroulante. Pour ma coutume zone de liste déroulante, j'ai mis DrawMode
à OwnerDrawFixed
et DropDownStyle
à DropDownList
. Puis-je écrire mon propre OnDrawItem
méthode. Mais j'ai fini comme ça:
Comment puis-je faire de ma zone de liste déroulante Personnalisée pour ressembler à la Norme?
Mise À Jour 1: ButtonRenderer
Après avoir cherché partout, j'ai trouvé le ButtonRenderer
de la classe. Il fournit un DrawButton
statique/méthode partagée qui, comme son nom l'indique -- attire le bon bouton 3D. Je suis en train d'expérimenter avec elle maintenant.
Mise à jour 2: Ce qui remplace mon contrôle?
J'ai essayé en utilisant le Graphique des propriétés de divers objets que je pense, mais j'ai toujours l'échec. Enfin, j'ai essayé le Graphique de la forme, et, apparemment, quelque chose d'écrasement de mon bouton.
Voici le 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
Et voici le résultat:
Remplacement Me.Parent.CreateGraphics
avec e.Graphics
m'a ceci:
Et de faire le ci-dessus + le remplacement de Me.ClientRectangle
avec e.Bounds
m'a ceci:
Quelqu'un peut-il m'indiquer dont les Graphiques je dois utiliser pour la ButtonRenderer.DrawButton
méthode?
PS: Le bleuté de la frontière est à cause de mon aide PushButtonState.Par défaut au lieu de PushButtonState.Normal
J'Ai Trouvé Une Réponse! (voir ci-dessous)
problème est, e.Graphique a un Clip qui est En lecture seule. Je suis toujours à la chasse de la manifestation/de code qui dessine le rectangle blanc avec flèche de menu déroulant
J'ai essayé de M'utiliser.CreateGraphics la place de l'e.CreateGraphics, qui devrait vous donner le graphisme de la zone de liste déroulante au lieu de seulement les Éléments de la zone. Il n'a pas complètement le travail, mais ce que j'ai remarqué est que la bonne case a été tiré quand j'ai cliqué sur la zone de liste déroulante, mais puis a été immédiatement retiré lorsque les éléments ont été affichés. Ainsi, le suivant vous donne la bonne case si vous pouvez comprendre comment le faire pour y rester (sans doute besoin d'être dans un autre événement qui peint la zone de liste déroulante lui-même). ButtonRenderer.DrawButton(Me.Les Graphismes, Moi.Limites, VisualStyles.PushButtonState.Normal)
ouais, été à la chasse pour cet événement toute la journée 🙁 ... eh bien, je vais juste dire à mon client "ne Peut pas être fait" 🙂 Merci pour votre aide!
Pourquoi, Microsoft?????
OriginalL'auteur pepoluan | 2011-05-03
Vous devez vous connecter pour publier un commentaire.
J'ai oublié où j'ai trouvé la réponse... je vais modifier cette réponse quand je me souviens.
Mais apparemment, j'ai besoin de régler le
Systems.Windows.Forms.ControlStyles
drapeaux. Surtout laControlStyles.UserPaint
drapeau.Donc, mon
New()
ressemble maintenant à ceci:Et maintenant je peux l'accrocher dans le
OnPaint
événement:Remarque: Oui, le
_ButtonArea
rectangle doit être élargie par 1 pixel pour toutes les directions (haut, bas, gauche, droite), ou bien il n'y aura 1 pixel 'périmètre' autour de la ButtonRenderer qui montre des ordures. Fait de moi un fou pendant un certain temps jusqu'à ce que j'ai lu que Je dois agrandir le Contrôle du rect pour ButtonRenderer.trop complexe, si vous me demandez.
OnDrawItem
est facilement substituée à l'aide de laDrawMode
bien; pourquoi dois-je plonger dansSetStyle
pour remplacerOnPain
? soupir ... eh bien, la sécurité d'emploi, je suppose 😀N'utilisez pas de CreateGraphics. Au lieu d'utiliser celui fourni l'e.Graphique fourni pour vous à partir du paramètre.
si vous avez lu ma Question d'origine et mes Commentaires en vertu de la Question, vous pouvez voir que j'ai a essayé d'utiliser
e.Graphics
.OriginalL'auteur pepoluan
J'ai eu ce problème moi-même et le répondre par pepoluan m'ont commencé. Je pense toujours que peu de choses sont manquantes afin d'obtenir une zone de liste déroulante avec l'apparence et le comportement similaire à la norme ComboBox avec DropDownStyle=DropDownList.
DropDownArrow
Nous avons aussi besoin de tirer les DropDownArrow. J'ai joué un peu avec le ComboBoxRenderer, mais il attire une bordure noire autour de la zone de la flèche du menu déroulant si cela ne fonctionne pas.
Ma dernière solution était tout simplement de dessiner un semblable flèche et le rendre sur le bouton dans la méthode OnPaint.
Point Chaud Comportement
Nous devons également nous assurer de notre zone de liste déroulante a un point chaud comportement similaire à la norme ComboBox. Je ne connais pas de méthode simple et fiable pour savoir quand une souris n'est plus au-dessus du contrôle. Par conséquent, je suggère d'utiliser une Minuterie qui vérifie à chaque itération si la souris reste sur le contrôle.
Modifier
Je viens d'ajouter un gestionnaire d'événement KeyUp pour s'assurer le contrôle de la mise à jour correctement lors de une sélection a été effectuée à l'aide du clavier. A également fait une correction mineure d'où le texte a été rendu, pour s'assurer qu'il est de plus en plus semblables à la vanille zone de liste déroulante " texte de positionnement.
Ci-dessous le code complet de ma zone de liste déroulante personnalisée. Il vous permet d'afficher des images sur chaque élément et est toujours rendu comme dans la DropDownList style, mais j'espère qu'il devrait être facile pour respecter le code de votre propre solution.
OriginalL'auteur rdongart