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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:45:42