Nella creazione di un'applicazione di tipo grafico, mi sono trovato di fronte alla necessità di riunire, in un unico pulsante, più funzionalità, ma mi sono reso conto ben presto che i controlli forniti dall'IDE di Visual Basic 2008 Express non contengono uno strumento adatto ai miei scopi.
Avevo bisogno di fare in modo che più funzioni dello stesso genere fossero raggiungibili e selezionabili attraverso la pressione di un solo pulsante. Pensate ai programmi di grafica o ai CAD dove, ad esempio, i comandi di ZOOM sono molti e ognuno con una specifica azione da svolgere ( Zoom Avanti, Zoom Indietro, Zoom Area, Zoom Tutto...). Collocare queste funzioni all'interno dei menù risulta piuttosto scomodo da usare e aggiungere un'icona per ognuna delle azioni, riempe troppo l'area dello schermo. Ogni applicazione che ha questo tipo di esigenza ha visto implementare in essa una propria soluzione:
Un pulsante che se viene tenuto premuto fa apparire un menù con le scelte possibili.
Un pulsante che se viene tenuto premuto fa apparire una seconda toolbar con tutte le possibili icone.
Un pulsante che se viene premuto fa apparire al centro dello schermo una lista di pulsanti con tutte le possibili opzioni.
...
Personalmente ho pensato di creare un pulsante che permette di cambiare le icone attraverso l'uso della rotellina del mouse o dei pulsanti SU/GIÙ ad esso affiancati. L'idea mi è venuta guardando alcune immagini di Slot Machines trovate in rete.
Allego l'immagine del pulsante finale.
Si tratta di creare un button affiancato da 2 piccoli pulsanti, premendo i quali si può vedere scorrere verso l'alto o verso il basso, tutte le icone assegnate a questo controllo, come se fossero disegnate su un rullo e questo potesse ruotare in entrambi i sensi per poterci permettere di scegliere quella che preferiamo. Ovviamente una volta deciso quale funzione utilizzare, il controllo deve essere in grado di capire quale azione deve compiere quando il pulsante viene premuto.
Verrà implementato un unico metodo pubblico che consentirà di inserire le icone/immagini che desideriamo e una breve descrizione delle loro funzionalità.
ATTENZIONE! Il programma può caricare immagini di tipo JPEG, BMP, PNG e ICO, ma non le librerie di icone.
Avviate Visual Basic 2008 Express e create un nuovo progetto di tipo "Applicazione Windows Form", assegnandoli un nome significativo.
Dal menù "Progetto" selezionate la voce "Aggiungi controllo utente..." e nella finestra che appare inserite "ScrollButton" come nome per il proprio controllo.
Impostate le seguenti proprietà:
ScrollButton:
Name:ScrollButton
Margin:0;0;0;0
Maximum Size:60;40 (imposta la dimensione max del controllo impedendo un cambiamento delle sue dimensioni)
Minimum Size:60;40 (come Maximum Size per la dimensione minima)
Size:60;40
Quindi aggiungete 3 Button , un Timer e un controllo ToolTip assegnando loro queste proprietà:
Button1:
Name:btnIcona
Location:0;0
Margin:0;0;0;0
Size:40;40
Button2:
Name:btnUp
Font:Wingdings 3; 8,25pt(o qualunque font che abbia i simboli freccia su e giù)
Location:40;0
Margin:0;0;0;0
Size:20;20
Text:p (o qualunque carattere che nel font scelto rappresenta una freccia rivolta in alto)
Button3:
Name:btnDown
Font:Wingdings 3; 8,25pt(o qualunque font che abbia i simboli freccia su e giù)
Location:40;20
Margin:0;0;0;0
Size:20;20
Text:q (o qualunque carattere che nel font scelto rappresenta una freccia rivolta in basso)
Timer1:
Name:Timer1
Enabled:True
interval:10
ToolTip1:
Name:ToolTip1
BackColor:White
ShowAlways:True
Use Animation:False
Use Fading:False
Inserite il seguente codice:
Public Class ScrollButton 'Definizione dell'indice dell'immagine Nuova, quella che appare dopo avere premuto i tasti SU/GIÙ o usato la rotellina Private intImmagineNuova As Integer = 0 'Definizione delle due immagini: quella Vecchia che scompare e quella Nuova che appare Private immagineVecchia, immagineNuova As Bitmap 'Definizione delle coordinate Y delle due immagini Private yVecchia, yNuova As Integer 'Impostazione dei flag per determinare se viene fatta scorrere la lista verso l'alto o verso il basso Private scorreSu, scorreGiu As Boolean 'Impostazione del flag per determinare se il mouse è sopra il pulsante (TRUE) o al di fuori di esso (FALSE) Private chkFocus As Boolean = False 'Impostazione del testo da visualizzare come descrizione Private testo As String = Nothing 'Impostazione del flag per determinare se sono state caricate (TRUE) o meno (FALSE) delle immagini nel pulsante Private chkListaInserita As Boolean = False 'Lista che contiene l'elenco delle immagini Private _listaImmagini As New ImageList 'Lista che contiene l'elenco delle descrizioni Private _descrizione As New List(Of String) 'Definizione dell'evento relativo al click del mouse sullo ScrollButton Public Event Icona_MouseClick(ByVal nIcona As Integer) Public Sub New() InitializeComponent() _listaImmagini.ImageSize = New Size(32, 32) yVecchia = -34 yNuova = 4 End Sub ''' <summary> ''' Metodo per inserire le immagini da caricare e il relativo testo ''' </summary> ''' <param name="img">immagine da caricare</param> ''' <param name="descr">descrizione allegata</param> ''' <remarks></remarks> Public Sub InserisciImmagini(ByVal img As Bitmap, ByVal descr As String) _listaImmagini.Images.Add(img) _descrizione.Add(descr) immagineNuova = _listaImmagini.Images.Item(0) immagineVecchia = immagineNuova chkListaInserita = True End Sub ''' <summary> ''' Metodo per inserire un icona da caricare e il relativo testo ''' </summary> ''' <param name="icona">icona da caricare</param> ''' <param name="descr">descrizione allegata</param> ''' <remarks></remarks> Public Sub InserisciImmagini(ByVal icona As Icon, ByVal descr As String) _listaImmagini.Images.Add(icona) _descrizione.Add(descr) immagineNuova = _listaImmagini.Images.Item(0) immagineVecchia = immagineNuova chkListaInserita = True End Sub ''' <summary> ''' Metodo per inserire le immagini da caricare da file e il relativo testo ''' </summary> ''' <param name="img"></param> ''' <param name="descr"></param> ''' <remarks></remarks> Public Sub InserisciImmagini(ByVal img As String, ByVal descr As String) _listaImmagini.Images.Add(Image.FromFile(img)) _descrizione.Add(descr) immagineNuova = _listaImmagini.Images.Item(0) immagineVecchia = immagineNuova chkListaInserita = True End Sub 'Esposizione e consumo dell'evento Icona_MouseClick Private Sub btnIcona_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles btnIcona.MouseClick If _listaImmagini.Images.Empty = True Then Exit Sub Dim indice As Integer = intImmagineNuova Mod _listaImmagini.Images.Count If indice < 0 Then indice = _listaImmagini.Images.Count + indice End If RaiseEvent Icona_MouseClick(indice) End Sub 'Evento per ottenere il focus sul pulsante quando il mouse vi staziona sopra Private Sub btnIcona_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles btnIcona.MouseHover Me.btnIcona.Focus() End Sub 'Sub per realizzare l'animazione della rotazione delle immagini con l'uso della rotellina Private Sub btnIcona_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles btnIcona.MouseWheel Dim chk As Integer = intImmagineNuova immagineVecchia = immagineNuova intImmagineNuova += CInt(e.Delta / 120) Visualizza() If (intImmagineNuova - chk) > 0 Then yVecchia = 4 yNuova = 42 scorreSu = True Else yVecchia = 4 yNuova = -34 scorreGiu = True End If ToolTip1.SetToolTip(Me.btnIcona, testo) ToolTip1.SetToolTip(Me.btnDown, testo) ToolTip1.SetToolTip(Me.btnUp, testo) End Sub 'Sub per determinare l'animazione della rotazione delle immagini con l'uso del pulsante GIÙ Private Sub btnDown_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDown.Click immagineVecchia = immagineNuova intImmagineNuova -= 1 Visualizza() yVecchia = 4 yNuova = -34 ToolTip1.SetToolTip(Me.btnIcona, testo) ToolTip1.SetToolTip(Me.btnDown, testo) ToolTip1.SetToolTip(Me.btnUp, testo) scorreGiu = True End Sub 'Sub per determinare l'animazione della rotazione delle immagini con l'uso del pulsante SU Private Sub btnUp_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUp.Click immagineVecchia = immagineNuova intImmagineNuova += 1 Visualizza() yVecchia = 4 yNuova = 42 ToolTip1.SetToolTip(Me.btnIcona, testo) ToolTip1.SetToolTip(Me.btnDown, testo) ToolTip1.SetToolTip(Me.btnUp, testo) scorreSu = True End Sub 'Sub per realizzare il movimento di scorrimento verso l'alto o il basso al trascorrere del tempo Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick If scorreSu Then yVecchia -= 2 yNuova -= 2 If yVecchia <= -33 AndAlso yNuova = 4 Then scorreSu = False End If If scorreGiu Then yVecchia += 2 yNuova += 2 If yVecchia >= 42 AndAlso yNuova = 4 Then scorreGiu = False End If Me.btnIcona.Invalidate() If scorreGiu = False AndAlso scorreSu = False Then Visualizza() End Sub 'Sub per visualizzare le immagini e il testo caricate all'interno del pulsante Private Sub Visualizza() If chkListaInserita Then Dim numeroImmagini As Integer = _listaImmagini.Images.Count Dim valore As Integer = intImmagineNuova Mod numeroImmagini For i As Integer = 0 To numeroImmagini - 1 If i = valore OrElse (i - numeroImmagini) = valore Then immagineNuova = _listaImmagini.Images.Item(i) testo = _descrizione.Item(i) Exit For End If Next End If End Sub 'Sub per disegnare le immagini sul pulsante Private Sub btnIcona_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles btnIcona.Paint If chkListaInserita Then e.Graphics.DrawImage(immagineVecchia, 4, yVecchia, 32, 32) e.Graphics.DrawImage(immagineNuova, 4, yNuova, 32, 32) End If End Sub End Class