Sometimes the need arises to provide a context menu for dynamically generated elements, such as those presented using a data bound ItemsControl
. The following example demonstrates how to host a context menu for each item in a ListBox
.
The ContextMenuViewModel
contains an ObservableCollection
of strings, declared as shown:
readonly ObservableCollection<string> items
= new ObservableCollection<string>();
public IEnumerable<string> Items
{
get
{
return items;
}
}
The items
collection is populated within the viewmodel constructor. In addition, a new command, named DeleteCommand
, is placed in the viewmodel. When the command is executed, it removes the item, passed as a command parameter, from the items
collection. See the following excerpt:
public ContextMenuViewModel()
{
IEnumerable<string> temp = from int i in Enumerable.Range(1, 5)
select "Item " + i;
foreach (var itemName in temp)
{
items.Add(itemName);
}
deleteCommand = new DelegateCommand<string>(
itemName => items.Remove(itemName));
/* Content omitted. */
}
A ListBox
is placed on the page. Its ItemTemplate
is defined, and a TextBlock
is used to display each item in the list. The TextBlock.Text
property is bound to the current item using the expression {Binding}
. The TextBlock
plays host to a ContextMenu
onto which a single MenuItem
is placed. Notice that the MenuItem
is bound to the DeleteCommand
using the DataContext
property of the page. This is because the DataContext
of the MenuItem
is the string item and not the page, and therefore we specify the source explicitly using the ElementName
binding property. See the following excerpt:
<ListBox ItemsSource="{Binding Items}" Height="200" Margin="12">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="20">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="false">
<toolkit:MenuItem
Header="Delete"
Command="{Binding DataContext.DeleteCommand,
ElementName=page}"
CommandParameter="{Binding}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Tapping and holding an item in the list causes the ContextMenu
for that item to be displayed. The DeleteCommand
accepts a single parameter, which is the item string (see Figure 9.12). When executed, the item is removed from the list as expected.
3.149.253.239