Откройте схему источника данных - PullRequest
0 голосов
/ 18 мая 2018

Какой интерфейс (ы) нужно реализовать классу для DataGrid, чтобы автоматически обнаруживать его схему и генерировать столбцы?

Подробно

Я пытаюсь реализовать подкачку для DataGrid.Основным источником данных является DataTable.Привязка DataGrid непосредственно к DataTable работает нормально, а AutoGenerateColumns делает свою работу.

Из-за большого размера входящих данных и медленного ответа DataGrid мне пришлось использовать виртуализацию строк, что привело к нескольким (известным) проблемам, и мне пришлось отключить их.

Сейчас я работаю над пейджинговым подходом.Нашел хорошую реализацию PagingCollectionView и попробовал ее.DataGrid правильно генерирует строк для текущей страницы, но не столбцы .Похоже, что он не может прочитать схему базовой коллекции.(Обратите внимание, что код по ссылке не использует AutoGenerateColumns и, следовательно, не страдает от проблемы под рукой).

Я провел дальнейшее исследование, чтобы увидеть, какие специальные интерфейсы DataTable и DataView реализуют для предоставления своей схемы.Кажется (и я могу ошибаться), что ITypedList - это интерфейс, который мне нужно реализовать.Я продолжал реализовывать это и теперь застрял GetItemProperties().Не существует способа построить PropertyDescriptor с вручную для каждого столбца DataTable.Существует TypeDesriptor, который может получить все открытые свойства данного типа, но он явно не будет работать для DataTable столбцов.

Итак, что мне нужно сделать, чтобы создать схему класса CollectionViewстать обнаруживаемым для DataGrid?

MCVE

Вот минимальный код, который показывает проблему с DataGrid:

XAML

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button Content="Select All" Click="SelectAll_Click" Grid.Row="0" />
    <Button Content="Deselect All" Click="Deselect_Click" Grid.Row="1" />

    <DataGrid x:Name="DG" AutoGenerateColumns="False" SelectionUnit="FullRow" Grid.Row="2">
      <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding ID}" />
        <DataGridTextColumn Binding="{Binding Name}" />
      </DataGrid.Columns>

      <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode  =TwoWay}" />
        </Style>
      </DataGrid.RowStyle>
    </DataGrid>
  </Grid>
</Window>

Код

using System.Data;

class MainWindow
{
  DataTable DT = new DataTable();

  MainWindow()
  {
    // This call is required by the designer.
    InitializeComponent();

    DT.Columns.Add(new DataColumn("ID", typeof(Int32)));
    DT.Columns.Add(new DataColumn("Name", typeof(string)));
    DT.Columns.Add(new DataColumn("IsSelected", typeof(bool)));

    for (index = 1; index <= 10000; index++) {
      var NR = DT.NewRow();
      NR["ID"] = index;
      NR["Name"] = System.Guid.NewGuid().ToString();
      DT.Rows.Add(NR);
    }

    DG.ItemsSource = DT.DefaultView;
  }

  private void SelectAll_Click(object sender, RoutedEventArgs e)
  {
    for (int i = 0; i < DT.Rows.Count; i++) {
      DT.Rows[i]["IsSelected"] = true;
    }
  }

  private void Deselect_Click(object sender, RoutedEventArgs e)
  {
    for (int i = 0; i < DT.Rows.Count; i++) {
      DT.Rows[i]["IsSelected"] = false;
    }
  }
}

Запустите код и нажмите Выбрать все кнопку.Все строки кажутся выбранными .Прокрутите вниз до нижней части DataGrid.Нажмите Отмените выбор всех .Теперь медленно прокрутите вверх.Вы увидите, что многие строки все еще выбраны.Перейдите к своему XAML и отключите виртуализацию строк для DataGrid.Выбор теперь будет работать нормально, но для загрузки DataGrid потребуется больше времени.

...