2009-11-18 6 views
4

Je crée mon propre FrameworkElement et remplace VisualChildrenCount {get;} et GetVisualChild (int index) en retournant ma propre instance de collection DrawingVisual. J'ai remplacé OnRender.Amélioration de la vitesse de rendu du dessinvisual

Je vais ajouter 20-50 DrawingVisuals dans ce FrameworkElement, chaque DrawingVisual aura 2000 segments de ligne. La valeur logique de ces points entre 0 et 60000.Quand je zoom dans 1: 1 la hauteur de FrameworkElement sera 60000, le temps de déchirement sera de 15 minutes !!

Comment améliorer les performances de rendu?

Répondre

4

Pour ce type de volume de données, je vous suggère de créer un GeometryDrawing et un StreamGeometry contenant un seul PolyLine pour chacun de vos points. Puis combinez-les tous ensemble dans un seul DrawingGroup et affichez-le en utilisant un seul DrawingVisual.

Ce serait le XAML:

<DrawingVisual Drawing="{Binding CurrentDrawing}" /> 

et ce serait le code pour mettre à jour CurrentDrawing:

var group = new DrawingGroup(); 
foreach(var data in myData) 
{ 
    StreamGeometry geo = new StreamGeometry(); 
    using(geoContext = geo.Open()) 
    { 
    geoContext.BeginFigure(myData.StartPoint, false, false); 
    geoContext.PolyLineTo(myData.AdditionalPoints, true, false); 
    } 
    group.Add(new GeometryDrawing 
    { 
    Geometry = geo, 
    Pen = myData.Pen, 
    }); 
} 
CurrentDrawing = group; 
... 

Si vos données sont en train de changer, il peut être avantageux de créer stocker chaque objet GeometryDrawing séparément il est donc seulement nécessaire de recréer les GeometryDrawings dont les données sources ont changé.

Mise à jour

Vous mentionnez dans votre commentaire que vous devez séparément hittest chacun des éléments de données 20-50. Dans ce cas, vous voulez probablement utiliser un DrawingVisual distinct pour chacun. Pour optimiser les performances que vous souhaitez utiliser avec RenderOpen()DrawingContext:

IEnumerable<Visual> BuildVisuals() 
{ 
    return 
    from var data in myData 
    select BuildVisualForData(data); 
} 

void BuildVisualForData(MyDataType data) 
{ 
    var geo = new StreamGeometry(); 
    using(geoContext = geo.Open()) 
    { 
    geoContext.BeginFigure(myData.StartPoint, false, false); 
    geoContext.PolyLineTo(myData.AdditionalPoints, true, false); 
    } 

    var visual = new DrawingVisual(); 
    using(drawingContext = visual.RenderOpen()) 
    { 
    drawingContext.DrawGeometry(null, myData.Pen, geo); 
    } 
    return visual; 
} 
+0

Hi Ray Merci pour votre réponse, je vais essayer bientôt. –

+0

J'ai besoin d'utiliser hittesting pour mettre en évidence chaque visuel. Si je les affiche en utilisant un seul DrawingVisual, je pense que ce n'est peut-être pas à faire. –

+0

Dans ce cas, placez chaque élément de données dans son propre DrawingVisual et utilisez RenderOpen() et DrawingContext. J'ai édité ma réponse pour montrer comment cela serait fait. –

0

J'ai besoin d'utiliser hittesting pour mettre en évidence tous les visuels. Si je les affiche en utilisant un seul DrawingVisual, je pense que ce n'est peut-être pas à faire.

Pour ce type de volume de données, je vous suggère de créer un GeometryDrawing et StreamGeometry contenant un seul PolyLine pour chacun de vos points. Puis combinez-les tous ensemble dans un seul DrawingGroup et affichez-le en utilisant un seul DrawingVisual.

Ce serait le XAML:

<DrawingVisual Drawing="{Binding CurrentDrawing}" /> 

et ce serait le code pour mettre à jour CurrentDrawing:

var group = new DrawingGroup(); 
foreach(var data in myData) 
{ 
    StreamGeometry geo = new StreamGeometry(); 
    using(geoContext = geo.Open()) 
    { 
    geoContext.BeginFigure(myData.StartPoint, false, false); 
    geoContext.PolyLineTo(myData.AdditionalPoints, true, false); 
    } 
    group.Add(new GeometryDrawing 
    { 
    Geometry = geo, 
    Pen = myData.Pen, 
    }); 
} 
CurrentDrawing = group; 
... 

Si vos données sont en train de changer, il peut être avantageux de créer stocker chaque objet GeometryDrawing séparément il est donc seulement nécessaire de recréer ces GeometryDrawings dont les données sources ont changé

Questions connexes