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>

 

posted @ 2021-12-27 21:12  xiejiang  阅读(1015)  评论(0编辑  收藏  举报