Press "Enter" to skip to content

4 – Uno user control per gestire i dati di connessione a SQL Server

In questo quarto post  vedremo l’implementazione del Menu del nostro User Control e i vari tipi di Binding ai dati o funzionale che utilizzeremo per rendere interattiva l’interfaccia utente.

Il Menu del controllo

<MenuItem Name="mnuEdit" Header="{x:Static p:Resources.mnuSCICEdit}"  Click="mnuClick" Margin="2,4,2,2" Height="32" IsEnabled="{Binding IsNotInEditMode}">
<MenuItem.Icon>
	<Image Source="/Dnw.UI.SqlServer.v4.0;component/Images/btn_032_113.png" Height="24" Width="24"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Name="mnuUndo" Header="{x:Static p:Resources.mnuSCICUndo}" ... IsEnabled="{Binding IsChanged}">
...
</MenuItem>
<MenuItem Name="mnuNew" Header="{x:Static p:Resources.mnuSCICNew}" ... >
...
</MenuItem>
<MenuItem Name="mnuClone" Header="{x:Static p:Resources.mnuSCICClone}" ... >
...
</MenuItem>

<MenuItem Name="mnuDelete" Header="{x:Static p:Resources.mnuSCICDelete}" ... IsEnabled="{Binding IsInEditMode}">
...
</MenuItem>
<MenuItem Name="mnuExport" Header="{x:Static p:Resources.mnuSCICExport}" ... IsEnabled="{Binding IsNotInEditMode}">
...
</MenuItem>
<MenuItem Name="mnuImport" Header="{x:Static p:Resources.mnuSCICImport}" ... IsEnabled="{Binding IsNotInEditMode}">
...
</MenuItem>

Ho compattato lo XAML degli elementi del menu e per evidenziare i concetti, eliminando il caos visuale di tanti controlli simili vediamo quali sono i concetti nuovi collegati al menu:

Name: Se ricordate lo XAML di definizione dei controlli  di tipo strutturale, nessuno di questi controlli ha l’attributo Name valorizzato, chi come me proviene da Windows Forms sa bene che in una form, tutti i controlli, anche quelli che non saranno mai referenziati da codice devono per forza avere un identificativo univoco, per WPF invece, il Name non é necessario se non per i controlli con cui vogliamo lavorare da Code Behind, nel caso dei bottoni del menu, il nome ci servirà  per identificarli all’interno dell’event handler del click.

Click: Imposta il nome del metodo che effettua l’handling dell’evento click dei pulsanti del menu,
wpf_uc_10[1]

L’opzione Navigate to Event Handler che appare sul menu contestuale nell’editor XAML ci porta all’event handler quando esiste o ne genera uno nuovo se non esiste.

IsEnabled: Come potete notare, l’attivazione di quasi tutte le opzioni di menu è stata collegata ad una property del Model del controllo.

public bool IsChanged
{
	get
	{
		return mIsChanged;
	}
	set
	{
		mIsChanged = value;
		OnPropertyChanged(FLD_IsChanged);
		OnPropertyChanged(FLD_IsNotChanged);
	}
}

public bool IsNotChanged
{
	get
	{
		return !IsChanged;
	}
}

Il codice della property IsChanged, che all’interno del modello viene posta a true quando i dati del dettaglio vengono modificati dall’utente Vedremo in dettaglio come la cosa funziona.

Header: l’attributo che fornisce la descrizione del menu

Header="_Edit"

Header="{x:Static p:Resources.....}"

Entrambe le rappresentazioni qui sopra sono equivalenti, la descrizione del menu é la scritta che permette di capirne l’uso, L’underscore (_) è il corrispondente dell’ampersand (&) delle WIndows Forms, è stato sostituito perché in XML l’ampersand è un carattere di controllo quindi non sarebbe stato pratico usarlo nelle stringhe, ad ogni modo il carattere dopo l’underscore diviene lo shortcut applicabile tenendo premuto il tasto Alt per cliccare il bottone senza usare il mouse.

wpf_uc_11[1]

Nel nostro XAML, non abbiamo scritto la stringa messa nella prima riga, eppure, il menu appare come sopra. Le descrizioni delle opzioni di menu sono delle stringhe. Come funziona? La parola p:Resources dovrebbe ricordarci qualcosa. Infatti, le stringhe descrittive dei menu si trovano in un File di risorse di tipo stringa, esattamente come nelle Windows Forms, abbiamo aggiunto un file Resources.resx sulla cartella Properties del progetto.

