2010-09-23 7 views
2

J'ai un très grand fichier texte séparé par des virgules. J'ai besoin de l'afficher dans une base de données WPF, quelle méthode aboutirait à la meilleure performance de chargement de toutes les données sur la grille? Je suis seulement au courant des deux méthodes suivantes:Performances WPF Datagrid

  • l'aide d'un Datatable, et en ajoutant chaque ligne comme rangée (qui ressemble à overkill)
  • L'utilisation d'un ObservableCollection, crée un objet pour chaque ligne (qui ressemble à overkill)

Existe-t-il une troisième méthode pour remplir Datagrid, ce qui donnerait des performances plus élevées?

Répondre

2

Dépend de ce que vous avez l'intention de faire avec les données. Si les données sont en lecture seule, vous pouvez définir une liste et la définir en tant que ItemsSource pour la grille de données. Ensuite, la grille de données crée automatiquement toutes les lignes pour représenter les éléments de la liste.

Si les données doivent être manipulées, vous pouvez utiliser une BindingList <> ou une ObservableCollection <>.

Comment « crée l'objet pour chaque ligne » un surpuissant? Vous devez représenter une ligne/ligne de données en tant qu'objet. C'est juste du bon sens, ce n'est pas possible de le faire autrement.

En fait, si la performance est ce que vous êtes après alors ItemsSource du DataGrid doit être aussi léger que possible. Un DataTable peut être excessif si vous n'avez pas l'intention d'utiliser toutes ses fonctionnalités. Une liste <> d'autre part est aussi léger que possible.

Notez également que le DataGrid WPF utilise par défaut la virtualisation, ce qui contribue à la performance aussi bien. Il y a quelques mises en garde, comme ne pas mettre la grille de données dans un panneau de pile sinon l'effet de virtualisation disparaît - vous pouvez google à ce sujet.

Une dernière chose, par mon expérience, la .NET4 WPF builtin DataGrid a un bug de conception sérieux. Fondamentalement, chaque DataGridRow consomme 1 Mo de mémoire, même pour la plus simple des données. Avec la virtualisation et l'affichage de 30 lignes seulement, ce n'est pas un gros problème - seulement 30 Mo de mémoire sont consommés. Mais prenez un millier de lignes, désactivez la virtualisation et la consommation de mémoire est de 3 Go !!!! Par contre, une vue de données WinForm consomme plus de 10 fois moins de mémoire avec les mêmes données. Même avec la virtualisation désactivé mille lignes ne prend 30MB ...

J'ai ouvert un bug à ce sujet dans Connect, mais les experts spécialisés doivent encore se pencher sur cette question. Je ne sais pas si la boîte à outils DataGrid WPF se comporte mieux ...

+0

Merci Marko! J'ai tout changé pour utiliser List (Of) au lieu de Datatables.Mon nouveau problème est, qu'en utilisant List (Of) j'ai perdu ma capacité à trier mes colonnes Datagrid, mais c'est un sujet complètement différent;) – Muis

+0

Vous pouvez utiliser ObservableColletion puis, qui supporte le tri. – Marko

+0

Savez-vous également s'il existe un moyen d'émuler la propriété .RowFilter de Dataview? Parce que j'ai perdu ma capacité à utiliser les requêtes de type SQL. – Muis

0

Vous pouvez lier à un DataView si vous chargez un fichier délimité par des virgules en utilisant OleDb.
Remarque: Je n'ai pas testé un grand ensemble de données.

Voici la liaison au 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> 

Voici le ViewModel:

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; 
    } 
    } 
} 

Voici le fichier de données utilisé i:

name,site,extra 
jeff,codinghorror,stackoverflow 
joel,joelonsoftware,stackoverflow 
zamboni,secondbeach,stackoverflow