首页 > 解决方案 > 从 ContextMenu 中的 MenuItem 访问 ListViewItem 信息

问题描述

我有一个包含多个项目的 ListView。我想在系统剪贴板中复制与给定行相关的信息(例如该行中项目的 ID)。

我创建了一个 ContextMenu,它在右键单击一行时打开,它显示一个 MenuItem 来复制 id:

<ListView x:Name="MyListView" MouseDoubleClick="MyListView_MouseDoubleClick">
    <ListView.Columns>
        <GridViewColumn Header="Id" DisplayMemberBinding="{Binding MyItem.Id}"/>
    </ListView.Columns>
    <ListView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type mynamespace:MyItemDefinition}" ItemsSource="{Binding MyGroupOfItems, Mode=OneWay}" />
    </ListView.ItemTemplate>
    <ListView.ContextMenu>
        <ContextMenu>
            <MenuItem x:Name="MenuItemCopyId" Header="Copy ID" Click="MenuItemCopyId_Click"/>
        </ContextMenu>
    </ListView.ContextMenu>
</ListView>

private void MenuItemCopyId_Click(object sender, RoutedEventArgs e)
{
     var menu_item = ((System.Windows.Controls.MenuItem)sender);
}

对于我阅读的内容(ListViewItem 上下文菜单从 ListViewItem 获取数据),它需要访问项目的 DataContext。这可以通过 ContextMenu 的 PlacementTarget 来实现,但我无法做到。有什么建议么?

提前致谢

标签: c#wpflistviewcontextmenumenuitem

解决方案


您通常可以使用PlacementTarget来执行一些相对绑定并提供ContextMenu它通常不会拥有的信息,因为它位于可视化树之外。鉴于您在此处进行设置的方式,我不确定这对您来说效果是否太好。看起来您想要一个属于 的上下文菜单,ListView但适用于右键单击的行。您可以通过手动附加事件来做到这DataContext一点ContextOpening。例如,我松散地遵循了您必须设置的内容ListView

<ListView ItemsSource="{Binding MyGroupOfItems}">
    <ListView.Resources>
        <Style TargetType="ListViewItem">
            <EventSetter Event="ContextMenuOpening" Handler="ListViewItem_ContextMenuOpening" />
        </Style>
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" />
        </GridView>
    </ListView.View>
    <ListView.ContextMenu>
        <ContextMenu Name="menu">
            <MenuItem Header="Copy ID" Click="MenuItem_Click" />
        </ContextMenu>
    </ListView.ContextMenu>
</ListView>

ListViewItem我为处理事件添加了一种样式。这ContextMenuOpening将允许您在上下文菜单打开时知道您在哪一行。在后面的代码中,您可以附加该DataContext行的。

private void ListViewItem_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
    ListViewItem listItem = sender as ListViewItem;
    menu.DataContext = listItem.DataContext;
}

在这种情况下,menu 是ContextMenu. DataContext我只是从 中抓取ListItemView并将其附加到ContextMenu.

现在,当您处理菜单单击事件时,您可以获取该数据并使用它来执行您需要执行的任何操作。

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    MyItem item = (MyItem)(sender as MenuItem).DataContext;
    //Now you can do stuff with MyItem
}

只是一个说明:我省略了你正在做的事情,HierarchicalDataTemplate因为我不理解意图,对我来说它没有导致任何渲染。无论如何,这种DataContext在打开时附加的策略ContextMenu应该转移到其他用例。


推荐阅读