2010-03-30 3 views
3

J'essaie actuellement de créer une scène dans WPF où j'ai environ 250 contrôles sur mon écran et l'utilisateur peut Pan et Zoom dans et hors de ces contrôles en utilisant la souris. J'ai exécuté les outils WPF Performance Suite sur l'application quand il y a un grand nombre de ces commandes sur l'écran (c'est-à-dire lorsque l'utilisateur a fait un zoom arrière) le FPS tombe à environ 15, ce qui n'est pas très bon.Performances WPF pour un grand nombre d'éléments sur l'écran

Voici les grandes lignes du XAML:

<Window> 
    <Window.Resources> 
    <ControlTemplate x:Key="LandTemplate" TargetType="{x:Type local:LandControl}"> 
     <Canvas> 
      <Path Fill="White" Stretch="Fill" Stroke="Black" StrokeThickness="1" Width="55.5" Height="74.687" Data="M0.5,0.5 L55,0.5 L55,74.187 L0.5,74.187 z"/> 
      <Canvas x:Name="DetailLevelCanvas" Width="24.5" Height="21" Canvas.Left="15.306" Canvas.Top="23.972"> 
       <TextBlock Width="21" Height="14" Text="712" TextWrapping="Wrap" Foreground="Black"/> 
       <TextBlock Width="17.5" Height="7" Canvas.Left="7" Canvas.Top="14" Text="614m2" TextWrapping="Wrap" FontSize="5.333" Foreground="Black"/> 
      </Canvas> 
     </Canvas> 
    </ControlTemplate> 
    </Window.Resources> 

    ... 
    <local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx"> 
    <local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx"> 
    <local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx"> 
    <local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx"> 
    ... and so on... 
</Window> 

Ive a essayé de minimiser les détails dans le modèle de contrôle et j'ai même fait une découverte massive et remplacer des contrôles de mettre juste leurs éléments bruts en ligne à la place d'utiliser un modèle, mais sans améliorations notables des performances. J'ai vu d'autres questions de SO à ce sujet et les gens disent de faire du dessin personnalisé, mais je ne vois pas vraiment comment cela a du sens quand vous devez zoomer et pan comme je le fais.

Si quelqu'un peut aider ici, ce serait génial!

Mark

Répondre

10

Cela peut sembler banal, mais - Il n'y a pas de repas gratuit. J'ai travaillé sur this au cours des deux dernières années. Ce produit se compose de 4 navigateurs dont les interfaces sont principalement des ZUI. Tous sauf l'Atlas utilisent Visuals pour leur rendu graphique et il y avait beaucoup de leçons apprises et quelques deadends.

1) FrameworkElements n'est pas votre ami. Le moteur FE sur une carte GFX moderne et le CPU atteint un maximum de 500 à 600 éléments, mais cela dépend de leur complexité. Les FE sont environ 10 fois plus lourds que les visuels.

2) Le texte aura un impact significatif sur votre framerate. courbes de rendu sont cher Voir Robby Ingebretsens post pour obtenir des conseils sur l'utilisation du texte animé

3) Abattage est important, mais l'ajout/suppression de la VisualTree est cher. Collapsing/Hiding est une sorte de compromis. 4) Dans WPF 3.5 vous avez 2 choix - Programmez le calque Visuals ou utilisez quelque chose comme le Planerator puis manipulez la caméra pour Pan et Zoom mais cela nécessite que vos utilisateurs aient une bonne carte gfx.

5) Dans WPF 4.0 les choses sont bien meilleures en raison de quelque chose appelé Cached Composition. Cela fonctionne pour la même raison que le Planerator. La carte GFX rend vos contrôles à une image bitmap et effectue un panoramique sur l'image bitmap.L'utilisation de ceci dans 4,0 est facile - Configurez .CacheMode pour vos FrameworkElements les plus chers et les choses vont beaucoup plus vite. Vous avez également la possibilité de contrôler la façon dont le texte est anti-crénelage et les échelles auxquelles bitmaps regénérés (EnableClearType et RenderAtScale)

Dans mon navigateur Atlas je pouvais afficher plus de 700 morceaux de rectangles de texte + simples sans perdre l'interactivité de panoramique et de zoom. Avant la carte était inutilisable.

Obtenir de meilleures performances interactives prend du temps, des objectifs et des mesures. Bonne chance.

Kael Rowan a une excellente série d'articles sur un ZoomableCanvas sur lequel il travaille. Il utilise un Quadtree et PriorityQueue pour la mise en œuvre et vous permettra d'implémenter le zoom sémantique.

Mise à jour: Ajout de texte 8-07-10 conseils et ZoomableCanvas Liens

+0

Merci pour les réponses détaillées, jusqu'à présent 4.0 n'est malheureusement pas possible , mais les éléments qui s'effondrent à certains niveaux de zoom semblent fonctionner, vous avez juste besoin d'être intelligent sur la façon dont vous décidez quoi montrer et quand. – Mark

0

Vous devriez être en mesure d'utiliser le dessin sur mesure en combinaison avec des transformations pour atteindre le zoom et de déplacement dont vous avez besoin. Vous aurez probablement besoin de faire des sélections de base pour empêcher le rendu des éléments qui ne sont pas dans la fenêtre ... mais les capacités de transformation de WPF sont assez riches, et vous devriez gagner une quantité décente de performance avec cela.

Transforms Overview
How to: Scale an Object
How to: Translate an Element

+0

Im ne pas avoir un problème avec la mise à l'échelle et les traductions, ils fonctionnent très bien. Je suppose que je suis plus confus sur la façon de changer ma situation actuelle afin qu'elle utilise un dessin personnalisé ... – Mark

+0

Je voudrais en savoir plus sur votre LandControl pour vous donner d'autres conseils. Je ne suis pas exactement sûr de ce que vous dessinez, ou de la complexité ... – jrista

+0

Chaque instance de LandControl utilise le modèle défini dans le XAML ci-dessus, c'est juste un chemin rectangle avec 2 morceaux de texte ... ça! – Mark

Questions connexes