【问题标题】:How to bind ContextMenu items in a nested DataGrid?如何在嵌套的 DataGrid 中绑定 ContextMenu 项?
【发布时间】:2025-11-26 09:35:01
【问题描述】:

我已经嵌套了 DataGrid。嵌套网格显示为所选 DataGrid 的 RowDetails。这是我与 DataGrid 绑定的类结构

public class CustomTable : INotifyPropertyChanged
    {
            public List<DataTable> Main { get; set; }
            private List<string> _menu;
            public List<string> Menu
            {
                 get
                 {   
                     return _menu;
                 }
                 set
                 {
                     _menu = value
                     OnPropertyChanged("Menu");
                 }
            }

            private CustomTable _child;
            public CustomTable Child
            {
                get
                {
                     return _child;
                }
                set
                {
                     _child = value;
                     OnPropertyChanged("Child");
                }
            }
            public DataRowView _selectedItem;
            public DataRowView SelectedItem
            {
                get
                {
                    return _selectedItem;
                }
                set
                {
                    _selectedItem = value;
                    Child = new CustomTable();
                    OnPropertyChanged("SelectedItem");
                }
            }  


        public CustomTable()
        {
            Main = new List<DataTable>();
            Main.Add(someRandomTable());

        }

        private DataTable someRandomTable()
        {
            DataTable table = new DataTable();
            table.Columns.Add("Dosage", typeof(int));
            table.Columns.Add("Drug", typeof(string));
            table.Columns.Add("Patient", typeof(string));
            table.Columns.Add("Date", typeof(DateTime));
            table.Rows.Add(25, "Indocin", "David", DateTime.Now);
            table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
            table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
            table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
            table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
            return table;
        }



        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string caller)
        {

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(caller));
            }
        }

}

这是我将数据网格与数据表绑定的 XAML。我想将菜单列表绑定到 DataGrid。谢谢

<ScrollViewer>
<ScrollViewer.Resources>
    <DataTemplate DataType="{x:Type l:CustomTable}">
        <StackPanel>
            <ItemsControl ItemsSource="{Binding Path=Main}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <DataGrid Name="dg" SelectedItem="{Binding DataContext.SelectedItem, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl}}"
                              CanUserAddRows="False"  ItemsSource="{Binding}" AutoGenerateColumns="True" >
                            <DataGrid.RowDetailsTemplate>
                                <DataTemplate>
                                    <ContentControl Margin="10"
                                                    Content="{Binding DataContext.Child, RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl,AncestorLevel=2}}"/>
                                </DataTemplate>
                            </DataGrid.RowDetailsTemplate>
                        </DataGrid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
    </DataTemplate>
</ScrollViewer.Resources>

<ContentControl Content="{Binding TableCollection}"/>

</ScrollViewer>

【问题讨论】:

  • 你有什么问题?关于ContextMenu 的东西?也请发布您的 XAML
  • @JonathonLee 对不起,我的错。不知怎的,我错过了它。是的,我想将 ContextMenu 添加到 DataGrid 的每个级别
  • 属性Menu应该是数据网格的上下文菜单吗?
  • @pushpraj 是的。如果我右键单击 DataGrid 上的任何行。它应该显示菜单列表的所有元素。

标签: c# wpf mvvm datagrid


【解决方案1】:

给你

截图

xaml

<DataGrid Name="dg"
            SelectedItem="{Binding DataContext.SelectedItem, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl}}"
            CanUserAddRows="False"
            ItemsSource="{Binding}"
            AutoGenerateColumns="True"
            Tag="{Binding DataContext, RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl}}">
    <DataGrid.ContextMenu>
        <ContextMenu ItemsSource="{Binding PlacementTarget.Tag.Menu, RelativeSource={RelativeSource Self}}" />
    </DataGrid.ContextMenu>

注意这两点

  • Tag="{Binding DataContext, RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl}}" 在数据网格中和
  • ItemsSource="{Binding PlacementTarget.Tag.Menu, RelativeSource={RelativeSource Self}}" 在上下文菜单中

这是一种解决方法,因为上下文菜单不是数据网格可视树的一部分,因此无法直接绑定到 Menu 属性,甚至无法使用 FindAncestor 等进行绑定

示例菜单生成

public CustomTable()
{
    Main = new List<DataTable>();
    Main.Add(someRandomTable());

    Menu = new List<string>();
    Menu.Add("Menu item 1");
    Menu.Add("Menu item 2");
    Menu.Add("Menu item 3");
    Menu.Add("Menu item 4");

}

【讨论】:

  • Question 有什么想法吗?你真的很擅长这个:)