发现数据源的架构

时间:2018-05-18 06:41:04

标签: c# wpf datagrid pagination

类需要为DataGrid实现哪些接口来自动发现其模式并生成列?

详细

我正在尝试为DataGrid实现分页。基础数据源是DataTable。将DataGrid直接绑定到DataTable可以正常工作,AutoGenerateColumns可以正常工作。

由于传入数据的大小和响应慢DataGrid,我不得不使用行虚拟化,这导致了几个(已知)问题,我不得不将其关闭。

我现在正在研究分页方法。找到了PagingCollectionView的良好实现并尝试了它。 DataGrid为当前页面正确生成,但不是列。看起来它无法读取底层集合的架构。 (请注意,链接处的代码不使用AutoGenerateColumns,因此不会遇到问题)。

我进一步调查了DataTableDataView实现哪些特殊接口来公开其架构。看来(我可能错了)ITypedList是我需要实现的接口。我继续实施这个,现在卡住了GetItemProperties()。似乎没有办法为PropertyDescriptor的每一列手动构建DataTable。有TypeDesriptor可以获取给定类型的所有公共属性,但这显然不适用于DataTable列。

那么,我需要做些什么才能使DataGrid发现我的CollectionView类架构?

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加载需要更多时间。

0 个答案:

没有答案