2009-09-29 10 views
13

Attualmente sto sviluppando uno strumento di visualizzazione che disegna forme WPF come percorsi, ellissi ecc. Su una tela. Ho già implementato un approccio virtualizzato in cui le forme vengono distrutte e create al volo a seconda della loro visibilità. Tuttavia, anche con solo 600 ellissi visibili, l'applicazione sembra faticare.Prestazioni WPF: visualizzazione di migliaia di percorsi/forme su una tela

Quali sono le opzioni per accelerare le cose? Sto pensando di rendere forme raggruppate (diciamo 500 alla volta) come bitmap trasparenti e di dipingerle solo sulla tela. Ma io non so se questa è una buona idea ... Da quanto ho capito questo richiede una sorta di hack, se sono state applicate le trasformazioni:

 VisualBrush shapeBrush = new VisualBrush(shape); 

    DrawingVisual drawingVisual = new DrawingVisual(); 
    DrawingContext drawingContext = drawingVisual.RenderOpen(); 

    using (drawingContext) 
    { 
     drawingContext.DrawRectangle(shapeBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight))); 
    } 
    renderTarget.Render(drawingVisual); 

Cosa succede ad usare una grande WritableBitmap? Questo sarebbe un altro approccio?

risposta

6

WPF sotto le copertine lavora con disegni e geometrie - quando dici che stai lavorando con le forme, sono questi UIElements reali? Tali elementi sono un po 'più pesanti. Se si utilizzano geometrie di base (preferibilmente stream) per disegnare disegni, si ottengono le migliori prestazioni nella mia esperienza.

Sono riuscito a ottenere fino a circa 10000 punti con un ragionevole framerate con tale approccio, ma qualcosa di più complesso di un punto inizia a rallentare le cose (ad esempio, punti rotondi o anche solo rettangoli). Tuttavia, geometrie di base e disegni di base sono la strada da percorrere se si desidera evitare il maggior carico possibile di WPF.

Una bitmap scrivibile è chiaramente alla fine più veloce, ma ciò significa che si rimuovono tutte quelle forme da soli, oppure, memorizzando nella cache la bitmap del risultato se è per lo più statica. Inoltre, in genere si desidera applicare le trasformazioni prima di eseguire il rendering in bitmap anziché applicarle alla bitmap renderizzata.

+0

Attualmente sto utilizzando questo approccio: una classe VirtualPath che memorizza i dati del percorso e restituisce un WPF System.Windows.Shapes.Path non appena i suoi limiti sono visibili. – kitsune

+0

Grazie per avermi segnalato StreamGeometry, non conoscevo ancora questa classe – kitsune

+1

@kitsune, hai mai completato il trucco "virtualpath che restituisce un percorso non appena visibile"? Penso che potrei trarne beneficio in uno dei miei progetti –

-1

Un approccio a forza bruta potrebbe essere quello di implementare un controllo ActiveX e rendere la grafica direttamente utilizzando Win32. Tuttavia, questo sarà un po 'complicato. Il controllo della tela di QT potrebbe essere un approccio più caldo e soffice allo stesso fine ed è noto per rendere questo tipo di cose abbastanza velocemente. Troll fornisce un wrapper ActiveX per le versioni commerciali di QT, quindi potrebbe essere più semplice da integrare.

+1

Com'è una cosa rilevante per una domanda taggata 'WPF'? – stakx

2

Sono consapevole che questa è una vecchia domanda, sto solo rispondendo nell'interesse della comunità.

Ho ricercato un po 'l'argomento e il migliore che ho trovato è quello di creare manualmente DrawingVisuals come dici tu. Fa risparmiare un sacco di lavoro interno a WPF, quindi finisce per essere molto più veloce. Ho usato la tecnica per creare un grafico leggero che può avere un paio di centinaia di punti. Ecco l'articolo da cui mi sono ispirato, potresti già saperlo.

http://blogs.microsoft.co.il/blogs/tamir/archive/2008/03/02/how-to-high-performance-graphics-in-wpf.aspx

EDIT: Nuovo URL http://khason.net/blog/how-to-high-performance-graphics-in-wpf/
EDIT: Newer URL: http://dedjo.blogspot.com/2008/03/how-to-high-performance-graphics-in-wpf.html

Buona fortuna.

Problemi correlati