У мене багато 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 для відповіді № 11) Покладіть контекстне меню на кожен елемент у кожному 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;
}