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

如何用UserControl为外层DataGrid的RowDetails绑定不同InnerDataGrid

解决方案:让每个RowDetails绑定独立的明细数据

问题根源在于你当前的InnerDataGrid绑定的是外层DataGrid全局DataContext中的DetailsTable,所有行的RowDetails共享同一个数据源,所以打开新行时会覆盖已有数据。要解决这个问题,核心是让外层DataGrid的每一行数据对象本身持有独立的明细数据表,并让InnerDataGrid绑定到当前行的明细属性。

步骤1:修改外层数据模型

给外层DataGrid的每行数据对象(假设类名为OuterRowItem)添加一个独立的明细数据表属性,确保每个实例持有自己的DataTable,并实现INotifyPropertyChanged:

public class OuterRowItem : INotifyPropertyChanged
{
    // 原有的外层表字段属性...

    // 新增:当前行对应的明细数据表
    private DataTable _innerDetailsTable;
    public DataTable InnerDetailsTable
    {
        get => _innerDetailsTable;
        set
        {
            _innerDetailsTable = value;
            OnPropertyChanged(nameof(InnerDetailsTable));
        }
    }

    // INotifyPropertyChanged 实现
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤2:调整InnerDgUserControl的绑定

修改InnerDgUserControl的XAML,让InnerDataGrid绑定到当前行数据对象的InnerDetailsTable(此时UserControl的DataContext就是外层行的OuterRowItem实例):

<Grid>
  <DataGrid x:Name="innerDg" 
            ItemsSource="{Binding InnerDetailsTable.DefaultView}"
            AutoGenerateColumns="True" IsReadOnly="False"
            CanUserAddRows="False" CanUserReorderColumns="False" 
            EnableColumnVirtualization="True" EnableRowVirtualization="True"
            MaxWidth="2560" MaxHeight="2000" RowHeight="20" 
            VirtualizingStackPanel.VirtualizationMode="Standard">
  </DataGrid>
</Grid>

步骤3:加载行对应的明细数据

在外层DataGrid的行数据初始化/加载时,为每个OuterRowItem的InnerDetailsTable赋值对应的明细数据(比如从数据库、文件或其他数据源获取当前行专属的DataTable):

// 示例:外层数据加载时,为每行绑定对应明细
foreach (var outerItem in outerTableItems)
{
    // 根据当前行的标识获取对应的明细DataTable
    var innerTable = GetInnerDataTableForOuterItem(outerItem.Id);
    outerItem.InnerDetailsTable = innerTable;
}

关键说明

  • 每个OuterRowItem的InnerDetailsTable必须是独立的DataTable实例,不能多个行共享同一个对象,否则仍会出现数据覆盖问题。
  • 因为你已经实现了INotifyPropertyChanged,当InnerDetailsTable异步加载完成后,UI会自动更新对应的InnerDataGrid。
  • 动态生成DataGrid的需求完全兼容:AutoGenerateColumns="True"会自动根据DataTable的结构生成列,无需提前知道行列数。

原代码问题分析

你之前的InnerDataGrid绑定路径{Binding DataContext.DetailsTable.DefaultView, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}},是获取外层DataGrid的全局DataContext中的DetailsTable,这是一个单一实例,所有行的RowDetails都会绑定到同一个数据源,所以打开新行更新这个属性时,所有已展开的详情都会同步变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:43:31