2013-01-23 7 views
0

J'utilise un modèle MVVM pour afficher les données arborescentes des transactions.WPF MVVM treeview performance

La hierachy est Client -> Comptes -> Transactions.

J'ai une classe de base TreeItemViewModel qui implémente des propriétés de dépendance de base comme IsExpanded, IsSelected etc qui sont 2 propriétés de dépendance à sens unique. Ensuite, j'ai un tas de classes telles que CustomerViewModel, AccountViewModel, TransactionViewModel. Chacun d'entre eux a une collection pour enfants. Ainsi, un CustomerViewModel contiendra une liste de AccountViewModels, chacun ayant sa propre collection Children de TransactionViewModels. J'utilise ensuite des datatemplates pour lier le XAML à ces modèles de vue, un exemple (modèle de transactionviewmodel) est donné ci-dessous.

Lorsque vous développez un nœud, la méthode IsExpanded de la classe de base est appelée, qui charge alors les enfants du nœud - il est donc charge paresseux. En outre, lorsque vous développez un nœud Client, il charge non seulement les comptes, mais également les transactions pour chaque compte, car elles sont nécessaires pour quelques données statistiques. Ainsi, lorsque vous développez le noeud de compte, tout ce qu'il a à faire est de rendre les transactionviewmodels en fonction des liaisons de datatemplate, car les enfants réels (objets transactionviewmodel) sont déjà chargés par ce point.

C'est ce rendu des transactions qui est extrêmement lent, surtout pour les gros volumes.

Je l'ai testé avec un client, un compte qui a 6000 transactions et en commentant la plupart des DataTemplate. Les horaires sont les suivants

colonnes d'image non seulement inclus - 26s Toutes les colonnes, changer la classe de convertisseur d'image pour retourner null au lieu d'une image - 51s Toutes les colonnes y compris les images: 20 minutes

Donc, mes préoccupations sont

1) Tout d'abord 27s pour charger 6000 transactions semble très lent et cela sans aucune image impliquée. Est-ce mon design qui le ralentit et comment pourrais-je le faire mieux sans réorganiser le tout? (pas une option à ce stade)

2) Comment puis-je accélérer le traitement de l'image afin de ne pas accrocher l'applcation?

Code Ok ci-dessous pour le modèle de données de transaction


   <Grid.RowDefinitions> 
        <RowDefinition Height="18" /> 
       </Grid.RowDefinitions> 

       <TextBlock Text="{Binding TransactionId}" /> 
       <TextBlock Grid.Column="1" Text="{Binding CutOffDate}" /> 
       <Image Grid.Column="2" Source="{Binding AlarmImg, Converter={StaticResource stringToImageConverter}}" Height="25" HorizontalAlignment="Left"/> 
       <TextBlock Grid.Column="3" Text="{Binding SourceSystemDesc}" /> 
       <Image Grid.Column="4" Margin="0,0,0,0" Source="{Binding CcmpImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="CCMP Type" HorizontalAlignment="Left"/> 
       <Image Grid.Column="5" Margin="0,0,0,0" Source="{Binding PrintedImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="Printed" HorizontalAlignment="Left"/> 
       <Image Grid.Column="6" Margin="0,0,0,0" Source="{Binding AppRejImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="Approved/Rejected" HorizontalAlignment="Left"/> 
       <Image Grid.Column="7" Margin="0,0,0,0" Source="{Binding LockImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="Locked" HorizontalAlignment="Left"/> 
       <TextBlock Grid.Column="8" Style="{StaticResource myTxnStyleColor}" Text="{Binding TxnAmount}" HorizontalAlignment="Right"/> 
       <TextBlock Grid.Column="9" Text="{Binding TxnCurrency}" HorizontalAlignment="Right" /> 
       <Image Grid.Column="10" Margin="0,0,0,0" Source="{Binding CurrencyImg, Converter={StaticResource stringToImageConverter}}" Height="25"/> 
      </Grid> 
     </DataTemplate> 

Et enfin, le convertisseur de ressource statique branlée pour revenir une image vide

using System; 
using System.Globalization; 
using System.Runtime.Caching; 
using System.Windows.Data; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 

namespace Citi.Rbcs.UI.Windows.HelperClasses 
{ 
    public class StringToImageConverter : IValueConverter 
    { 
     private static readonly BitmapImage BlankImage = 
      new BitmapImage(new Uri("pack://application:,,,/Resources/Images/Blank.gif")); 

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      try 
      { 
       return BlankImage; 

       var imageUrl = value as string; 
       if (string.IsNullOrEmpty(imageUrl)) return BlankImage; 

       // Strip out the Image name so we ignore path 
       if (imageUrl.LastIndexOf(@"\") != -1) 
        imageUrl = imageUrl.Substring(imageUrl.LastIndexOf(@"\") + 1); 
       if (imageUrl.LastIndexOf(@"/") != -1) 
        imageUrl = imageUrl.Substring(imageUrl.LastIndexOf(@"/") + 1); 

       var image = MemoryCache.Default.Get(imageUrl) as ImageSource; 

       if (image == null) 
       { 
        image = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/" + imageUrl)); 
        MemoryCache.Default.Set(imageUrl, image, new CacheItemPolicy()); 
       } 

       return image; 
      } 
      catch (Exception) 
      { 
       return BlankImage; 
      } 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

Toute aide serait grandement appréciée, Idéalement j'espère en vue d'arbre WPF de ces données de hierachichal que vous pouvez développer un nœud avec 6000 enfants dans environ 5-10 secondes. Qu'est-ce qui le rend si long, est-ce juste la liaison de données MVVM?

+2

Je suis désolé, mais je crains que personne ne lise tout le message. Veuillez le réduire à l'essentiel. – DHN

Répondre

0

Je suppose que vous ne montrez pas toutes les images du XAML en même temps.

Il y a deux raisons d'être lente:

1 - analyse syntaxique lourd XAML et le chargement est très très lent

2 - La liaison est grande, mais sont séquentielle et un verrouillage de liaison d'autres liaisons et ainsi de suite .

Vous pouvez essayer:

1 - Ne pas ajouter au contrôle innecesary temps desing dans votre XAML, ajoutez à l'exécution des commandes créant dynamiquement, est plus rapide (ou plus rapide). Faites-le même ceux-ci ne montrent pas, rappelez-vous que le problème est dans l'analyse et le chargement.

2 - Essayez d'utiliser une liaison asynchrone si possible. De cette façon, une liaison ne se verrouille pas.