Technology Experience
.NET World

WPF: gestire un ContextMenu con una TextBox interna

Guardate questo screenshot:

E’ lo screenshot di FlickrBrowser, il software in WPF che mi sto divertendo a creare nel tempo libero. Nella figura qui sopra, c’è l’elenco di 4 set fotografici: Microsoft Security Workshop VII, Giornata Azzurra 2007, AvioExpo 2007 e Nove Colli (Fiat 500) – 2007 – Fabio Edition. Il secondo set fotografico è selezionato: se ci facciamo sopra doppio-click, otteniamo la figura qui sotto:

In pratica, una ListBox orizzontale che visualizza tutte le foto associate al set fotografico che abbiamo selezionato. Ho associato un ContextMenu ad ogni Image, che ovviamente appare cliccando col pulsante destro del mouse. Il ContextMenu è stato inserito fra le risorse della Window; vi riporto lo XAML qui sotto.

<Window.Resources> <ContextMenu Name="mnuPhotoContextMenu" x:Key="menu" Opened="ContextMenuOpened"> <ContextMenu.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Yellow" Offset="0.0" /> <GradientStop Color="White" Offset="1.0" /> </LinearGradientBrush> </ContextMenu.Background> <MenuItem Header="Tags" Click="TagsMenuClick" /> <MenuItem Header="Save As" Name="mnuSaveAs"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Path :" /> <TextBox Width="100" Name="txtPath" Text="E:" HorizontalAlignment="Stretch" /> <Button Name="btnDownloadPhoto" Content="Ok" Click="btnDownloadPhotoClick" /> </StackPanel> </MenuItem> <MenuItem Header="EXIF Information" Click="ExifMenuClick" /> <Separator /> <MenuItem Header="Properties" /> </ContextMenu> </Window.Resources>

Al ContextMenu è stato associato un event-handler sull’evento Opened. Il Background del ContextMenu è un semplice gradiente, visibile nello screenshot. Ci sono diversi MenuItem: uno mostra i tag associati alla foto cliccata, un altro permette il Save As (ne parliamo adesso), un altro ancora mostra le informazioni EXIF della foto. L’ultimo, quello associato a Properties, non fa assolutamente un bel nulla.

Parliamo un po’ del Save As che è il più interessante.
Questo MenuItem contiene uno StackPanel con una TextBox ed un Button a fianco. L’utente può digitare un qualsiasi path nella casella di testo e poi cliccare sul Button per salvare l’immagine sul proprio disco locale. Ogni foto ha il proprio PhotoID, perciò ho voluto intercettare l’apertura del ContextMenu per dare un valore predefinito alla TextBox. Vediamo cosa fa l’event-handler dell’evento Opened del ContextMenu:

void ContextMenuOpened(object sender, RoutedEventArgs e) { if (lstPhotos.SelectedItem != null) { FlickrBrowserPhoto photo = lstPhotos.SelectedItem as FlickrBrowserPhoto; // Ottengo il riferimento alla TextBox che contiene il path ContextMenu menu = this.FindResource("menu") as ContextMenu; StackPanel p = ((MenuItem)menu.Items[1]).Items[0] as StackPanel; directoryTextBox = p.Children[1] as TextBox; directoryTextBox.Text = string.Format(@"E:{0}.jpg", photo.PhotoId); } }

Ottengo un riferimento al ContextMenu, poi “navigo” il visual-tree per raggiungere l’istanza prima dello StackPanel e poi della TextBox. Fatto questo, è sufficiente valorizzare la proprietà Text ed il gioco è fatto. Ovviamente il drive E: andrebbe messo a posto. Il click su Ok scarica la foto sfruttando la connessione attiva di Flickr.

La cosa brutta di questo sistema è che se cambiassi la struttura del ContextMenu, cambierebbe di conseguenza il visual-tree e quiandi bisognerebbe modificare la parte di codice che recuperare l’istanza. Lo StackPanel potrebbe non trovarsi più in menu.Items[1].Items[0]. E la TextBox un giorno potrebbe non essere più il Children[1]  dello StackPanel.

Technorati Tags:  

Send to Kindle

Igor Damiani

La sua passione per l'informatica nasce nella prima metà degli anni '80, quando suo padre acquistò un Texas Instruments TI-99. Da allora ha continuato a seguire l'evoluzione sia hardware che software avvenuta nel corso degli anni. E' un utente, un videogiocatore ed uno sviluppatore software a tempo pieno. Igor ha lavorato e lavora anche oggi con le più moderne tecnologie Microsoft per lo sviluppo di applicazioni: .NET Framework, XAML, Universal Windows Platform, su diverse piattaforme, tra cui spiccano Windows 10 piattaforme mobile. Numerose sono le app che Igor ha creato e pubblicato sul marketplace sotto il nome VivendoByte, suo personale marchio di fabbrica. Adora mantenere i contatti attraverso Twitter e soprattutto attraverso gli eventi delle community .NET.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.