In pratica, uno dei miei TreeViewItem è "databindato" ad una gerarchia di categorie.
<TreeViewItem Header="Categories" ItemsSource="{Binding Categories}" >
</TreeViewItem>
Da qualche altra parte (tra le risorse dell'applicativo) definisco un HierarchicalDataTemplate per il tipo "Category":
<HierarchicalDataTemplate DataType="{x:Type my:Category}"
ItemsSource="{Binding Path=Categories}" >
<TextBlock Text="{Binding Path=Name}" >
<TextBlock.ContextMenu>
<ContextMenu Name="MyMenu">
<MenuItem Header="New Category... "
Click="NewCategory_Click"
CommandParameter="{Binding Path=.}"/>
<MenuItem Header="Delete Category"
Click="DeleteItem_Click"
CommandParameter="{Binding Path=.}"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
L'elemento ContextMenu specifica un semplice menu contestuale che permette l'aggiunta di una categoria. E la sua cancellazione. Per fare ciò è necessario che al metodo gestore dell'evento arrivi l'oggetto che corrisponde all'elemento dell'albero. Intendo cioè l'oggetto Category su cui è "bindato" il TreeViewItem su cui l'utente ha fatto click col tasto destro del mouse.
Uno stratagemma semplice è usare il CommandParameter con un espressione di binding come Path=.
In questa maniera il CommandParameter prenderà il valore dell'oggetto stesso e sarà inviato all'event handler:
private void DeleteItem_Click(object sender, RoutedEventArgs e)
{
Category cat = (Category)((MenuItem)sender).CommandParameter;
//Cancella la categoria...
}
Ovviamente questo trucco non si può utilizzare nel caso che si abbia effetivamente bisogno di valorizzare CommandParameter con qualcos'altro, ma in molti casi questo non è necessario.

Nessun commento:
Posta un commento