【问题标题】:Access ListViewItem information from MenuItem in ContextMenu从 ContextMenu 中的 MenuItem 访问 ListViewItem 信息
【发布时间】:2020-02-14 19:48:35
【问题描述】:

我有一个包含多个项目的 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 Context Menu Get Data from ListViewItem),它需要访问项目的 DataContext。这可以通过 ContextMenu 的 PlacementTarget 来实现,但我无法做到。有什么建议吗?

提前致谢

【问题讨论】:

  • 我不确定你在找什么,它只是右键单击的 MenuItem 的 DataContext 吗?如果是这样,您应该可以通过((MenuItem)sender).DataContext 获得它

标签: c# wpf listview contextmenu menuitem


【解决方案1】:

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

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

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

在这种情况下,menu 是ContextMenu 的名称。我只需从ListItemView 中获取DataContext 并将其附加到ContextMenu

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

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

请注意:我省略了您对 HierarchicalDataTemplate 所做的事情,因为我不了解其意图,而且对我而言,它不会导致任何渲染。无论如何,这种在打开ContextMenu 时附加DataContext 的策略应该转移到其他用例。

【讨论】:

    猜你喜欢
    • 2020-07-12
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2010-11-04
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多