我有一个非常大的逗号分隔文本文件。我需要在 WPF Datagrid 中显示它,哪种方法会导致将所有数据加载到网格中的最高性能?我只知道两种方法:
- 使用数据表,并将每一行添加为行(看起来有点矫枉过正)
- 使用 ObservableCollection,为每一行创建对象(看起来有点矫枉过正)
是否有第三种方法来填充 Datagrid,这将提供更高的性能?
我有一个非常大的逗号分隔文本文件。我需要在 WPF Datagrid 中显示它,哪种方法会导致将所有数据加载到网格中的最高性能?我只知道两种方法:
是否有第三种方法来填充 Datagrid,这将提供更高的性能?
取决于您打算如何处理数据。如果数据是只读的,您可以定义一个 List 并将其设置为数据网格的 ItemsSource。然后数据网格将自动创建所有行来表示列表中的项目。
如果要操作数据,您可以使用 BindingList<> 或 ObservableCollection<>。
“为每一行创建对象”如何过度杀伤?您必须将一行/行数据表示为一个对象。这只是常识,不可能以任何其他方式做到这一点。
基本上,如果性能是您所追求的,那么数据网格的 ItemsSource 必须尽可能轻。如果您不打算使用它的所有功能,则 DataTable 可能是一种矫枉过正。另一方面, List<> 的重量尽可能轻。
另请注意,WPF 数据网格默认使用虚拟化,这也有助于提高性能。有一些警告,比如不要将数据网格放在堆栈面板中,否则虚拟化效果会消失 - 你可以用谷歌搜索。
最后一件事,根据我的经验,.NET4 WPF 内置数据网格有一个严重的设计错误。基本上每个 DataGridRow 都会消耗 1MB 的内存,即使是最简单的数据也是如此。使用虚拟化并且只显示 30 行,这并不是什么大问题——只消耗了 30MB 的内存。但是取一千行,关闭虚拟化,内存消耗是3GB!!!!相比之下,WinForm datagridview 使用相同的数据消耗的内存要少 10 倍以上。即使禁用了虚拟化,一千行也只需要 30MB ......
我在 Connect 中打开了一个关于此的错误,但专业专家尚未调查此问题。不确定 WPF 工具包数据网格的行为是否更好......
如果使用 OleDb 加载逗号分隔的文件,则可以绑定到 DataView。
注意:我没有测试大型数据集。
这是到 DataGrid 的绑定:
<Window x:Class="DatagridBackgroundWorker.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfToolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
Loaded="Window_Loaded"
Title="Main Window" Height="400" Width="800">
<DockPanel>
<Grid>
<WpfToolkit:DataGrid
ItemsSource="{Binding Path=GridData, Mode=OneWay}" >
</WpfToolkit:DataGrid>
</Grid>
</DockPanel>
</Window>
这是视图模型:
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
// name of the file
string fileName = "MyData.txt";
// location of the file
string filePath = Environment.CurrentDirectory;
string connection = @"Provider=Microsoft.Jet.OleDb.4.0; Data Source = " +
filePath +
";Extended Properties=\"Text;HDR=Yes;FMT=Delimited\"";
OleDbConnection conn = new OleDbConnection(connection);
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [" + fileName + "]", conn);
adapter.Fill(_ds);
}
private DataSet _ds = new DataSet("MyDataSet");
public DataView GridData
{
get
{
return _ds.Tables[0].DefaultView;
}
}
}
这是我使用的数据文件:
name,site,extra
jeff,codinghorror,stackoverflow
joel,joelonsoftware,stackoverflow
zamboni,secondbeach,stackoverflow