Visual Basic .NET introduce un nuovo oggetto, la Windows form, che prende il posto della form delle versioni precedenti; i cambiamenti riguardano in particolare le funzionalità, le nuove caratteristiche e i nuovi metodi supportati. Le Windows form sono il componente fondamentale della piattaforma Microsoft .NET, rispondendo a quelli che sono i requisiti del paradigma della programmazione orientata agli oggetti. Esse consentono di sfruttare in maniera estremamente semplice tutte le caratteristiche di Windows 2000 e XP.
Per utilizzare le Windows form è necessario creare una Windows Application (Applicazione Windows), come abbiamo visto nella precedente lezione. Per aggiungere nuove form al progetto, fare clic con il tasto destro del mouse sul nome del progetto all'interno del Solution Explorer e scegliere Add (Aggiungi), quindi selezionare €Add Windows form (Aggiungi Windows form).
La Windows form è concettualmente molto diversa dalla form di Visual Basic 6. Innanzi tutto nel codice di una Windows form possiamo notare la Sub New, che come abbiamo detto nella lezione "Utilizzo di classi in VB .NET" definisce il costruttore della classe: una Windows form, infatti, è prima di tutto una classe, quindi per essa valgono tutte le considerazioni fatte in precedenza.
Da notare che tale Sub non è direttamente visibile nel codice, ma è contenuta all'interno della regione Windows form designer generated code (Codice generato dal Windows form designer). Sotto la definizione della form, Public Class Form1, compare l'istruzione Inherits System.Windows.Forms.Form: si tratta della classe base da cui ereditano tutte le Windows form. Essa fa parte della base class library, la libreria classi base di .NET. Come si può vedere da tale istruzione, la classe Form è contenuta nel namespace System.Windows.Forms (per una breve descrizione dei namespace, si rimanda alla lezione 3.
Altra novità rispetto alle versioni precedenti di Visual Basic è la routine InitializeComponent, che contiene la definizione e le proprietà di tutti gli elementi dell'interfaccia della form: mentre prima tali informazioni erano contenute nell'intestazione del file .frm e non erano direttamente modificabili da Visual Basic, ora sono chiaramente visibili aprendo il codice della Windows form all'interno di Visual Studio .NET. La routine New può essere usata per replicare le funzionalità dell'evento Form_Initialize, scrivendo il proprio codice dopo la chiamata a InitializeComponent.
facendo doppio clic sulla form, verrà aperto l'editor del codice all'interno della routine Form1_Load, il cui significato è lo stesso che aveva in VB 6. Dopo la lista degli argomenti dell'evento, di cui parleremo tra breve, si può notare un nuovo costrutto: Handles MyBase.Load. Con questa istruzione si indica a Visual Basic che la routine appena dichiarata gestisce l'evento Load del form; MyBase è una parola chiave che permette di riferire la classe in cui ci si trova attualmente (abbiamo infatti detto che la Windows form è una classe) . La conseguenza di questa novità è che i nomi degli eventi in VB .NET non sono più vincolati: è possibile creare Sub con qualsiasi nome, a patto naturalmente che prevedano la corretta lista degli argomenti, e poi associarli a determinati eventi con il costrutto Handles oggetto.evento. Ad esempio, l'evento Load del form potrebbe essere gestito da una Sub Avvio così definita:
Private Sub Avvio(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MsgBox("Hello World!")
End Sub
Dopo aver scritto questo codice, eseguiamo il programma, premendo come di consueto il tasto F5: se non ci sono stati errori di digitazione, verrà visualizzata la seguente finestra:
E' importante notare una cosa: a causa di un bug di Visual Studio .NET, potrebbe succedere che, premendo il tasto F5, il programma venga compilato ma non eseguito. In questo caso è sufficiente premere il tasto , quindi il tasto per avviare correttamente il programma.
Vediamo ora le differenze negli argomenti inviati ad un evento. Innanzi tutto, in VB .NET tutti gli eventi prevedono degli argomenti, a differenza di quanto avveniva nelle versioni precedenti di Visual Basic, in cui eventi del tipo Form_Click e lo stesso Form_Load non avevano alcun argomento. Il primo argomento è sempre di tipo System.Object e permette di identificare l'oggetto che ha generato l'evento: questa informazione è utile, ad esempio, perché con la parola chiave Handles è possibile associare più oggetti alla stessa routine. Ad esempio, inseriamo due pulsanti sulla form, quindi premiamo il tasto F7 per visualizzare il codice del form e scriviamo:
Private Sub Clic(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click, Button2.Click
If sender.Equals(Button1) Then
MsgBox("E' stato fatto clic sul pulsante Button1.")
ElseIf sender.Equals(Button2) Then
MsgBox("E' stato fatto clic sul pulsante Button2.")
End If
End Sub
La lista degli argomenti richiesti da un certo evento è disponibile nella Guida in linea di Visual Basic .NET. Dopo la parola chiave Handles sono stati specificati due eventi, separati da una virgola; in generale, è possibile specificarne un numero arbitrario, a patto che richiedano gli stessi argomenti.
Poiché la Sub Clic viene generata indifferentemente quando si fa clic su Button1 o su Button2, è necessario usare l'oggetto sender per sapere quale dei due pulsanti è stato in realtà premuto; per fare questo, si usa il metodo Equals dell'oggetto, che prende come argomento un altro oggetto e restituisce true se i due oggetti sono uguali.
Il secondo argomento, nel caso dell'evento Load, è di tipo EventArgs, anche se a seconda del tipo di evento può essere diverso; ad esempio, nel caso degli eventi KeyDown, KeyUp, è di tipo System.Windows.Forms.KeyEventArgs. Esso contiene informazioni di vario genere, dipendenti dal particolare tipo di evento a cui si riferisce.
Per fare un esempio, proviamo a intercettare l'evento KeyPress della form; Innanzi tutto posizioniamoci sull'evento relativo. All'interno della finestra del codice, fare clic sulla ComboBox in alto a sinistra e selezionare (base class events): tale categoria raggruppa tutti gli eventi della classe base; fatto questo, nel ComboBox in alto a destra comparirà la scritta (Declarations): fare clic su quest'ultima e scorrere l'elenco fino a selezionare l'evento KeyPress. All'interno dell'editor verrà automaticamente aggiunta la seguente Sub per gestire l'evento:
Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress
End Sub
Supponiamo di voler stampare un messaggio diverso a seconda che si digiti una consonante o una vocale. Il codice da scrivere è:
Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress
Select Case e.KeyChar
Case "A", "E", "I", "O", "U", "a", "e", "i", "o", "u"
MsgBox("E' stata digitata una vocale.")
Case Else
MsgBox("E' stata digitata una consonante.")
End Select
End Sub
L'oggetto e, di tipo KeyPressEventArgs, contiene informazioni sul carattere premuto; in particolare, la proprietà KeyChar restituisce il carattere che è stato digitato.
Quanto detto relativamente agli eventi è valido per la form, ma più in generale per tutti i controlli di Visual Basic .NET.
Una delle cose più importanti da notare è che la proprietà Caption è stata rinominata in Text. Più in generale, le proprietà Caption di tutti i controlli sono state sostituite dalla proprietà Text; a parte il nome diverso, comunque, le due proprietà sono assolutamente analoghe.
Abbiamo detto che una Windows form è una classe: è quindi possibile creare oggetti di tipo form e lavorare con essi come con qualunque altro oggetto. In particolare, quando si vuole aprire una form sopra un altro, è necessario prima dichiarare un oggetto che abbia come tipo la form da visualizzare. Cerchiamo di spiegare meglio questo concetto con un esempio. Dopo aver creato una nuova soluzione, aggiungiamo un secondo form al progetto corrente, oltre a quello che viene creato di default (e che ha nome Form1). Per fare questo, fare clic con il tasto destro del mouse sul nome del progetto all'interno del Solution Explorer e scegliere Add (Aggiungi), quindi selezionare Add Windows form (Aggiungi Windows form). Confermare le impostazioni della finestra di dialogo Add New Item (Aggiungi nuovo elemento) con un clic sul pulsante Open (Apri). Il nome del nuovo form è Form2. Ora aggiungiamo un pulsante sul Form1: l'oggetto CommandButton è stato rinominato in Button; impostiamone la proprietà Text su "Apri secondo form". Facciamo quindi doppio clic sul pulsante per generare la routine che gestisce l'evento clic e scriviamo il codice seguente:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim frm As New Form2()
'Visualizza il Form2.
frm.ShowDialog()
End Sub
La prima dichiarazione definisce un nuovo oggetto frm di tipo Form2 e, tramite la parola chiave New, ne crea una nuova istanza. L'istruzione successiva richiama il metodo ShowDialog di frm: esso corrisponde, nelle precedenti versioni di Visual Basic, al metodo Show con il parametro vbModal, cioè visualizza il Form2 e blocca l'esecuzione di Form1 finché Form2 non viene chiuso. Invece, se vi vuole visualizzare il Form2 senza fermare Form1, è necessario richiamare il metodo Show di frm. Potete scaricare un esempio che mostra l'uso di ShowDialog e Show facendo clic qui.
L'evento QueryUnload è stato rinominato in Closing. Mentre in VB6, per annullare la chiusura della form, era necessario impostare su true la variabile Cancel che faceva parte degli argomenti di QueryUnload, per ottenere lo stesso effetto in VB .NET si deve agire sulla proprietà e.Cancel, come potete osservare dall'esempio seguente:
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
'Annulla la chiusura del form.
e.Cancel = true
End Sub
Per chiudere una form è necessario richiamare il metodo Close della form stessa. Ad esempio, per fare in modo che premendo il pulsante Button1 la finestra venga chiusa, si deve scrivere il codice seguente:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Close()
End Sub
La Windows form introduce numerose nuove proprietà, consentendo di realizzare facilmente operazioni che prima erano possibili sono utilizzando le API di Windows, come impostare le dimensioni massima e minima della finestra (per determinare le quali sono disponibili rispettivamente le proprietà Maximumsize e Minimunsize). Non essendo possibile analizzarle tutte, ci limiteremo ad illustrare le più importanti e quelle che hanno subito cambiamenti rispetto alla versione precedenti di Visual Basic.
Innanzi tutto, le proprietà AcceptButton e CancelButton consentono di impostare il pulsante il cui codice si vuole venga eseguito, rispettivamente, quando si premono i tasti Invio oppure Esc. In pratica, queste due proprietà sostituiscono le precedenti Accept e Cancel del controllo CommandButton. Per impostare tali proprietà, fare clic sulla freccia posta sulla destra di AcceptButton oppure CancelButton nella finestra delle Proprietà: verrà visualizzata una lista da cui è possibile selezionare il pulsante che si vuole associare.
La proprietà borderStyle è stata rinominata in FormborderStyle, ma a parte il cambiamento di nome non ha subito altre modifiche.
La proprietà Menu consente di impostare un menu per il form. Anche il menu e i comandi di menu, infatti, in VB .NET sono trattati come oggetti. Questa proprietà viene esposta perché è possibile definire più oggetti di tipo Menu nell'applicazione, visualizzando di volta in volta quello opportuno, ad esempio in risposta a determinate azioni dell'utente.
Opacity consente di impostare la percentuale di trasparenza della form. La proprietà StartUpPosition è stata rinominata in StartPosition; la proprietà CenterOwner ora si chiama CenterParent. transparentKey permette di definire un colore che apparirà trasparente quando verrà disegnato sulla form.
Ci sono poi altre nuove proprietà supportate dalla form e dai controlli standard. Analizziamo anche in questo caso le più significative.
La proprietà BackgroundImage consente di impostare un'immagine di sfondo. Se il file selezionato ha dimensioni inferiori a quelle del form, verrà automaticamente affiancato fino a coprire l'intera finestra.
La proprietà Cursor sostituisce la proprietà MousePointer. Per impostare un cursore è necessario utilizzare la classe Cursors, come mostrato nell'esempio seguente:
Me.Cursor = Cursors.WaitCursor 'Imposta la clessidra.
Me.Cursor = Cursors.Default 'Ripristina il puntatore predefinito.
Una proprietà completamente nuova è ContextMenu, con cui è possibile associare un menu contestuale alla form, cioè un menu che viene automaticamente richiamato quando si fa clic sulla form con il tasto destro del mouse.
Ora che abbiamo preso familiarità con la Windows form, possiamo analizzare le novità dei controlli standard di VB .NET, che saranno trattate a partire dalla prossima Lezione.