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 № 11) 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;
}