C# 无法获取嵌套对象以在DataGrid中显示为嵌套的Datgrid行

C# 无法获取嵌套对象以在DataGrid中显示为嵌套的Datgrid行,c#,wpf,xaml,datagrid,nested,C#,Wpf,Xaml,Datagrid,Nested,我是WPF和XAML的新手,但我想我很快就学会了 我有一个自定义的项目,我正在工作,其中有一些对象,如下所示。所有数据都存储在XML文件中,并在启动时加载到对象中。注意,我正在更改代码/应用程序上隐私保护的名称 全班,我们称之为学校的教室 包含教室作为ObservableCollection的属性 使用INotifyPropertyChanged 主要对象类,我们称之为教室。包含有关对象的唯一属性以及作为ObservableCollection的学生属性 使用INotifyPropertyCha

我是WPF和XAML的新手,但我想我很快就学会了

我有一个自定义的项目,我正在工作,其中有一些对象,如下所示。所有数据都存储在XML文件中,并在启动时加载到对象中。注意,我正在更改代码/应用程序上隐私保护的名称

全班,我们称之为学校的教室 包含教室作为ObservableCollection的属性 使用INotifyPropertyChanged

主要对象类,我们称之为教室。包含有关对象的唯一属性以及作为ObservableCollection的学生属性 使用INotifyPropertyChanged

第二个对象类,我们称之为。包含关于学生的唯一属性和作为可观察集合的供应品属性 使用INotifyPropertyChanged

第三个对象类,我们称之为SupplyItem。包含有关对象的唯一属性。 使用INotifyPropertyChanged

我希望在我的主窗口上有一个DataGridView,并有一个全局集合类的绑定实例。每行应表示一个主要对象并显示其属性

每一行都应该有一个扩展按钮来展开该行,并查看一个数据网格,其中包含与主要对象关联的次要对象的每个学生的行

第三个对象稍后将出现在单独的数据网格中。我需要让第一部分工作起来

我正在努力使这项工作。通过XAML,我尝试了很多不同的方法来实现这一点,但我记不清了。什么都没用

XAML中的Intellisense显示每个属性和ItemSource都被适当地映射。没有生成错误。但是,在调试时,我可以看到行中列出了eah主对象。展开具有辅助对象的行时,将显示DataTable,但表中没有列出任何数据

我还使用了Live Property Explorer和Live Visual Tree。我可以将可视化树中的所有主要对象视为数据网格中的行。我甚至可以进入关联的次对象,查看这些对象的必要属性。但是,我无法将其显示在工作应用程序中

请帮忙!我做错了什么?非常感谢您的帮助

综合课堂

XAML-XAML的顶部

XAML

在StudentDataGrid中,ItemsSource应该是ItemsSource={Binding Path=Students},而不是ItemsSource={Binding Path=Coll.Students}

还要确保该数据网格中有一些未隐藏的列:

<DataGrid x:Name="StudentDataGrid"
          IsReadOnly="True"
          Margin="15,8,8,8"
          Width="1000"
          AutoGenerateColumns="False"
          ItemsSource="{Binding Path=Students}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Student Id"
                        Binding="{Binding Path=StudentId}"
                        Width="Auto"/>

  </DataGrid.Columns>
</DataGrid>

感谢@ASh和@sfaust帮助我理解这一点。答案在DataGrid.rowtailstemplate/DataTemplate中。我们必须将这里的数据类型设置为教室类,因为这是每行所代表的。然后将DataGrid ItemSource设置为学生的教室ObservableCollection属性

下面是更新的XAML代码 '


谢谢你。我已经尝试过了,但是我得到了一个错误,即无法解析“App.Objects.questions”类型的数据上下文中的属性“Students”。我相信这是因为它从父数据网格获取数据上下文。如何更改扩展数据网格的数据上下文?我已经研究了几种方法,但都没有成功。顺便说一句,谢谢你对专栏的评论。我也有额外的专栏,我只是从代码中删除,以避免问题变得杂乱无章。打开时的列仍然不显示数据。我还一直在考虑设置另一个Window.DataContext并在datatable中引用它。然而,这表明DataContext被设置了不止一次。。。关于DataContext,ASh是正确的,details部分继承了它显示详细信息的行的上下文,而不是父网格的上下文。您是在VS中收到警告还是在实际运行代码?我的猜测是第一个,这只是因为设计师并不总是善于了解上下文。您可以通过如下方式告诉它模板中的预期类型来解决此问题:另一个快速注释是,在整个类中,您在属性设置器中的名称是错误的,它应该是属性的名称,而不是类型。正如我对集合的偏好一样,我几乎总是让它们只在类构造时获取和初始化。这样,集合本身就永远不会为空,您只需修改集合中的对象,因为我发现您几乎不想实际更改集合本身。请格式化您的代码并修复缩进。很难看到嵌套了哪些标签对不起,这样应该更好。我一直在查看DataGrid.RowDetailsTemplate以及在DataTemplate中设置的数据类型,但是在将学生绑定到DataGrid以及将每个学生属性绑定到DataGrid的列时,这会导致相同的错误。错误:无法在类型为“App.Objects.questions”的数据上下文中解析属性“Students”。是否存在任何问题 g我还可以提供其他帮助来解决这个问题吗?我缺少什么?我需要帮助,这个问题被否决了。
    public class Classroom : ClassroomBaseClass
    {
        private Guid? _classroomId;
        public Guid? ClassroomId
        {
            get { return _classroomId; }
            set
            {
                _classroomId = value;
                OnPropertyChanged(nameof(ClassroomId));
            }
        }

        private ObservableCollection<Student> _students;
        public ObservableCollection<Job> Students
        {
            get { return _students; }
            set
            {
                _students = value;
                OnPropertyChanged(nameof(Students));
            }
        }

    }
    public class Student : StudentBaseClass
    {
        private Guid? _studentId;
        public Guid? StudentId
        {
            get { return _studentId; }
            set
            {
                _studentId = value;
                OnPropertyChanged(nameof(StudentId));
            }
        }

        private ObservableCollection<SupplyItem> _supplyitems;
        public ObservableCollection<SupplyItem> SupplyItems
        {
            get { return _supplyitems; }
            set
            {
                _supplyitems = value;
                OnPropertyChanged(nameof(SupplyItems));
            }
        }

    }

    public class SupplyItem : SupplyItemBaseClass
    {
        private Guid? _supplyId;
        public Guid? SupplyId
        {
            get { return _supplyId; }
            set
            {
                _supplyId = value;
                OnPropertyChanged(nameof(SupplyId));
            }
        }

    }

