Ieri Alessio mi ha dato un'idea: da buon utente del mio plug-in, mi ha chiesto di ridurre di un po' (50-60%, dice lui) la dimensione dei Button che contengono le emoticons. Mi è sembrata una buona idea, ma poi ho pensato che fosse una cosa piuttosto soggettiva: c'è chi vorrebbe vederle grandi come una casa, e chi invece vorrebbe vederle minuscole per farcene stare di più a parità di dimensioni.
Cosa c'è di meglio quindi che lasciar decidere a voi? All'interno della soluzione faccio già uso di un file VivendoByteEmoticons.settings, che contiene alcuni settaggi specifici per ciascun utente. Per adesso, l'unico settings si chiama ImageUrl ed è il tag <img/> che viene usato per inserire l'emoticon all'interno del post. Ho quindi aggiunto un altro setting, chiamato Size, di tipo double, con un valore predefinito di 50. Ok, fin qua, ci siamo: abbiamo un post dove l'utente può scrivere la larghezza (e l'altezza, trattandosi di un quadrato) dei Button che contengono gli emoticons.
Come facciamo ad utilizzarlo? Andiamo con calma.
Il WrapPanel è ovviamente definito nello XAML:
<WrapPanel Name="MainPanel" ItemHeight="70" ItemWidth="70"
Grid.Column="0" Grid.Row="1">
</WrapPanel>
Il WrapPanel espone tra le altre cose due proprietà interessanti: ItemWidth e ItemHeight. E' abbastanza chiaro il loro scopo: ogni volta che viene un oggetto alla sua collection Children (un Button) tale oggetto assume le dimensioni indicate da queste due proprietà. Nella prima release, tale dimensione è - come si vede sopra - fissa, cablata nello XAML: 70 punti. Adesso dobbiamo fare in modo di utilizzare il setting Size di cui parlavamo prima. Dovremmo poter scrivere un qualcosa del tipo:
<WrapPanel Name="MainPanel"
ItemHeight="{StaticResource Size}"
ItemWidth="{StaticResource Size}"
Grid.Column="0" Grid.Row="1">
</WrapPanel>
Nello XAML, le proprietà ItemHeight e ItemWidth dello WrapPanel non sono più cablate, ma fanno riferimento alla stessa StaticResource, denominata Size. Ma dove è definita questa risorsa? Ancora una volta, non avrebbe senso definirla nello XAML, perchè in realtà il valore che ci serve deve essere reperito nel file dei settings. E allora?
La soluzione che ho adottato è creare ed aggiungere una risorsa chiamata Size via codice, nel costruttore della classe ChooseEmoticon, che è la Window che contiene lo XAML che definisce il WrapPanel qui sopra. Il costruttore è il seguente:
public ChooseEmoticon()
{
initialize();
InitializeComponent();
populateIcons();
}
Notare la chiamata al metodo initialize(), definito come private. Il metodo contiene...
private void initialize()
{
// Aggiungo la risorsa ItemSize che viene poi usata dal WrapPanel
// per settare ItemWidth e ItemHeight con la sintassi
// {StaticResource Size}
this.Resources.Add("Size", _settings.Size);
// altro codice di inizializzazione
}
La classe Windows espone una proprietà Resources, di tipo ResourceDictionary, attraverso la quale possiamo gestire le risorse via C#. Il codice qui sopra aggiunge una risorsa con key = "Size", ed il cui valore viene prelevato dai settings dell'utente. Occhio che la risorsa deve essere aggiunta alla Window prima della chiamata ad InitializeComponent(). Lo XAML adesso può far uso di una StaticResource attraverso la sintassi ItemHeight="{StaticResource Size}". L'unico svantaggio di questo approccio è che la risorsa non è definita a design-time, e quindi l'editor di VS2005 ci segnala un errore nello XAML, proprio perchè mentre stiamo sviluppando la risorsa Size non esiste ancora. In realtà, si può sistemare anche questo...