WPF DataGrid添加行时数据不同步问题(滚动后数据异常)
问题分析与解决方案
这个问题是WPF DataGridUI虚拟化导致的常见问题:DataGrid默认只渲染当前可见区域的行,不在视图内的行延迟创建UI元素。当滚动到这些行时,CustomComboBox才会初始化,但如果数据模型或自定义控件的绑定逻辑有缺陷,就会出现数据不同步的情况。
核心修复步骤
1. 确保数据模型实现INotifyPropertyChanged
Customer和Item类必须实现该接口,否则属性变更无法通知UI更新。示例代码:
public class Customer : INotifyPropertyChanged { private string _name; private Item _item; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } public Item Item { get => _item; set { _item = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class Item : INotifyPropertyChanged { private string _name; private string _type; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } public string Type { get => _type; set { _type = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 修正CustomComboBox的依赖属性定义
自定义控件的依赖属性必须正确配置元数据,确保绑定双向生效并同步内部控件状态。示例:
public class CustomComboBox : UserControl { public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( "SelectedItem", typeof(Item), typeof(CustomComboBox), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (d, e) => ((CustomComboBox)d).CustomCombo.SelectedItem = e.NewValue)); public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( "ItemsSource", typeof(IEnumerable<Item>), typeof(CustomComboBox), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (d, e) => ((CustomComboBox)d).CustomCombo.ItemsSource = e.NewValue)); public Item SelectedItem { get => (Item)GetValue(SelectedItemProperty); set => SetValue(SelectedItemProperty, value); } public IEnumerable<Item> ItemsSource { get => (IEnumerable<Item>)GetValue(ItemsSourceProperty); set => SetValue(ItemsSourceProperty, value); } // 其他原有代码... }
3. 确认集合类型为ObservableCollection
用于绑定的CustomersList必须是ObservableCollection<Customer>,而非普通List,这样新增元素时才能自动通知DataGrid更新:
public ObservableCollection<Customer> CustomersList { get; set; } = new ObservableCollection<Customer>();
4. 验证虚拟化影响(可选测试步骤)
如果以上步骤无效,可临时关闭DataGrid虚拟化确认问题根源:
<DataGrid x:Name="DG" ... VirtualizingPanel.IsVirtualizing="False" />
注意:关闭虚拟化会降低大数据量下的性能,仅用于测试,最终建议保留虚拟化并修复绑定逻辑。
内容的提问来源于stack exchange,提问作者MElSawy
相关产品推荐
相关产品推荐

