多个ListView共享一个ContextMenu,如何引用正确的对象
本文关键字:引用 何引用 对象 ContextMenu 共享 ListView 多个 一个 | 更新日期: 2023-09-27 18:25:45
我有许多ListView,每个ListView都绑定到自己的ListCollectionView,每个都有相同的ContextMenu需求。我不想重复相同的ContextMenu N次,所以我在参考资料中定义了它,并通过StaticResource引用它。
当右键单击ListView中的项目X,并单击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?
}
更新
感谢Michael Gunter的回答,我现在使用以下扩展方法:
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)将上下文菜单放在每个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;
}