wpf_uc_12[1]

wpf_uc_13[1]

Al suo interno abbiamo definito le stringhe del menu, questo, ci permetterà  di localizzare la nostra applicazione semplicemente generando i file nelle altre lingue Resources.en.resx, Resources.it.resx, e così via.
Torniamo quindi quindi alla nostra stringa di definizione:

Header="{x:Static p:Resources.mnuSCICEdit}"

x:Static indica che stiamo utilizzando un oggetto statico definito in altro luogo. x: lo abbiamo già  trovato, se andiamo in cima al nostro file XAML possiamo anche capire che cos’è¨:

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

In tutti i file XAML prodotti dai template di Visual Studio, troveremo questa dichiarazione, è la dichiarazione del Namespace di base di WPF, tutti i riferimenti che iniziano con x: sono relativi a oggetti specifici di WPF. osservando il file XAML anche solo superficialmente ne incontriamo vari:

  • x:Class sulla prima riga dichiarazione della classe
  • x:Key nella dichiarazione dei nomi di tutte le risorse
  • x:Static ovunque le risorse statiche sono utilizzate

vedremo in quali luoghi lo troveremo ancora.

C’è ancora un elemento che non abbiamo discusso, p: che cos’è? Se x: era la definizione di un namespace, potrebbe essere simile? Esatto, ed in questo caso p: lo abbiamo deciso noi, è l’alias del namespace che contiene il nostro Resources.resx.

xmlns:p="clr-namespace:Dnw.UI.SqlServer.Properties"

Questa dichiarazione, che troviamo sempre in cima al nostro file XAML indica che l’alias p: verrà  sostituito dal namespace di tipo .NET (clr-namespace) indicato.

Un ultima cosa importante per l’uso di risorse di tipo stringa, se volete utilizzare delle stringhe di risorsa all’interno di XAML è indispensabile che il file di risorse sia pubblico:

wpf_uc_14[1]

Se non ricordate di indicare che le stringhe di risorsa sono Public, il progetto compilerà  ma a runtime avrete un errore di “Risorsa non trovata”, quindi ricordatevene se utilizzerete questa funzionalità .

L’ultima porzione del menu che non abbiamo ancora esplorato è quella relativa alla gestione delle immagini collegate alle opzioni di menu

<MenuItem.Icon>
	<Image Source="/Dnw.UI.SqlServer.v4.0;component/Images/btn_032_113.png" Height="24" Width="24"/>
</MenuItem.Icon>

In questa porzione di codice la cosa interessante è vedere come viene collegata l’immagine al controllo Image, l’attributo Source di un campo Image può essere collegato in binding ad un elemento del Model del controllo, come vedremo nel dettaglio della Main Instruction del nostro controllo oppure può contenere un URI (Unique Resource Identifier) che identifica una risorsa di tipo BitmapImage all’interno di una libreria. Il formato di un URI è lo stesso di quello di un link http o un link ftp, in questo caso nel file XAML viene omesso il prefisso che evidentemente è gestito automaticamente:

pack://application:,,,

Vedremo in seguito che quando indicati nel code behind, gli URI devono avere questo prefisso per funzionare correttamente. Il formato di un URI in XAML è il seguente

/AssemblyName;component/path/filename

Nel nostro caso Dnw.UI.SqlServer.v4.0 è il nome dell’assembly, /Images/ è il  path, btn_032_113.png è il nome del file che contiene la risorsa.

wpf_uc_15[1]

In questa quarta porzione della serie di articoli sulla realizzazione di uno User Control WPF abbiamo proseguito l’esplorazione delle funzionalità  di Binding e dell’uso delle risorse in WPF proseguiremo nel prossimo post addentrandoci nei controlli di dettaglio del nostro User Control.

Il progetto di esempio che contiene il codice come sarà alla fine della serie è disponibile nella nuova versione delle librerie di uso comune a questo indirizzo:

Per qualsiasi domanda, curiosità approfondimento, potete usare il link al modulo di contatto in cima alla pagina.

Aggiungo i riferimenti alle librerie di supporto che saranno utilizzate anche negli articoli successivi.