xmlns:appObjects="clr-namespace:App.Objects"

<Window.DataContext>
        <appObjects:Classrooms/>
</Window.DataContext>
<DataGrid x:Name="ClassroomDataGrid"                                           RowDetailsVisibilityMode="VisibleWhenSelected"
AutoGenerateColumns="False"                            RowDetailsVisibilityChanged="ClassroomDataGrid_RowDetailsVisibilityChanged"
Margin="30,60,30,10"
ItemsSource="{Binding Path=Colls}">

<DataGrid.Resources>
    <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"
           TargetType="{x:Type DataGridColumnHeader}">
           <Setter Property="Background" Value="#666666" />
           <Setter Property="Foreground" Value="#ffffff" />
           <Setter Property="FontSize" Value="15" />
           <Setter Property="FontStyle" Value="Normal" />
    </Style>
</DataGrid.Resources>

    <DataGrid.Columns>
        <DataGridTextColumn Header="GUID" Binding="{Binding Path=ClassroomId,UpdateSourceTrigger=PropertyChanged}"
        CanUserResize="True"
        Width="200" />

        <DataGridTemplateColumn Header="Students Expander" Width="100">

            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="appObjects:Classroom">
                    <Expander Width="50"
                         Expanded="Expander_Expanded"
                         Collapsed="Expander_Collapsed"
                         IsExpanded="{Binding Expanded,UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
         </DataGridTemplateColumn>
    </DataGrid.Columns>

    <DataGrid.RowDetailsTemplate>
         <DataTemplate >
            <DataGrid x:Name="StudentDataGrid"
                      IsReadOnly="True"
                      Margin="15,8,8,8"
                      Width="1000"
                      AutoGenerateColumns="False"
                      ItemsSource="{Binding Path=Coll.Students}">

                <DataGrid.Columns>
                      <DataGridTextColumn Header="Student Id"
                       Binding="{Binding Path =StudentId,UpdateSourceTrigger=PropertyChanged}"
                       Width="Auto"
                       Visibility ="Hidden"/>

        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
   </DataGrid.Columns>
</DataGrid>
<DataGrid x:Name="StudentDataGrid"
          IsReadOnly="True"
          Margin="15,8,8,8"
          Width="1000"
          AutoGenerateColumns="False"
          ItemsSource="{Binding Path=Students}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Student Id"
                        Binding="{Binding Path=StudentId}"
                        Width="Auto"/>

  </DataGrid.Columns>
</DataGrid>
<DataGrid.Resources>
    <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"
           TargetType="{x:Type DataGridColumnHeader}">
           <Setter Property="Background" Value="#666666" />
           <Setter Property="Foreground" Value="#ffffff" />
           <Setter Property="FontSize" Value="15" />
           <Setter Property="FontStyle" Value="Normal" />
    </Style>
</DataGrid.Resources>

    <DataGrid.Columns>
        <DataGridTextColumn Header="GUID" Binding="{Binding Path=ClassroomId,UpdateSourceTrigger=PropertyChanged}"
        CanUserResize="True"
        Width="200" />

        <DataGridTemplateColumn Header="Students Expander" Width="100">

            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="appObjects:Classroom">
                    <Expander Width="50"
                         Expanded="Expander_Expanded"
                         Collapsed="Expander_Collapsed"
                         IsExpanded="{Binding Expanded,UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
         </DataGridTemplateColumn>
    </DataGrid.Columns>

    <DataGrid.RowDetailsTemplate>
         <DataTemplate DataType="{x:Type appObjects:Classroom}">
            <DataGrid x:Name="StudentDataGrid"
                      IsReadOnly="True"
                      Margin="15,8,8,8"
                      Width="1000"
                      AutoGenerateColumns="False"
                      ItemsSource="{Binding Path=Students}">

                <DataGrid.Columns>
                      <DataGridTextColumn Header="Student Id"
                       Binding="{Binding Path =StudentId,UpdateSourceTrigger=PropertyChanged}"
                       Width="Auto"
                       Visibility ="Visible"/>

        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
   </DataGrid.Columns>
</DataGrid>