Agganciare un elemento grafico, come ad esempio un’immagine o un’icona, ai propri menu richiede poche righe di codice.
Tutta la logica deve essere infatti implementata in due eventi del MenuItem
che devono essere gestiti: DrawItem
e MeasureItem
. Definiamo perciò due metodi che verranno richiamati all’interno delle due routine di gestione degli eventi: tanto per cominciare definiamo il metodo che gestirà l’evento MeasureItem.
Private Sub MeasureMenuItem(ByVal myMenuItem As MenuItem, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Dim altezza, larghezza As Integer Dim misureDelTesto As SizeF misureDelTesto = e.Graphics.MeasureString(myMenuItem.Text, SystemInformation.MenuFont) altezza = SystemInformation.MenuHeight larghezza = SystemInformation.MenuCheckSize.Width + Convert.IoInt32(misureDelTesto.Width) e.ItemHeight = altezza e.ItemWidth = larghezza End Sub
Il codice non fa altro che aumentare la larghezza del MenuItem
per comprendere il segno di spunta (anche se poi in realtà ci disegneremo ben altro).Definiamo ora il metodo che gestisce l’evento DrawItem
.
Private Sub DrawMenuItem(ByVal myMenuItem As MenuItem, ByVal e As System.Windows.Forms.DrawItemEventArgs, ByVal icon As System.Drawing.Icon) Dim coloreTesto, coloreSfondo As Color Dim rettangoloImmagine As System.Drawing.Rectangle Dim altezzaCarattere, margineVerticale As Single Dim rettangoloTesto As RectangleF Dim selezionato As Boolean selezionato = ((e.State And DrawItemState.Selected) = DrawItemState.Selected) If selezionato Then coloreTesto = SystemColors.HighlightText coloreSfondo = SystemColors.Highlight Else coloreTesto = SystemColors.MenuText coloreSfondo = SystemColors.Menu End If rettangoloImmagine = New Rectangle(e.Bounds.X, e.Bounds.Y, SystemInformation.SmallIconSize.Width, SystemInformation.SmallIconSize.Height) altezzaCarattere = e.Graphics.MeasureString(myMenuItem.Text, Me.Font).Height margineVerticale = e.Bounds.Height - altezzaCarattere rettangoloTesto = New RectangleF(e.Bounds.X + rettangoloImmagine.Width, e.Bounds.Y + (margineVerticale / 2), e.Bounds.Width - rettangoloImmagine.Width, e.Bounds.Height - margineVerticale) e.Graphics.FillRectangle(New SolidBrush(coloreSfondo), e.Bounds) e.Graphics.DrawIcon(icon, rettangoloImmagine) e.Graphics.DrawString(myMenuItem.Text, Me.Font, New SolidBrush(coloreTesto), rettangoloTesto) End Sub
Innanzitutto la routine determina se il MenuItem è evidenziato o meno per attribuire il colore del testo e dello sfondo; poi crea il rettangolo che conterrà l’immagine e quello che conterrà il testo; disegna un rettangolo pieno con il colore di sfondo sul MenuItem
, infine disegna immagine e testo, ciascuno nel suo rettangolo.
Manca solo un ultimo passaggio, anzi due: gli eventi del MenuItem
:
Private Sub miFileFineLavoro_MeasureItem(ByVal sender As Object, ByVal e As MeasureItemEventArgs) Handles miFileFineLavoro.MeasureItem MeasureMenuItem(CType(sender, MenuItem), e) End Sub Private Sub miFileFineLavoro_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles miFileFineLavoro.DrawItem DrawMenuItem(CType(sender, MenuItem), e, System.Drawing.SystemIcons.Error) End Sub
In tutto questo, sono solamente due le parti da modificare: il nome del MenuItem
interessato (ovviamente) e l’icona da attribuire al MenuItem
stesso!