views:

52

answers:

2

I have a listview with contextMenu on each ListViewItem that has Click event, how can I detect in the event handler witch Item was click in his contextMenu ? I need the item ID.

 <Style TargetType="{x:Type ListViewItem}">

. . .

 <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate TargetType="tv:TreeListViewItem">
                        <Grid>
                            <Grid.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="Open in current tab" Click="MenuItemCurrentTab_Click"/>
                                    <MenuItem Header="Open in new tab" Click="MenuItemNewTab_Click"/>
                                </ContextMenu>
                            </Grid.ContextMenu>
A: 
    private void MenuItemCurrentTab_Click(object sender, RoutedEventArgs e)
    {
        MenuItem menuItem = (MenuItem)e.Source;
        ContextMenu menu = (ContextMenu)menuItem.Parent;
        ListViewItem item = (ListViewItem)menu.PlacementTarget;
        // do something with item
    }

But it's probably better idea to create single ContextMenu, give it proper name, and use it for all list view items.

Athari
@Athari, I did what you wrote but menu.PlacementTarget retrieves grid and not the listview item and I didn't know what to do with that.
Erez
+1  A: 

See this thread..

Following the same way as the answer from the link you would

<Grid.ContextMenu> 
    <ContextMenu> 
        <MenuItem Header="Open in current tab"
                  Click="MenuItemCurrentTab_Click"
                  CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}"/>

...

private void MenuItemCurrentTab_Click(object sender, RoutedEventArgs e)
{
    MenuItem menuItem = sender as MenuItem;
    if (menuItem != null)
    {
        ContextMenu parentContextMenu = menuItem.CommandParameter as ContextMenu;
        if (parentContextMenu != null)
        {
            ListViewItem listViewItem = parentContextMenu.PlacementTarget as ListViewItem;
        }
    } 
}

UPDATE

Add this to get the parent ListViewItem from the Grid

public T GetVisualParent<T>(object childObject) where T : Visual
{
    DependencyObject child = childObject as DependencyObject;
    while ((child != null) && !(child is T))
    {
        child = VisualTreeHelper.GetParent(child);
    }
    return child as T;
}

private void MenuItemCurrentTab_Click(object sender, RoutedEventArgs e)
{
    MenuItem menuItem = sender as MenuItem;
    if (menuItem != null)
    {
        ContextMenu parentContextMenu = menuItem.CommandParameter as ContextMenu;
        if (parentContextMenu != null)
        {
            Grid grid = parentContextMenu.PlacementTarget as Grid;
            ListViewItem listViewItem = GetVisualParent<ListViewItem>(grid);
        }
    } 
}
Meleak
@Meleak - I triedit and since I have a control template, instead of the listview item parentContextMenu.PlacementTarget retrieves for me the grid that inside the control template :(
Erez
Updated my example
Meleak