Pochi minuti fa ho dovuto popolare un menù su una Windows Form con i membri dell'enum MdiLayout. La WF è ovviamente una form MDI Parent, che può hostare al suo interno tante child. Il menù permette all'utente di riposizionare (layout) le form child secondo le 4 tradizionali modalità (Cascade, Tile Horizontal, Tile Vertical e Arrange Icons). Possiamo creare a mano i ToolStripMenuItem attraverso il designer, oppure possiamo andare via Reflection per ottenere i membri e creare le voci di menù dinamicamente, sfruttando nel contempo la proprietà Tag per mantenere il riferimento al membro MdiLayout corrispondente. In codice C# il tutto si traduce in:
private void frmFather_Load(object sender, EventArgs e)
{
Type type = typeof(MdiLayout);
foreach (FieldInfo info in type.GetFields())
{
if (!info.IsSpecialName)
{
ToolStripMenuItem itm = new ToolStripMenuItem(info.Name);
itm.Tag = (MdiLayout)info.GetValue(info);
itm.Click += new EventHandler(layoutWindows);
layoutToolStripMenuItem.DropDownItems.Add(itm);
}
}
}
Il form frmFather è il form MDI Parent, di cui vado a gestire l'evento Load. In questo handler, ottengo un riferimento al tipo (Type) dell'enum MdiLayout, faccio un foreach su tutti i FieldInfo, escludendo quelli la cui proprietà IsSpecialName è true. Verificare che IsSpecialName sia false permette di escludere il membro privato Int32 che ogni enum possiede - controllare con Reflector per maggiori dettagli. Per ciascuno di essi, creo un ToolStripMenuItem e gli do un testo uguale al nome del membro. Nella proprietà Tag (che è object) metto un riferimento al valore di MdiLayout con una semplice chiamata a GetValue esposto dalla classe Type. L'handler per le 4 voci di menù è lo stesso, e l'ho chiamato layoutWindows. Il codice per l'evento Click è il seguente:
void layoutWindows(object sender, EventArgs e)
{
ToolStripMenuItem item = (ToolStripMenuItem)sender;
MdiLayout newLayout = (MdiLayout)item.Tag;
this.LayoutMdi(newLayout);
}
Posso castare sender ad un'istanza di ToolStripMenuItem, poi posso castare il suo Tag ad un valore dell'enum MdiLayout ed infine utilizzare questo valore nella chiamata al metodo LayoutMdi. La conclusione di tutto ciò è che quando frmFather contiene più child, e l'utente clicca su una delle 4 voci, le form child vengono reimpaginate automaticamente. L'unica cosa da migliorare sarebbe il testo, perchè adesso appare 1) in inglese 2) tutto attaccato, esattamente come si chiamano i membri dell'enum.