我有一個非常大的逗號分隔的文本文件。我需要在WPF Datagrid中顯示它,哪種方法會將所有數據加載到網格中的性能最高?我只知道兩種方法:WPF Datagrid性能
- 使用一個DataTable,並加入每行排(貌似矯枉過正)
- 使用一個ObservableCollection,每個行創建對象(貌似矯枉過正)
是否有第三種方法來填充Datagrid,這將提供更高的性能?
我有一個非常大的逗號分隔的文本文件。我需要在WPF Datagrid中顯示它,哪種方法會將所有數據加載到網格中的性能最高?我只知道兩種方法:WPF Datagrid性能
是否有第三種方法來填充Datagrid,這將提供更高的性能?
取決於您打算如何處理數據。如果數據將只讀,您可以定義一個List並將其設置爲DataGrid的ItemsSource。然後datagrid會自動創建所有行來表示列表中的項目。
如果要處理數據,可以使用BindingList <>或ObservableCollection <>。
「如何爲每條線創建對象」是一種矯枉過正?您必須將一行/一行數據表示爲一個對象。這只是常識,不可能以任何其他方式進行。
基本上,如果性能是你之後的那麼datagrid的ItemsSource必須儘可能輕。如果您不打算使用它的所有功能,那麼DataTable可能是一種矯枉過正的行爲。另一方面,列表<>儘可能輕。
另請注意,默認情況下,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
感謝馬爾科!我改變了所有使用List(Of)而不是Datatables。我的新問題是,使用List(Of)我失去了排序Datagrid列的能力,但這是一個完全不同的主題;) – Muis 2010-09-24 11:23:06
然後,您可以使用ObservableColletion,它支持排序。 – Marko 2010-09-24 13:14:24
您是否也碰巧知道是否有辦法模擬Dataview的.RowFilter屬性?因爲我失去了使用類似SQL的查詢的能力。 – Muis 2010-09-24 14:32:45