Le avventure in VB.Net di un principiante ex-VB6 - 3
a cura di Oscar Zanin e Diego Cattaruzza (requisiti: Visual Basic Express e SqlServer Express)Premessa
Dopo aver predisposto l'ambiente di programmazione (primo articolo) e il database di esempio (secondo articolo), si può dare inizio allo sviluppo del nuovo progetto. Ma prima...Istallazione di un controllo di terze parti: Krypton Tools
Leggendo i tanti post del sito mi sono imbattuto in uno che parlava di questo tool di controlli. Incuriosito sono andato sul sito del produttore http://www.componentfactory.com/, ho guardato alcuni ScreenCast, l'ho ritenuto molto bello ed elegante e l'ho quindi scaricato ed installato.
Lo sfrutterò per la creazione della parte di applicazione di esempio. Pertanto, dovreste scaricarlo ed installarlo anche voi. Ritengo sia un utile esercizio per capire come potere usufruire di prodotti aggiuntivi rispetto a quelli messi a disposizione dall'IDE di Visual Basic.
Se non vorrete utilizzarlo sarà comunque possibile seguire l'articolo e mettere in pratica il codice. Il tool di controlli verrà infatti utilizzato esclusivamente per cambiare l'aspetto dei form. Tutti gli altri controlli usati saranno standard.La cartella Immagini
Create, allo stesso livello della cartella GesImp\Risorse creata contestualmente al database, la cartella GesImp\Immagini.
Come potete facilmente intuire, vi troveranno collocazione le immagini/icone che utilizzeremo per form e pulsanti.
Il download del set di immagini/icone che io utilizzerò lo potrete effettuare attraverso il link in fondo all'articolo. Sono tutte icone liberamente scaricabili dal sito http://www.everaldo.com e fanno parte del pacchetto Crystal Project Icons.Creazione di un nuovo progetto
Lanciamo ora il Visual Basic. Una volta caricata la Pagina iniziale clicchiamo su Crea Progetto. Si aprirà la form "Nuovo progetto". Nell'elenco dei "Tipi di progetto" selezioniamo Windows; nei "Modelli" Applicazione Windows Form e come "Nome" digitiamo "PrimiPassi".[Diego] Nelle proprietà del progetto, scheda Application, spuntate la casella Enable application framework, assicuratevi di 'non' importare (scheda References) il namespace Microsoft.VisualBasic (Oscar indica le stesse operazioni più avanti, io caldeggio di farlo 'subito', come metodo: create un progetto e apportate immediatamente le eventuali modifiche di impostazione).
Qui, e altrove, noterete che Oscar usa la versione italiana, mentre io preferisco la versione inglese. Questo significa che vi toccherà ragionare di volta in volta cosa intendo dire io o Oscar, a seconda della lingua del vostro prodotto.
Qui, e altrove, ritroverete alcuni concetti e anche codice provenienti da altre fonti, segnatamente la serie "Guarda! Senza mani!", che si consiglia di leggere o rileggere, anche senza seguirne lo sviluppo, dato che non è stato possibile concluderla, per defezione di Sabrina Cosolo, che ne era l'autrice principale.In "Esplora soluzioni" selezioniamo ed eliminiamo la Form1 creata di default, dato che vogliamo usare le Krypton form (se non intendete usufruire del tool di controlli, come detto in precedenza, non eliminate la Form1).
Creiamo la nostra prima classe: Program
Questa sarà la classe di accesso all'applicativo.
In Esplora soluzioni facciamo click con il tasto destro sul nome del progetto, nel menù selezioniamo Aggiungi e quindi Classe, diamo il nome Program.
Il codice è il seguente e verrà spiegato in seguito:Public Class Program <STAThread()> _ Shared Sub Main() 'Avvio l'applicazione Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) Application.Run(New FrmMain) End Sub End Class
- STAThread
- E' un attributo che indica al compilatore che modello di threading utilizzare per lanciare questa applicazione. Lo standard, pur essendo il meno performante, è Single Threaded Apartment (STA). E' possibile utilizzare anche il Multi Threaded Apartment (MTA - MTAThread), ma questo funziona solo se non ci sono chiamate a componenti COM all'interno dell'applicazione, e tutto il codice è rigorosamente managed: basta che ci serva una chiamata ad una Dll non .NET o a un componente .COM e non si può utilizzare.
Noi, poiché useremo Crystal Reports, non possiamo utilizzare l'MTA.- Shared Sub Main()
- E' l'entry point, ovvero il primo metodo chiamato dal sistema operativo quando l'Exe .NET viene lanciato. Il suo scopo è quello di istanziare la classe principale su cui il programma si basa. Usualmente, per i programmi Windows Forms, la classe principale è una form, può essere una MDI per un programma complesso, oppure una normale form. Nel nostro caso sarà la form MDI FrmMain che creeremo in seguito.
Se non specificato diversamente, la chiusura di questa prima form lanciata, termina automaticamente il programma.
La parola Shared davanti al metodo indica che esso è statico e può essere eseguito senza la necessità di istanziare un oggetto. Il metodo Main deve obbligatoriamente essere definito in questo modo.
La parola Sub indica che il metodo Main non ha un valore di ritorno. E' possibile, se necessario, far restituire dal metodo Main un valore intero che indichi lo stato della chiusura dell'applicazione e può essere utilizzato da una eventuale applicazione chiamante.
Nella nostra applicazione, il metodo Main non ha parametri di input nella sua chiamata, ma, volendo, è possibile passare al Main un array di parametri stringa cambiandone la dichiarazione in Shared Sub Main(args As String()), dove args contiene un array di tutti i parametri passati da linea di comando.- Application.EnableVisualStyles()
- E' la chiamata a un metodo statico della classe Application fornita dal Framework .NET che attiva automaticamente la visualizzazione delle form nello stile di Windows XP o superiore; senza questa chiamata, l'applicazione viene visualizzata nello stile di Windows precedenti.
- Application.SetCompatibleTextrenderingDefault(False)
- E' la chiamata ad un altro metodo statico della classe Application; questo metodo è nuovo dal Framework 2.0 e attiva una serie di funzionalità per l'ottimizzazione della visualizzazione delle modifiche ai testi dovute alla localizzazione fornite dalla GDI+ ai controlli di nuova concezione.
La specifica avvisa di non usare questa funzionalità se la vostra applicazione è eseguita all'interno di un browser.- Application.Run(New FrmMain())
- La cosa più importante del metodo Main: la chiamata al metodo Run della classe Application, che istanzia la nostra form principale.
Application.Run informa il sistema che l'oggetto FrmMain governa l'applicazione: quando l'oggetto viene rilasciato, l'applicazione si chiude.Altra cosa da notare è che (adesso) viene segnalato un errore in corrispondenza di FrmMain. Giustamente: ancora non esiste. Quando la creeremo l'errore scomparirà.
Approfitto dell'occasione per consigliare di visualizzare la barra dell'Elenco errori cliccando sulla voce di menù "Visualizza" e quindi su "Elenco errori".Facciamo un primo salvataggio. Nel form che appare digitiamo come nome PrimiPassi, scegliamo come cartella quella creata in precedenza (Gesimp) contenente già le sottocartelle Immagini e Risorse. NON usate "Crea directory per soluzione".
Creazione di progetti accessori
Creiamo ora altri tre progetti aggiungendoli alla soluzione. Sono tre librerie di classi di utilità come quelle descritte negli articoli "Guarda! Senza mani!", suddivise in:
- APP.Base : classi per strutture e funzionalità base
- APP.Data : classi per la gestione dei dati e
- APP.UI : classi per l'interfaccia utente
Vi troveranno posto classi quasi identiche a quelle (a parte l'italianizzazione dei nomi), altre leggermente modificate e altre ancora nuove, create da me.
Clicchiamo sulla voce di menù File, su Aggiungi e quindi su Nuovo progetto.
Nel form che appare selezioniamo in "Modelli" Libreria di classe e diamo il "Nome" APP.Base. Il percorso proposto dovrebbe già essere corretto e puntare alla cartella della soluzione.
Eliminiamo la classe Class1 creata di default.
Ripetiamo la stessa procedura per gli altri due progetti APP.Data e APP.UI.Proprietà dei progetti
Selezioniamo ora in "Esplora soluzioni" il progetto PrimiPassi, clicchiamo sulla voce di menù Progetto e quindi su Proprietà.
Nella scheda Applicazione:
- in nome assembly lasciamo il nome del progetto assegnato in precedenza e quindi PrimiPassi
- in spazio dei nomi di 1° livello (namespace) premettiamo APP al nome (APP.PrimiPassi)
- come tipo di applicazione lasciamo Applicazione Windows
- indichiamo l’icona principale del programma (la stessa che sarà poi usata per la form main). Dalla cartella Immagini creata in precedenza selezioniamo Lurker.ico (il nostro piccolo bebè intimorito dal mondo NET) ;o)
- togliamo la spunta ad Attiva framework applicazione
- Disattivando " Attiva framework applicazione" indichiamo di usare la nostra Sub Main invece di quella standard che crea Visual Basic e che sfrutta le proprietà selezionate in "Proprietà framework applicazione windows".
- impostiamo come oggetto di avvio Sub Main (contenuta in Program)
Nella scheda Compila assicuriamoci che siano impostati:
- Option Explicit a On
- Lasciando Option Explicit a On vogliamo che tutte le variabili debbano essere dichiarate in modo esplicito utilizzando l'istruzione Dim. Se si utilizza il nome di una variabile non dichiarata, in fase di compilazione verrà generato un errore.
- Option Compare a Binary
- Option Strict a On
- Come si può leggere in MSDN, Visual Basic consente di convertire molti tipi di dati in altri tipi di dati. Se tuttavia un valore viene convertito da un tipo di dati a un altro caratterizzato da un livello di precisione o da una capacità inferiore ([Diego] spiegazione alla carlona, un po' mnemonica: cioè i dati vengono 'ristretti', da cui la parola Strict), possono verificarsi perdite di dati. Se questa conversione con restrizione ha esito negativo, si verifica un errore di runtime. Durante la compilazione con l'istruzione Option Strict On tali tipi di conversione vengono notificati in modo che possano essere evitati.
Oltre a non consentire conversioni implicite verso tipi di dati più piccoli, Option Strict genera un errore per l'associazione tardiva. Un oggetto è associato tardivamente quando è assegnato a una variabile dichiarata di tipo Object.
Poiché l'istruzione Option Strict On prescrive una tipizzazione forte, impedisce che avvengano conversioni non intenzionali di tipi con perdita di dati, disattiva l'associazione tardiva e migliora le prestazioni, ci aiuta a non lasciare ambiguità ([Diego] non volute, s'intende; a volte può essere necessario, ma in tal caso è buona pratica impostare Option Strict Off nel solo modulo dove ciò si richiede).
Da quanto precede conseguono le tre impostazioni successive.- Conversione implicita a errore
- Associazione tardiva a errore
- Tipo implicito a errore
- Gli altri su avviso
Nella scheda Riferimenti:
- aggiungiamo all'elenco dei riferimenti ComponentFactory.Krypton.Toolkit (se lo si vuole usare) dalla scheda ".NET" e i progetti di librerie di classe creati in precedenza (APP.Base, APP.Data e APP.UI) dalla scheda "Progetti"
- togliamo il riferimento a Microsoft.VisualBasic
- Quest'ultima impostazione è molto importante, in quanto impone un taglio netto con il passato per chi, come me, proviene dal Visual Basic 6. Toglierla ci impone di sfruttare i metodi del NET e più performanti invece di quelli del Visual Basic 6.
[Diego] Questo non significa che Microsoft.VisualBasic non c'è più, ma solo che ci viene pressocché impedito di usare le stesse vecchie funzioni compatibili-VB6. La libreria rimane nei riferimenti ed è utilissima in tutte le altre cose.I riferimenti rappresentano il passaggio obbligato per permettere ad un progetto di interagire e sfruttare le potenzialità messe a disposizione da componenti esterne allo stesso quali possono essere componenti COM, servizi Web XML, assembly o librerie di classi .NET Framework oppure altre librerie di classi.
I riferimenti hanno rappresentato (e lo sono tuttora) l'elemento del NET che più mi incute timore. Il framework mette a disposizione diversi namespace e un mare di funzionalità ma... spesso mi trovo a dovere far fronte ad una nuova esigenza e mi viene naturale chiedermi sotto quale namespace e relativi elementi di programmazione si troverà. E' un pò come cercare un ago in un pagliaio, per chi è agli inizi come me, e debbo dire che, per quanto mi riguarda, la guida del Visual Basic non mi viene quasi mai in aiuto: la trovo fatta malissimo, è a mio avviso l'elemento peggio riuscito del linguaggio di programmazione. I contenuti sono difficili da trovare e quando li si trova (già, quando!) sono a mio avviso confusionari: mille link ad altre risorse correlate e un po' criptici. Cosa digito come chiavi di ricerca? Ho chiaro cosa voglio realizzare ma i criteri di ricerca che mi vengono in mente di utilizzare spesso sono in italiano (o inglese) corrente e raramente portano a trovare qualcosa di utile. Forse tutto questo è dovuto alla struttura ad albero del framework. Una volta mi è capitato di vedere un poster che illustrava la struttura del primo framework: una cartina stradale dettagliata d'Italia è meno articolata e con il tempo, crescendo, si sarà solo complicata. Probabilmente, per ogni voce, un richiamo al ramo principale di appartenenza potrebbe essere utile, con magari anche tutte le "diramazioni" per arrivare a quello che abbiamo cercato. Insomma per arrivare a capire come risolvere in codice una nuova esigenza spesso mi butto su internet e sui vari forum di programmazione. Trovo che mi restituisca dei risultati più gratificanti e in minor tempo. Tutto è naturalmente opinabile e un grosso contributo lo dà anche la mia ignoranza. Se qualcuno in ascolto non si trova d'accordo e ha la voglia e il tempo di scrivere un articolo su come si usa la guida ... beh .. un lettore lo ha già trovato! ;o)
[Diego] Conosco benissimo questa sensazione di panico, di spaesamento. Ma è soltanto una questione di pratica, di perseveranza. Bisogna prendersi il tempo - un vero e proprio investimento - di 'leggere' (solo leggere, non occorre 'studiare') la gerarchia dei vari namespace del Framework (Nel visualizzatore oggetti troviamo l'albero completo di tutte le librerie referenziate, per esempio. Se aggiungiamo un riferimento, troveremo pure quello). Le denominazioni e le collocazioni che sembrano strane alla nostra 'vecchia' conceizone delle entità con cui abbiamo sempre avuto a che fare ci salteranno immediatamente all'occhio e ce ne ricorderemo. Contemporaneamente, acquisiremo una superficiale infarinatura sulla struttura generale e sapremo cercare, per esempio, l'oggetto Device nel namespace Management, piuttosto che l'oggetto Drive nel namespace IO. Quando poi leggiamo nei forum questa o quella risposta, cerchiamo di approfondire la conoscenza dell'oggetto che ci è stato indicato. E' vero che la guida a volte sembra anche troppo dispersiva, con un sacco di collegamenti (che sono insieme la sua forza e il suo tallone d'Achille), ma è sempre la pratica che prima o poi conduce all'informazione cercata. Inoltre, nella guida c'è sempre anche il namespace completo cui pertiene il singolo elemento che abbiamo trovato, e a sinistra c'è tutto l'albero.
Nella scheda Risorse:
- aggiungiamo tutte le icone e le immagini che verranno usate nelle form del programma. Apriamo l'elenco a tendina "Aggiungi risorsa", clicchiamo su "Aggiungi file esistente", visualizziamo il contenuto della cartella Immagini, selezioniamo tutti i file e confermiamo.
Selezioniamo ora in "Esplora soluzioni" il progetto APP.Base, clicchiamo sulla voce di menù Progetto e quindi su Proprietà.
Lasciamo come sono le impostazioni di scheda Applicazione.
Assicuriamoci che nella scheda Compila le impostazioni siano le stesse di PrimiPassi, e che nella scheda Riferimenti sia assente l'importazione di Microsoft.VisualBasic.Apriamo la pagina delle proprietà del progetto APP.Data.
Lasciamo come sono le impostazioni della scheda Applicazione.
Assicuriamoci che nella scheda Compila le impostazioni siano le stesse di PrimiPassi.
Nella scheda Riferimenti, oltre a togliere l'importazione di Microsoft.VisualBasic, aggiungiamo all'elenco dei riferimenti i progetti di librerie di classe creati in precedenza (APP.Base e APP.UI).Apriamo la pagina delle proprietà del progetto APP.UI.
Lasciamo come sono le impostazioni della scheda Applicazione.
Assicuriamoci che nella scheda Compila le impostazioni siano le stesse di PrimiPassi.
Nella scheda Riferimenti, oltre a togliere l'importazione di Microsoft.VisualBasic, aggiungiamo APP.Base (dalla scheda Progetti) e System.Windows.Forms (dalla scheda .NET) all'elenco dei riferimenti.[Diego] In Esplora Soluzioni, se cliccate su 'mostra tutti i file', probabilmente vedete la cartella Risorse 'bianca' (cioè presente ma non inclusa nel progetto) e non 'gialla' (cioè presente anche 'per' il progetto): cliccate su col pulsante destro del mouse e sceglliete il menu 'Includi nel progetto'.
Non seguite l'eventuale wizard di impostazione di connessione al database, cliccando su Annulla.Conclusione
Con questo articolo, non è ancora teminato lo sviluppo 'generale' del progetto PrimiPassi, ma si può cominciare a rendersi conto della strategia di programmazione che cerchiamo di condividere: si cerca di strutturare la soluzione in modo da dividere progetti e classi a seconda della loro funzionalità.
Nel prossimo articolo si comincerà lo sviluppo di diverse classi accessorie che ci permetteranno di dedicarci con maggior concentrazione al progetto principale.Il progetto sviluppato fino a questo punto (con codice, database e immagini) è scaricabile dall'area download.