Как я могу создать вложенную DataGrid, где внутренняя сетка данных показывает детали элемента? - PullRequest
0 голосов
/ 22 января 2020

Допустим, у нас есть Person класс модели, который имеет следующие свойства:

  • Id
  • FirstName
  • LastName
  • PhoneNumber
  • AddressLine1
  • AddressLine2
  • Postcode

Я хочу показать некоторые из эти свойства (Id, FirstName и LastName) во внешней сетке данных, а остальные - во внутренней сетке данных, которая отображается при раскрытии элемента. Эта внутренняя сетка данных будет иметь одну строку, отображающую остальные свойства для выбранного Person. У меня есть DataGrid, который отображает список Person объектов и имеет столбцы Id, FirstName и LastName (столбцы указываются вручную). В настоящее время существует RowDetailsTemplate, который содержит Grid, который сам содержит TextBlock s, которые связаны с оставшимися Person свойствами:

<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch" AutoGenerateColumns="False" x:Name="PersonsDataGrid"
                      ColumnWidth="*" IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="False" CanUserSortColumns="False" 
                      CanUserReorderColumns="False" CanUserResizeRows="False" SelectionMode="Single" SelectionUnit="FullRow" SelectedItem="{Binding SelectedPerson}">
  <DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="50"/>
  <DataGridTemplateColumn Header="First Name">
    <DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
        <TextBlock Text="{Binding FirstName}" TextWrapping="Wrap" Margin="0,10" />
      </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
  </DataGridTemplateColumn>
  <DataGridTemplateColumn Header="Last Name">
    <DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
        <TextBlock Text="{Binding LastName}" TextWrapping="Wrap" Margin="0,10" />
      </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
  </DataGridTemplateColumn>
  <DataGrid.RowDetailsTemplate>
    <DataTemplate>
      <Border BorderBrush="Transparent" BorderThickness="0" Background="LightGray">
        <Grid Margin="10">
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
          </Grid.ColumnDefinitions>
          <TextBlock Grid.Row="0" Grid.Column="0" Text="Phone Number: " Foreground="Black" FontWeight="SemiBold"/>
          <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding PhoneNumber}" TextWrapping="Wrap" Foreground="Black"/>
          <TextBlock Grid.Row="1" Grid.Column="0" Text="Address Line 1: " Foreground="Black" FontWeight="SemiBold"/>
          <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding AddressLine1}" TextWrapping="Wrap" Foreground="Black"/>
          <TextBlock Grid.Row="2" Grid.Column="0" Text="Address Line 2: " Foreground="Black" FontWeight="SemiBold"/>
          <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding AddressLine2}" TextWrapping="Wrap" Foreground="Black"/>
          <TextBlock Grid.Row="3" Grid.Column="0" Text="Postcode: " Foreground="Black" FontWeight="SemiBold"/>
          <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Postcode}" TextWrapping="Wrap" Foreground="Black"/>
        </Grid>
      </Border>
    </DataTemplate>
  </DataGrid.RowDetailsTemplate>
</DataGrid>

Этот внутренний Grid должен быть заменен с DataGrid, который содержит одну строку, показывающую оставшиеся свойства для выбранного объекта Person, например:

<DataGrid.RowDetailsTemplate>
  <DataTemplate>
    <Border BorderBrush="Transparent" BorderThickness="0" Background="LightGray">
      <DataGrid ItemsSource="{Binding}" Margin="10" ColumnWidth="50" SelectionUnit="FullRow"
                AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False" CanUserReorderColumns="False" CanUserDeleteRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding PhoneNumber}" Header="Phone Number"/>
            <DataGridTextColumn Binding="{Binding AddressLine1}" Header="Address Line 1"/>
            <DataGridTextColumn Binding="{Binding AddressLine2}" Header="Address Line 2"/>
            <DataGridTextColumn Binding="{Binding Postcode}" Header="Postcode"/>
        </DataGrid.Columns>
      </DataGrid>
    </Border>
  </DataTemplate>
</DataGrid.RowDetailsTemplate>

Я также пробовал другие варианты, такие как предоставление ItemSource внутренней сетки * имя и замена PhoneNumber, AddressLine1 et c. с Item.PhoneNumber, Item.AddressLine1 et c. Я также попытался полностью удалить атрибут ItemSource из внутренней сетки, как PhoneNumber, AddressLine1 et c. во внутренней сетке следует просто ссылаться на свойства Person, как и в случае привязок в столбцах внешней сетки.

Однако, каждый раз, когда я пытался, результаты приводят к тому, что сетка данных становится пустой.

Я видел похожие вопросы, но, похоже, они касаются других вещей - например, отображение другого списка во внутренней сетке в отличие от выбранного элемента или не использование DataGrid в качестве внутреннего элемента, что я в настоящее время.

Возможно ли это в WPF? Если так, то как? Или я должен придерживаться моего текущего решения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...