2010-09-23 115 views
2

我有一个非常大的逗号分隔的文本文件。我需要在WPF Datagrid中显示它,哪种方法会将所有数据加载到网格中的性能最高?我只知道两种方法:WPF Datagrid性能

  • 使用一个DataTable,并加入每行排(貌似矫枉过正)
  • 使用一个ObservableCollection,每个行创建对象(貌似矫枉过正)

是否有第三种方法来填充Datagrid,这将提供更高的性能?

回答

2

取决于您打算如何处理数据。如果数据将只读,您可以定义一个List并将其设置为DataGrid的ItemsSource。然后datagrid会自动创建所有行来表示列表中的项目。

如果要处理数据,可以使用BindingList <>或ObservableCollection <>。

“如何为每条线创建对象”是一种矫枉过正?您必须将一行/一行数据表示为一个对象。这只是常识,不可能以任何其他方式进行。

基本上,如果性能是你之后的那么datagrid的ItemsSource必须尽可能轻。如果您不打算使用它的所有功能,那么DataTable可能是一种矫枉过正的行为。另一方面,列表<>尽可能轻。

另请注意,默认情况下,WPF数据网格使用虚拟化,这也有助于提高性能。有一些注意事项,比如不要将数据网格放入堆栈面板,否则虚拟化效果就会消失 - 您可以通过谷歌关于这一点。

最后一件事,根据我的经验,.NET4 WPF内置数据网格有一个严重的设计错误。基本上每个DataGridRow即使是最简单的数据也会消耗1MB的内存。通过虚拟化,只显示30行,这不是一个大问题 - 只消耗30MB的内存。但采取一千行,关闭虚拟化和内存消耗是3GB!相比之下,WinForm datagridview消耗的内存少于使用相同数据的10倍以上。即使在禁用虚拟化的情况下,一千行也只需要30MB ...

我在Connect中打开了一个关于此问题的错误消息,但专家们尚未研究此问题。不知道WPF工具包数据网格的行为是否更好...

+0

感谢马尔科!我改变了所有使用List(Of)而不是Datatables。我的新问题是,使用List(Of)我失去了排序Datagrid列的能力,但这是一个完全不同的主题;) – Muis 2010-09-24 11:23:06

+0

然后,您可以使用ObservableColletion,它支持排序。 – Marko 2010-09-24 13:14:24

+0

您是否也碰巧知道是否有办法模拟Dataview的.RowFilter属性?因为我失去了使用类似SQL的查询的能力。 – Muis 2010-09-24 14:32:45

0

如果使用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