Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

WPF: Context Menu on List Item

5.00/5 (7 votes)
12 May 2010Apache1 min read 47.9K  
WPF: Context Menu on List Item

I am using WPF and MVVM. I have a Window and a view model attached to it via Datacontext. The window has a listbox, and its items have context menu. I am using DelegateCommand in my view model, and I want to bind a menu items in the context menu to this command.

The first problem is that by default the menu item is bound to the DataContext of the list box item, which may or may not have knowledge of the whole view model.

The second problem is that context menu is not part of the visual tree, so referring to the main window via FindAncestor or ElementName=... will not work.

You can get to the object immediately containing the context menu via the PlacementTarget property, but then you will need an ancestor of this object (“window”), and there is no built-in way to find an ancestor of a property.

An (almost) working solution that I found on the Internet after hours of search was to store the data context some property of the PlacementTarget – they used Tag for this purpose.

The “almost” part lies in the fact that if your command has CanExecute() method, the command parameter passed to it is sometimes null (see here).

XML
<Window Name="MainWindow" ...>
    <Grid>
        <ListBox ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal"
                               Tag="{Binding DataContext, ElementName=MainWindow}">
			...
                        <StackPanel.ContextMenu>
                             <MenuItem Header="do it"
    Command="{Binding PlacementTarget.Tag.MyCommand, 
	RelativeSource={RelativeSource AncestorType=ContextMenu}}"
    CommandParameter="{Binding}">
                        </StackPanel.ContextMenu>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0