You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF如何绑定嵌套DataGrid的SelectedItem,解决绑定后属性不更新问题

问题原因

你的绑定路径本身是正确的,RowDetailsTemplate的DataContext默认就是当前行对应的Element实例,所以{Binding SelectedMyItem}的路径没有问题。绑定不生效的核心原因有两个:

  1. SelectedMyItem属性的set方法没有做空值校验:绑定初始化时会先给属性赋值null,此时你直接访问_selectedItem.MyItemName会抛出NullReferenceException,WPF绑定引擎遇到属性setter抛出的异常时会静默中断该绑定,不会抛出绑定错误,所以你在IDE里看不到相关报错。
  2. 你的实体类没有实现INotifyPropertyChanged接口,不符合MVVM绑定规范,会导致部分双向绑定场景失效。

修复方案

1. 修改C#类代码

先实现基础的INotifyPropertyChanged接口,同时修复set方法的空引用问题:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace NesteGridMVVM
{
    // 实现INotifyPropertyChanged的基类,复用逻辑
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class MyItem
    {
        public string MyItemName { get; set; }
    }
    
    public class Element : ViewModelBase
    {
        private MyItem _selectedItem;

        public string ElementName { get; set; }
        public ObservableCollection<MyItem> MyItemsList { get; set; } = new ObservableCollection<MyItem>();

        public MyItem SelectedMyItem
        {
            get => _selectedItem;
            set
            {
                _selectedItem = value;
                OnPropertyChanged();
                // 先判空再访问属性,避免空引用异常
                if (_selectedItem != null)
                {
                    System.Diagnostics.Debug.Print($"Selected MyItem: {_selectedItem.MyItemName}");
                }
            }
        }
    }
    
    public class MainVM : ViewModelBase
    {
        private Element _selectedElement;

        public ObservableCollection<Element> ElementsList { get; set; } = new ObservableCollection<Element>();

        public Element SelectedElement
        {
            get => _selectedElement;
            set
            {
                _selectedElement = value;
                OnPropertyChanged();
                if (_selectedElement != null)
                {
                    System.Diagnostics.Debug.Print($"{_selectedElement.ElementName}");
                }
            }
        }

        public MainVM()
        {
            Element elem1 = new Element() { ElementName = "element-01" };
            Element elem2 = new Element() { ElementName = "element-02" };

            elem1.MyItemsList.Add(new MyItem() { MyItemName = "item-A" });
            elem1.MyItemsList.Add(new MyItem() { MyItemName = "item-B" });
            elem2.MyItemsList.Add(new MyItem() { MyItemName = "item-C" });

            ElementsList.Add(elem1);
            ElementsList.Add(elem2);
        }
    }
}

2. 调整XAML绑定(可选,更稳妥)

可以给嵌套DataGrid的SelectedItem绑定显式指定双向绑定模式和更新触发时机,避免默认配置的差异问题:

<DataGrid
    x:Name="NestedDG"
    ItemsSource="{Binding MyItemsList}"
    AutoGenerateColumns="True"
    SelectedItem="{Binding SelectedMyItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</DataGrid>

修改完成后选中嵌套DataGrid的行,就会正常触发SelectedMyItem的赋值逻辑,Debug窗口会输出对应选中项的名称。


内容的提问来源于stack exchange,提问作者Adam Mroczek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:06:03