WPF 中 DataGrid 的表级菜单和行级菜单
除了针对整个 DataGrid 的菜单外,有时还需要表中的每一行有各自不同菜单.
以下例子使用.net c#10 vs2022,在表的第一行和第二行上点击右键可弹出不同的行菜单,在 DataGrid 的空白处点击可弹出整个 DataGrid 的菜单.
c#
using System.Collections.ObjectModel; using System.Linq; namespace DataGridRowContextMenu { public partial class MainWindow { public ObservableCollection<GridItem> Items { get; set; } public MainWindow() { Items = new ObservableCollection<GridItem>() { new("Item1", new[] { "RowMenuItem1", "RowMenuItem2" }), new("Item2", new[] { "RowMenuItem3", "RowMenuItem4" }), }; InitializeComponent(); } } public class GridItem { public ObservableCollection<MenuItem> Menus { get; } public string Name { get; } public GridItem(string name, string[] menusTitle ) { Name = name; Menus = new ObservableCollection<MenuItem>(menusTitle.Select(v => new MenuItem(v))); } } public class MenuItem { public MenuItem(string title) { Title = title; } public string Title { get; set; } } }
xaml:
<Window x:Class = "DataGridRowContextMenu.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:local = "clr-namespace:DataGridRowContextMenu" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name = "ThisWindow" Title = "MainWindow" Width = "800" Height = "450" mc:Ignorable = "d" > <DataGrid ItemsSource = "{Binding ElementName=ThisWindow, Path=Items}" > <DataGrid.RowStyle> <Style TargetType = "DataGridRow" > <Setter Property = "ContextMenu" > <Setter.Value> <ContextMenu DisplayMemberPath = "Title" ItemsSource = "{Binding Path=(local:GridItem.Menus)}" /> </Setter.Value> </Setter> </Style> </DataGrid.RowStyle> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header = "DataGridMenuItem1" /> <MenuItem Header = "DataGridMenuItem2" /> </ContextMenu> </DataGrid.ContextMenu> </DataGrid> </Window>