Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

[MCAD.22] Un nuovo Windows Form per lavorare con i database, pronti con ADO.NET

Nel mio ultimo (ormai lontano) post relativo ad MCAD, avevo scritto delle funzioni in grado di leggere e scrivere files XML usando i metodi messi a disposizione dalla classe DataSet. Usando ReadXMLWriteXML, siamo riusciti a salvare su disco l'elenco dei nostri compleanni, così da non dover tutte le volte popolare la ListBox che abbiamo messo sulla Windows Form principale della nostra applicazione. Queste funzionalità hanno reso l'utilizzo della nostra piccola applicazione un po' più semplice ed intelligente. Riprendiamo il discorso preparandoci ad affrontare al meglio le insidie di ADO.NET!

Ecco l'interfaccia di Age come si presenta fino ad oggi. Il menù File incorpora in questo momento quasi tutte le funzioni che ho descritto dettagliatamente nei post precedenti: anteprima di stampa, imposta pagina, salvataggio e caricamento su files XML, etc.

Ho intenzione di aggiungere due menù nuovi di fianco a File: View e Database. Il primo (mnuView) ci permetterà di giocherellare un po' con il data-binding di .NET, ma lo vedremo molto, molto più avanti. Il secondo (mnuDatabase) comprende per adesso un solo MenuItem chiamato mnuSetup , che vediamo nel post di oggi.

Che cosa vogliamo fare esattamente?
Beh, innanzitutto chiariamoci un attimo le idee su quello che vogliamo fare. Dopo aver visto come lavorare con DataTable e DataSet nei post precedenti, voglio darmi da fare con qualche database fisico, nello specifico SQL Server. Ho pensato quindi di dotare la nostra applicazione Age di una funzione di "esportazione" dei dati verso una tabella di SQL Server. Quindi, vedremo come lavorare con SqlConnection e SqlCommand per connetterci ad un database e per creare da zero una tabella adatta a contenere le istanze della classe Age che abbiamo inserito nella nostra ListBox.

E poi? Beh, una volta che la tabella è stata creata, creeremo una funzione di esportazione che la popoli. Il tutto vedendo le classi principali per lavorare con ADO.NET, mantenendo uno ed un solo obiettivo principale: la certificazione MCAD . Quindi, useremo DataAdapter, costrutti SELECT, UPDATE ed INSERT INTO per lavorare sui database e quant'altro. Possiamo procedere? C'è qualcuno che mi ascolta?

Velocemente...aggiungiamo un nuovo Windows Form
Innanzitutto occorre creare un nuovo WF, che io ho chiamato frmConnection. Questo WF permetterà all'utente di specificare quale tipo di database vuole gestire e la stringa di connessione per lavorare su questo database. Senza dilungarci troppo, ecco l'aspetto della form che ci serve:

Sappiamo come creare Windows Form, vero? Riassumendo: due GroupBox, due RadioButton, una TextBox e due Button per chiudere la WF confermando o annullando le modifiche. Lo so che sembra semplice, eppure qualcosa di interessante da osservare c'è.
La form dispone di due property TypeDB e DBConnection, il cui codice get/set è riportato qui:

public string TypeDB
{
    
get
    
{
        
if(this.optAccess.Checked)
            
return("ACCESS");
        
else
            return
("SQLSERVER");
    }
    
set
    
{
        
if(value == "ACCESS")
            
this.optAccess.Checked = true;
        
else
            this
.optSQLServer.Checked = true;
    }
}

public string DBConnection
{
    
get
    
{
        
return(this.txtConnection.Text);
    }
    
set
    
{
        
this.txtConnection.Text = value;
    }
}

Le property sono entrambe di tipo string, e ritornano rispettivamente il tipo di database e la stringa di connessione, appunto. Notare che i membri privati delle rispettive property non esistono, o meglio, esistono eccome , ma fanno diretto riferimento alle properties dei controls sulla WF: il membro privato di DBConnection non è nient'altro che la property Text del control txtConnection, mentre il membro privato di TypeDB viene ritornato banalmente con una semplice if , per capire quale RadioButton è selezionato (può essere "ACCESS" oppure "SQLSERVER").

Altra cosa interessante: la classe Button dispone della property DialogResult . A cosa serve? Quando una WF viene trattata come una form di dialogo (visualizzandola con il metodo ShowDialog ), ritorna un valore dall'enum  DialogResult cosicchè possiamo capire in che modo l'utente ha chiuso la form: ha chiuso cliccando Ok, oppure ha chiuso cliccando Cancel? La differenza, come potete ben immaginare, è molto molto diversa. Quindi, per spiegarmi meglio:

// estratto da InitializeComponent
// btnOk e btnCancel
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK;
// frmConnection
this.AcceptButton = this.btnOk;
this.CancelButton = this.btnCancel;

Direi che la Form è conclusa qui: manca un grosso dettaglio, ma sarà tema del prossimo post.

