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

WPF DataGrid新增行时SelectedItems未同步UI选中状态的问题

WPF DataGrid新增行后SelectedItems持续增长的问题分析与解决

问题原因

当你的DataGrid设置了CanUserAddRows="True"时,WPF会自动在Items集合末尾添加一个**CollectionView.NewItemPlaceholder**对象作为新增行的占位符。这个占位符虽然在UI上显示为可编辑的空行,但它并不是你业务模型中的实际数据对象:

  • 当你开始编辑这个占位符行时,DataGrid会将这个占位符加入SelectedItems集合,触发SelectionChanged事件;
  • 当编辑完成(比如行失去焦点),DataGrid会用你业务模型的实例替换这个占位符,同时生成新的占位符行;
  • 但此时,原来的占位符对象并没有被自动从SelectedItems中移除——因为它已经不在DataGrid的Items集合里了,UI不会渲染它,但SelectedItems依然持有这个无效引用,导致集合大小持续增长,而UI上只能看到当前有效的选中行。

另外,你设置了SelectionMode="Single",但这个模式只对有效数据项生效,无法自动过滤掉NewItemPlaceholder这种特殊对象,所以才会出现"UI只有单行选中,但SelectedItems持续变大"的矛盾现象。

解决方法

针对这个问题,有两种直接有效的解决方式:

1. 在SelectionChanged事件中过滤无效项

在你已经绑定的dataGrid_SelectionChanged事件中,手动移除SelectedItems中的NewItemPlaceholder对象,确保集合中只保留有效的业务数据项:

using System.Windows.Data; // 需要引入这个命名空间才能访问CollectionView

private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // 筛选出所有NewItemPlaceholder类型的无效项
    var invalidPlaceholderItems = dataGrid.SelectedItems.Cast<object>()
        .Where(item => CollectionView.NewItemPlaceholder.Equals(item))
        .ToList();

    // 从SelectedItems中移除这些无效项
    foreach (var invalidItem in invalidPlaceholderItems)
    {
        dataGrid.SelectedItems.Remove(invalidItem);
    }

    // 这里可以更新你的TextBox显示,验证选中数量是否正确
    selectionBox.Text = $"当前选中行数:{dataGrid.SelectedItems.Count}";
}

2. 确保ItemsSource使用ObservableCollection

你的GeneralTasks属性必须是ObservableCollection<YourTaskModel>类型(而不是普通的List<T>),因为ObservableCollection会自动通知UI集合的变化,DataGrid才能正确跟踪项的添加/替换操作,减少无效引用残留的概率:

// 在你的ViewModel或窗口类中定义
public ObservableCollection<YourTaskModel> GeneralTasks { get; set; }

// 初始化时赋值
public SampleWindow()
{
    InitializeComponent();
    GeneralTasks = new ObservableCollection<YourTaskModel>();
    DataContext = this; // 如果是直接绑定到窗口的话
}

额外注意事项

  • 避免在SelectionChanged事件中做复杂的业务逻辑,防止因为多次触发(新增行过程中会触发多次)导致的性能问题;
  • 如果你的DataGrid设置了SelectionUnit="Cell"或CellOrRowHeader,也可能出现类似的选中残留问题,但你的代码中设置的是FullRow,所以上面的方法完全适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:53:35