WPF如何绑定嵌套DataGrid的SelectedItem,解决绑定后属性不更新问题
问题原因
你的绑定路径本身是正确的,RowDetailsTemplate的DataContext默认就是当前行对应的Element实例,所以{Binding SelectedMyItem}的路径没有问题。绑定不生效的核心原因有两个:
SelectedMyItem属性的set方法没有做空值校验:绑定初始化时会先给属性赋值null,此时你直接访问_selectedItem.MyItemName会抛出NullReferenceException,WPF绑定引擎遇到属性setter抛出的异常时会静默中断该绑定,不会抛出绑定错误,所以你在IDE里看不到相关报错。- 你的实体类没有实现
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
相关产品推荐
相关产品推荐

