Hosting a ContextMenu in a ListBoxItem

,

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.

Image

FIGURE 9.12 The ListBoxItem plays host to a ContextMenu with a delete button.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.253.239