/ / Multiple ListViews che condividono un ContextMenu, come posso fare riferimento all'oggetto giusto? - c #, wpf, listview, contextmenu

Multiple ListViews che condividono un ContextMenu, come posso fare riferimento all'oggetto giusto? - c #, wpf, listview, contextmenu

Ho molte ListViews, ognuna legata alla propriaListCollectionView, ciascuno con esigenze ContextMenu identiche. Non voglio ripetere lo stesso ContextMenu N volte, quindi lo definisco nelle Risorse e mi riferisco ad esso tramite StaticResource.

Quando si fa clic con il tasto destro su un oggetto X in un ListView e si fa clic su MenuItem, come posso accedere all'oggetto X nel codebehind?

<Window.Resources>
<ContextMenu x:Key="CommonContextMenu">
<MenuItem Header="Do Stuff" Click="DoStuff_Click" />
</ContextMenu>
</Window.Resources>

<ListView ItemsSource="{Binding Path=ListCollectionView1}" ContextMenu="{StaticResource CommonContextMenu}">
...
</ListView>

<ListView ItemsSource="{Binding Path=ListCollectionView2}" ContextMenu="{StaticResource CommonContextMenu}">
...
</ListView>

private void DoStuff_Click(object sender, RoutedEventArgs e)
{
// how do i get the selected item of the right listview?
}

Aggiornare

Grazie alla risposta di Michael Gunter, ora sto usando i seguenti metodi di estensione:

public static ListView GetListView(this MenuItem menuItem)
{
if (menuItem == null)
return null;

var contextMenu = menuItem.Parent as ContextMenu;
if (contextMenu == null)
return null;

var listViewItem = contextMenu.PlacementTarget as ListViewItem;
if (listViewItem == null)
return null;

return listViewItem.GetListView();
}

public static ListView GetListView(this ListViewItem item)
{
for (DependencyObject i = item; i != null; i = VisualTreeHelper.GetParent(i))
{
var listView = i as ListView;
if (listView != null)
return listView;
}

return null;
}

risposte:

1 per risposta № 1

1) Metti il ​​menu contestuale su ciascun elemento all'interno di ciascuno ListView, piuttosto che su ciascuno ListView si. Ciò evita che il menu contestuale si apra quando si fa clic sullo spazio vuoto nel ListView. Per fare questo, utilizzare il ListView.ItemContainerStyle proprietà. (Se vuoi davvero il menu di scelta rapida sul ListView di per sé, fammi sapere e modificheremo questa risposta di conseguenza).

<Window.Resources>
<ContextMenu x:Key="CommonContextMenu">
<MenuItem Header="Do Stuff" Click="DoStuff_Click" />
</ContextMenu>
<Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource CommonContextMenu}" />
</Style>
</Window.Resources>

<ListView ItemsSource="{Binding Path=ListCollectionView1}" ItemContainerStyle="{StaticResource ListViewItemStyle}">
...
</ListView>
<ListView ItemsSource="{Binding Path=ListCollectionView2}" ItemContainerStyle="{StaticResource ListViewItemStyle}">
...
</ListView>

2) Utilizzare codice come il seguente per determinare quale elemento è stato fatto clic con il pulsante destro del mouse.

private void DoStuff_Click(object sender, RoutedEventArgs e)
{
var menuItem = sender as MenuItem;
if (menuItem == null)
return;

var contextMenu = menuItem.Parent as ContextMenu;
if (contextMenu == null)
return;

var listViewItem = contextMenu.PlacementTarget as ListViewItem;
if (listViewItem == null)
return;

var listView = GetListView(listViewItem);
if (listView == null)
return;

// do stuff here
}

private ListView GetListView(ListViewItem item)
{
for (DependencyObject i = item; i != null; i = VisualTreeHelper.GetParent(i))
{
var listView = i as ListView;
if (listView != null)
return listView;
}
return null;
}