有WPF中,针对ListView定义的弹出菜单,在Click事件里很难获得当前弹出菜单应对的ListViewItem数据行,如果我们想对特定的数据行右击进行某些操作,操作时需要知道在哪个项目上右击弹出的菜单,需要把弹出菜单定义在ListViewItem上而不是ListView上。
步骤示例如下:
- 在xaml中定义弹出菜单的资源:
<!--定义给ListViewItem用的弹出菜单-->
<Window.Resources>
<ContextMenu x:Key="ListViewItemContextMenu">
<MenuItem Header="编辑" Click="EditMenuItem_Click"/>
<MenuItem Header="删除" Click="DeleteMenuItem_Click"/>
</ContextMenu>
</Window.Resources>
- 在ListView里绑定右键菜单
<ListView ItemsSource="{Binding Products}">
<ListView.View>
<GridView>
<GridViewColumn Header="备注" DisplayMemberBinding="{Binding remarks}" Width="200"/>
</GridView>
</ListView.View>
<!--这里针对ListViewItem设置上下文菜单,不然等下事件里取不到操作的数据-->
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource ListViewItemContextMenu}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
上面关键的是以下部分:
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource ListViewItemContextMenu}"/>
</Style>
</ListView.ItemContainerStyle>
上面的ListViewItemContextMenu
实际对应的第一步中定义的右键菜单资源的Key值。
- 两个菜单项对应的程序代码简化如下:
// 编辑商品
private void EditMenuItem_Click(object sender, RoutedEventArgs e)
{
if ((sender as MenuItem).DataContext is not ProductInfo selectedProduct) return;
......
}
// 删除商品
private void DeleteMenuItem_Click(object sender, RoutedEventArgs e)
{
var selectedProduct = (sender as MenuItem).DataContext as ProductInfo;
if (selectedProduct == null) return;
......
}
如此处理就行了。
需要注意的是,不建议使用如下的定义方式,如下的方式没有把右键菜单定义成静态资源,看上去完全没问题,而且能编译通过,但一运行很可能就会报错,至于在哪些版本、哪些平台会报错,不明:
<ListView ItemsSource="{Binding Products}">
<ListView.View>
<GridView>
<GridViewColumn Header="备注" DisplayMemberBinding="{Binding remarks}" Width="200"/>
</GridView>
</ListView.View>
<!--这里针对ListViewItem设置上下文菜单,编译通过,但运行会出错-->
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="编辑" Click="EditMenuItem_Click"/>
<MenuItem Header="删除" Click="DeleteMenuItem_Click"/>
</ContextMenu>
</Setter.Value>
</Setter Property>
</Style>
</ListView.ItemContainerStyle>
</ListView>
网友评论