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

WPF DataGrid分页后旧行Item属性显示{DisconnectedItem}问题求助

问题原因与解决方案

核心原因

你直接将DataGridRow作为ItemsSource的数据源是错误的——DataGridRow是WPF的可视化容器,而非数据实体。它的Item属性依赖于所在的DataGrid可视化树上下文:

  • 当你替换DataGrid的ItemsSource时,旧的DataGridRow会被从可视化树中移除,WPF内部会自动断开它与原数据的绑定,将Item标记为{DisconnectedItem},这是WPF的容器回收机制导致的。
  • 你存储的是已经被使用过的可视化容器,重复复用这些容器必然触发这个问题。

解决方案:数据与可视化分离

正确的做法是绑定数据实体集合,让DataGrid自动生成和管理DataGridRow容器,而非手动操作这些容器。

1. 定义数据模型

创建对应业务的数据类,存储每行需要展示的数据:

// 示例数据模型,根据实际业务调整属性
public class RowData
{
    public string Column1 { get; set; }
    public int Column2 { get; set; }
    // 其他列属性...
}

2. 替换数据源为数据集合

将原来存储DataGridRow的集合替换为数据实体集合:

// 用ObservableCollection方便数据变更通知
public ObservableCollection<RowData> Rows { get; } = new ObservableCollection<RowData>();

3. 修改分页逻辑

分页时直接操作数据集合,截取对应页的数据赋值给ItemsSource:

public void Navigate(PaginationDirections direction, int pageNumber = -1)
{
    if (_tableWidget.DataGrid == null || !_tableWidget.Rows.Any())
    {
        return;
    }

    // 计算总页数
    _totalPages = (int)Math.Ceiling((double)_tableWidget.Rows.Count / _rowsPerPage);
    _comboBox.ItemsSource = Enumerable.Range(1, _totalPages).ToList();
    _comboBox.IsEnabled = _totalPages > 1;
    _button.IsEnabled = _totalPages > 1;

    // 处理分页方向
    switch (direction)
    {
        case PaginationDirections.Previous:
            if (_currentPage <= 1) break;
            _currentPage--;
            break;
        case PaginationDirections.Next:
            if (_currentPage >= _totalPages) break;
            _currentPage++;
            break;
        case PaginationDirections.GoTo:
            if (pageNumber < 1 || pageNumber > _totalPages) break;
            _currentPage = pageNumber;
            break;
        case PaginationDirections.Self:
            // 保持当前页不变
            break;
        default:
            break;
    }

    // 统一计算当前页需要展示的数据
    int skipCount = (_currentPage - 1) * _rowsPerPage;
    var rowsToDisplay = _tableWidget.Rows.Skip(skipCount).Take(_rowsPerPage).ToList();
    _tableWidget.DataGrid.ItemsSource = rowsToDisplay;
}

4. 确保列绑定正确

因为你设置了AutoGenerateColumns = false,需要手动将DataGrid列绑定到数据模型的属性,示例:

// 在DataGrid初始化时添加列
_tableWidget.DataGrid.Columns.Add(new DataGridTextColumn
{
    Header = "列1",
    Binding = new Binding(nameof(RowData.Column1))
});
_tableWidget.DataGrid.Columns.Add(new DataGridTextColumn
{
    Header = "列2",
    Binding = new Binding(nameof(RowData.Column2))
});

额外说明

  • 自定义行/单元格样式:如果之前是通过手动创建DataGridRow来设置样式,现在可以通过DataGrid的RowStyle或CellStyle属性来实现,通过绑定数据模型的属性控制样式逻辑。
  • 数据变更通知:使用ObservableCollection<RowData>可以自动通知DataGrid数据新增/删除的变化,无需手动刷新ItemsSource。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:02:52