2009-10-16 16 views
6

Ich habe ein bisschen Animation zu meiner WPF-Anwendung hinzugefügt.WPF - LayoutUpdated Ereignis wiederholt ausgelöst

Dank Dan Crevier's unique solution to animating the children of a panel kombiniert mit der awesome WPF Penner animations stellte sich heraus, dass es ziemlich einfach war, eine meiner Steuerungen großartig aussehen zu lassen und seine Kinder mit einer netten Animation zu bewegen.

Leider kommt das alles mit einem Leistungsoverhead. Ich bin froh, dass die Leistung beim Hinzufügen/Entfernen von Elementen oder bei der Größenänderung des Steuerelements erreicht wird. Dieser Perf-Treffer scheint jedoch während der gesamten Lebensdauer der Anwendung konsistent zu sein, auch wenn die Elemente vollständig statisch sind.

Die Klasse verwendet eine angehängte Eigenschaft, um das Ereignis UIElement.LayoutUpdated zu haken. Wenn dieses Ereignis ausgelöst wird, werden Rendertransformationen animiert, damit die Kinder zu ihren neuen Positionen gleiten können.

Leider scheint das Ereignis LayoutUpdated jede Sekunde oder so ausgelöst wird, auch wenn nichts in der Anwendung passiert (zumindest glaube ich nicht, dass mein Code etwas tut - die App hat keinen Fokus und die Maus ist) steady.) Da der Event-Handler dem Event-Handler nicht sofort den Grund für das Event aufzeigt, müssen alle untergeordneten Elemente des Controls neu bewertet werden. Dieses Ereignis wird im Leerlauf einmal pro Sekunde aufgerufen. Die Häufigkeit erhöht sich, wenn Sie die App tatsächlich verwenden.

Also meine Frage ist, wie kann ich hier die Leistung verbessern? Jede Antwort, dass Assists würde geschätzt, aber ich bin zur Zeit auf diesen Unterfragen fest:

  1. Was sind die Ursachen der LayoutUpdated Ereignis so häufig zu schießen? Soll das passieren und wenn nicht, wie kann ich herausfinden, warum es feuert und es beschneidet?

  2. Gibt es einen bequemeren Weg innerhalb des Handlers, um zu wissen, ob etwas passiert ist, das Kinder bewegt haben könnte? Wenn das der Fall ist, könnte ich früh ausbrechen und den Aufwand vermeiden, jedes Kind zu schleifen.

Vorerst werde ich durch das Deaktivieren Animation, um dieses Problem zu umgehen, wenn es mehr als N Kinder in der Platte sind.

+0

Drew, könnten Sie bitte kleines Codebeispiel teilen, die das Problem reproduzieren konnten? – Anvaka

+0

Yeah, weil LayoutUpdated eigentlich nur feuern sollte, wenn etwas das Layout tatsächlich aktualisiert ... offensichtlicher, als das klingt. :) Da du nicht mit dem Window interagierst weiß ich nicht, was dies außer Animationen zu Dimensionen, Position oder Layouttransformation auslösen würde. –

+0

Hmm die App ist ziemlich groß. Wenn LayoutUpdated nicht regelmäßig zünden sollte, mit welcher Technik kann ich herausfinden, warum es ausgelöst wird? –

Antwort

7

Wenn Sie die Benutzeroberfläche von dem EventHandler aktualisieren, der an das LayoutUpdated-Ereignis angefügt wurde, löst dies auch dieses Ereignis aus!

Zum Beispiel:

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

wird eine Endlosschleife von Updates gehen.

Vielleicht brauchen Sie so etwas wie dies zu tun:

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

Interessanter Punkt, und es macht Sinn. Ich arbeite nicht mehr an dieser Anwendung, aber das klingt plausibel. Hoffentlich hilft es jemand anderem. –

+0

Kann überprüft werden, welche Benutzeroberfläche aktualisiert wurde und die Ungültigmachung verursacht hat? – simo

Verwandte Themen