从ContextMenu中的MenuItem访问ListViewItem信息

问题描述 投票:0回答:1

我有一个包含多个项目的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实现,但是我无法做到这一点。有什么建议吗?

提前感谢

c# wpf listview contextmenu menuitem
1个回答
0
投票

您经常可以使用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;
}

在这种情况下,菜单是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的策略应转移到其他用例。

© www.soinside.com 2019 - 2024. All rights reserved.