/ / Multiple ListView, які використовують ContextMenu, як я можу посилатися на потрібний об'єкт? - c #, wpf, listview, contextmenu

Кілька ListView, які використовують ContextMenu, як я можу посилатися на потрібний об'єкт? - c #, wpf, listview, contextmenu

У мене багато ListView, кожен з яких пов'язаний з їх власнимиListCollectionView, кожна з однаковими ContextMenu потребує. Я не хочу повторювати той самий ContextMenu N раз, тому я визначаю його в ресурсах і посилаюсь на нього за допомогою StaticResource.

Коли елемент X в ListView клацнеться правою кнопкою миші, а натискання кнопки MenuItem, як я можу отримати доступ до об'єкта X в коді?

<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?
}

Оновити

Завдяки відповіді Майкла Гюнтер, тепер я використовую наступні методи розширення:

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;
}

Відповіді:

1 для відповіді № 1

1) Покладіть контекстне меню на кожен елемент у кожному ListView, а не на кожному ListView сама по собі Це дозволяє уникнути появи контекстного меню при натисканні на порожній простір в ListView. Для цього використовуйте ListView.ItemContainerStyle власність (Якщо ви дійсно хочете контекстне меню на ListView сама, дайте мені знати, і я відповідним чином редагую цю відповідь.)

<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) Використовуйте код, подібний до наведеного нижче, щоб визначити, який елемент натиснув правою кнопкою миші.

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;
}