当前位置 : 主页 > 编程语言 > c语言 >

c# – 确定在执行ContextMenu MenuItem时在ListView中单击了哪个ListViewItem

来源:互联网 收集:自由互联 发布时间:2021-06-25
我正在尝试使用列表视图中的上下文菜单来运行一些代码,这些代码需要来自哪个项目的数据. 我最初只是这样做了: XAML: ListView x:Name="lvResources" ScrollViewer.VerticalScrollBarVisibility="Visibl
我正在尝试使用列表视图中的上下文菜单来运行一些代码,这些代码需要来自哪个项目的数据.

我最初只是这样做了:

XAML:

<ListView x:Name="lvResources" ScrollViewer.VerticalScrollBarVisibility="Visible">
      <ListView.Resources>
        <ContextMenu x:Key="resourceContextMenu">
            <MenuItem Header="Get Metadata" Name="cmMetadata" Click="cmMetadata_Click" />
        </ContextMenu>
      </ListView.Resources>
      <ListView.ItemContainerStyle>
          <Style TargetType="{x:Type ListViewItem}">
              <Setter Property="ContextMenu" Value="{StaticResource resourceContextMenu}" />
          </Style>
      </ListView.ItemContainerStyle>
 ...

C#:

private void cmMetadata_Click(object sender, RoutedEventArgs e)
    {
      // code that needs item data here
    }

但我发现原始listview项目无法通过这种方式访问​​.

我已经阅读了一些关于如何解决这个问题的策略,比如拦截MouseDown事件并将一个私有字段设置为被点击的listviewitem,但这并不适合我,因为它似乎有点hacky传递数据办法. WPF应该很容易,对吧? :)我已经阅读了这个SO question和这个MSDN forum question,但我仍然不确定如何真正做到这一点,因为这些文章似乎都不适用于我的情况.有没有更好的方法将点击的项目传递到上下文菜单?

谢谢!

在cmMetadata_Click处理程序中,您可以只查询lvResources.SelectedItem属性,因为lvResources可以从单击处理程序所在的代码隐藏文件中访问.它不优雅,但它可以工作.

如果您想要更优雅,可以更改设置ContextMenu的位置.例如,您可以尝试这样的事情:

<ListView x:Name="lvResources" ScrollViewer.VerticalScrollBarVisibility="Visible">
 <ListView.Style>
  <Style TargetType="ListView">
   <Setter Property="ItemContainerStyle">
    <Setter.Value>
     <Style TargetType="{x:Type ListViewItem}">
      <Setter Property="Template">
       <Setter.Value>
        <ControlTemplate TargetType="{x:Type ListViewItem}">
         <TextBlock Text="{TemplateBinding Content}">
          <TextBlock.ContextMenu>
           <ContextMenu>
            <MenuItem Header="Get Metadata" Name="cmMetadata" Click="cmMetadata_Click" 
             DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"/>
           </ContextMenu>
          </TextBlock.ContextMenu>
         </TextBlock>
        </ControlTemplate>
       </Setter.Value>
      </Setter>
     </Style>
    </Setter.Value>
   </Setter>
  </Style>
 </ListView.Style>
 <ListViewItem>One Item</ListViewItem>
 <ListViewItem>Another item</ListViewItem>
</ListView>

这样做是插入ListViewItem的模板,然后您可以使用方便的TemplatedParent快捷方式将ListViewItem分配给菜单项的DataContext.

现在你的代码隐藏看起来像这样:

private void cmMetadata_Click(object sender, RoutedEventArgs e)
{
    MenuItem menu = sender as MenuItem;
    ListViewItem item = menu.DataContext as ListViewItem;
}

显然缺点是你现在需要完成ListViewItem的模板,但我相信你可以很快找到一个适合你需求的模板.

网友评论