Velocemente...un nuovo handler, ecco a voi...mnuSetup_Click!
Ho introdotto la struttura della nuova form. Come fa l'utente ad aprirla? Niente di più semplice! Ricordate il menù mnuDatabase che ho descritto prima? Questo menù comprende un solo MenuItem chiamato mnuSetup , il cui codice è il seguente:

private void mnuSetup_Click(object sender, System.EventArgs e)
{
    
// Recupero da app.config i valori correnti
    // tipo di database e stringa di connessione
    
System.Configuration.AppSettingsReader read = new System.Configuration.AppSettingsReader();
    
string TypeDB = (string) read.GetValue("TypeDB", typeof(System.String));
    
string DBConnection = (string) read.GetValue("DBConnection", typeof(System.String));

    DialogResult res;
    frmConnection frmNewForm = 
new frmConnection();
    frmNewForm.TypeDB = TypeDB;
    frmNewForm.DBConnection = DBConnection;
    res = frmNewForm.ShowDialog();

    
// se l'utente chiude il form cliccando su Ok,
    // chiedo se vuole salvare le nuove impostazioni
    
if (res == DialogResult.OK)
    {
        
// se clicco Ok, ma non ho cambiato nulla,
        // evito di chiedere all'utente e di salvare
        // su XML, perchè è rimasto tutto invariato
        
if((frmNewForm.TypeDB != TypeDB) || (frmNewForm.DBConnection != DBConnection))
        {
            res = MessageBox.Show("Salvare le nuove impostazioni ?", "Conferma!", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            
if (res == DialogResult.Yes)
            {
                
// salvare i nuovi valori da qualche parte
            
}
        }
    }

    frmNewForm.Dispose();
}

In breve. Usando la classe AppSettingsReader, leggiamo il file app.config, recuperiamo i valori correnti di TypeDB e DBConnection. Istanziamo la form frmNewForm appartenente alla classe frmConnection, e lo visualizziamo tramite ShowDialog(). Notare che prima di visualizzarlo imposto le sue property TypeDB e DBConnection: se guardate il blocco di codice set delle properties più sopra, vi accorgerete che impostare le properties equivale a tutti gli effetti impostare le properties del controls. In questo modo, appena la form apparirà sullo schermo, mostrerà direttamente i valori correnti.

Torniamo a noi. Il metodo ShowDialog() memorizza in res il DialogResult. Quindi, if (res == DialogResult.OK), vuol dire che l'utente ha chiuso cliccando su Ok, per cui dobbiamo salvare i nuovi valori di TypeDB e DBConnection. Giusto per mettere una ciliegina sulla torta, salvo solamente se l'utente ha effettivamente cambiato qualcosa (questo è il motivo del secondo if). Dopo un messaggio di conferma, bisognerebbe salvare i nuovi valori sul app.config: in realtà questo metodo è sconsigliato, come mi rispose Corrado molto, molto tempo fa (in una galassia lontana lontana). Ho comunque omesso il codice, che esula dall'intento di questo post.

Cosa abbiamo fatto? Cosa dovremo fare?
In questo post non abbiamo visto cose particolarmente nuove, vero? Abbiamo predisposto una nuova voce nel nostro MainMenu, abbiamo creato una nuova Form predisposta per gestire il tipo di database e la stringa di connessione. L'interfaccia a questo punto è qualcosa di simile a questo:

L'obiettivo, che completeremo nel prossimo post, è il seguente. Avete presente il pulsante Ok sulla nostra nuova Form? Se l'utente chiude la form cliccando su questo pulsante, significa che desidera confermare la stringa di connessione, specificando così un server, un database, uno username ed una password.

Se viene cliccato Ok, quindi, vogliamo, nell'ordine:

  1. testare la connessione al server, usando SqlConnection
  2. se la connessione funziona, verificare la presenza della tabella ListBirthdays
  3. se la tabella esiste, tutto ok, la form può essere chiusa senza problemi
  4. se la tabella non esiste, occorre lanciare la stored-procedure SettingUp che provvede a creare la tabella ListBirthdays
  5. se tutto fila liscio, la form può essere chiusa

Adesso che siamo pronti (finalmente), nel prossimo post parleremo veramente di ADO.NET.

powered by IMHO 1.2

Print | posted on mercoledì 24 agosto 2005 18:17 | Filed Under [ MCAD ]

Feedback

Gravatar

# re: [MCAD.22] Un nuovo Windows Form per lavorare con i database, pronti con ADO.NET

assolutamente d'accordo su tutti e due punti.
il punto (b), tra l'altro, proprio non lo conoscevo...adesso, nell'handler mnuSetup_Click ho scritto così:

string TypeDB = ConfigurationSettings.AppSettings["TypeDB"];
string DBConnection = ConfigurationSettings.AppSettings["DBConnection"];

e funziona e meraviglia!!!!
grazie!
24/08/2005 20:15 | Igor Damiani
Gravatar

# [MCAD.23] SqlConnection e SqlCommand: primi passi con ADO.NET

25/08/2005 20:27 | Technology Experience
Gravatar

# [MCAD.24] Alcuni miglioramenti del codice

26/08/2005 17:38 | Technology Experience
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET