类需要为DataGrid
实现哪些接口来自动发现其模式并生成列?
我正在尝试为DataGrid
实现分页。基础数据源是DataTable
。将DataGrid
直接绑定到DataTable
可以正常工作,AutoGenerateColumns
可以正常工作。
由于传入数据的大小和响应慢DataGrid
,我不得不使用行虚拟化,这导致了几个(已知)问题,我不得不将其关闭。
我现在正在研究分页方法。找到了PagingCollectionView的良好实现并尝试了它。 DataGrid
为当前页面正确生成行,但不是列。看起来它无法读取底层集合的架构。 (请注意,链接处的代码不使用AutoGenerateColumns
,因此不会遇到问题)。
我进一步调查了DataTable
和DataView
实现哪些特殊接口来公开其架构。看来(我可能错了)ITypedList
是我需要实现的接口。我继续实施这个,现在卡住了GetItemProperties()
。似乎没有办法为PropertyDescriptor
的每一列手动构建DataTable
。有TypeDesriptor
可以获取给定类型的所有公共属性,但这显然不适用于DataTable
列。
那么,我需要做些什么才能使DataGrid
发现我的CollectionView类架构?
以下是显示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加载需要更多时间。