2010-09-23 114 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