2009-10-16 12 views
6

Ho aggiunto un po 'di animazione alla mia applicazione WPF.WPF - Spegnimento evento ripetuto Aggiornamento evento

Grazie a Dan Crevier's unique solution to animating the children of a panel combinato con lo awesome WPF Penner animations, è risultato abbastanza semplice rendere uno dei miei controlli fantastico e far muovere i suoi bambini con delle belle animazioni.

Sfortunatamente tutto questo è accompagnato da un sovraccarico prestazionale. Sono felice di avere la performance colpita quando gli articoli vengono aggiunti/rimossi o il controllo viene ridimensionato, ma sembra che questo colpo perfetto si verifichi costantemente durante tutta la vita dell'applicazione, anche quando gli articoli sono completamente statici.

La classe PanelLayoutAnimator utilizza una proprietà associata per agganciare l'evento UIElement.LayoutUpdated. Quando questo evento si attiva, le animazioni di rendering vengono animate per far scivolare i bambini nelle loro nuove posizioni.

Sfortunatamente sembra che l'evento LayoutUpdated si accenda ogni secondo o così, anche quando non accade nulla nell'applicazione (almeno non penso che il mio codice stia facendo qualcosa - l'app non ha il focus e il mouse è costante.) Poiché la motivazione dell'evento non è immediatamente evidente per il gestore dell'evento, tutti i bambini del controllo devono essere rivalutati. Questo evento viene chiamato circa una volta al secondo quando inattivo. La frequenza aumenta quando si utilizza effettivamente l'app.

Quindi la mia domanda è: come posso migliorare le prestazioni qui? Qualsiasi risposta che assiste sarebbe apprezzato, ma sto attualmente bloccato su queste sotto-domande:

  1. Quali sono le cause dell'evento LayoutUpdated al fuoco così frequentemente? Questo dovrebbe succedere, e se no, come posso scoprire perché sta sparando e ridurlo?

  2. C'è un modo più conveniente all'interno del gestore per sapere se è successo qualcosa che potrebbe aver spostato i bambini? Se è così, potrei uscire in anticipo e evitare il sovraccarico del ciclo di ogni bambino.

Per ora mi aggirare il problema disattivando l'animazione quando ci sono più di N bambini nel pannello.

+0

Drew, la prego di condividere codice di esempio piccolo che potrebbe riprodurre il problema? – Anvaka

+0

Sì, perché LayoutUpdated dovrebbe essere attivato solo se qualcosa sta effettivamente causando l'aggiornamento del layout ... ovvio come sembra. :) Dato che non stai interagendo con la finestra, non so cosa possa scatenare questo oltre alle animazioni per le dimensioni, la posizione o la trasformazione del layout. –

+0

Hmm l'app è abbastanza grande. Se LayoutUpdated non dovrebbe sparare regolarmente, allora quale tecnica posso usare per scoprire perché sta sparando? –

risposta

7

Se stai aggiornando l'interfaccia utente dall'EventHandler che hai allegato all'evento LayoutUpdated, questo attiverà anche quell'evento!

Ad esempio:

void my_LayoutUpdatedEvent(object sender, EventArgs e) 
    { 
     textBlock1.Text = "changed"; 
     Console.Out.WriteLine("text changed!"); 
    } 

andrà in un ciclo infinito di aggiornamenti.

forse avete bisogno di fare qualcosa di simile:

void my_BetterLayoutUpdatedEvent(object sender, EventArgs e) 
    { 
     if (!hasChanged) 
      textBlock1.Text = "changed"; 
     hasChanged = true; 
     Console.Out.WriteLine("text changed!"); 
    } 
+2

Punto interessante, e rende senso. Non sto più lavorando su quell'applicazione, ma suona plausibile. Speriamo che aiuti qualcun altro. –

+0

È possibile verificare quale UI si stava aggiornando causando l'invalidazione? – simo