Laden...

Synchrone / Blockierende Animationen ?

Erstellt von srynoname vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.826 Views
S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 13 Jahren
Synchrone / Blockierende Animationen ?

Hallo,

ich benötige dringend synchrone / blockierende Animationen statt asynchrone Animationen, das Completed Event einer Animation reicht in meinem Fall nicht, dafür ist mein Programmablauf zu komplex. Ich habe daher folgendes versucht:

  1. Nach Aufruf von BeginAnimation für eine Animation mit einer Dauer von x Millisekunden rufe ich Thread.Sleep(x) auf. Resultat: Die Animation beginnt nachdem der Thread geschlafen hat, obwohl BeginAnimation vor Thread.Sleep aufgerufen wird!?

  2. Nutzung von Signalen, d.h. konkret der AutoResetEvent Klasse: Sende ein Signal aus dem Completed Event der Animation, im ursprünglichen Thread, der die Animation mit BeginAnimation aufruft, warte nach dem Start der Animation auf das Signal. Resultat: Ähnlich wie in 1 - es blockiert alles die Animation wird nie ausgeführt, obwohl erst nach starten der Animation auf ein Signal gewartet wird.

Ich bin langsam wirklich am verzweifeln und hoffe ihr könnt mir bei diesem Problem helfen, schonmal vielen Dank!

Ich habe ein fertiges Projekt zum Testen angehängt.
Hier noch direkt der Code:

  1. Variante mit Thread.Sleep:
        messageLogTB.Clear();

        TranslateTransform translateTransform = new TranslateTransform();
        animatedButton.RenderTransform = translateTransform;

        DoubleAnimation animation = new DoubleAnimation(0, 200.0, new Duration(TimeSpan.FromMilliseconds(2000)));
        translateTransform.BeginAnimation(TranslateTransform.XProperty, animation);

        // Animation wird asynchron gestartet und dauert 2 Sekunden, warte daher 2 Sekunden nach dem asynchronen Start
        // (funktioniert jedoch nicht, Animation wird NACH der 2 Sekunden Pause ausgeführt!)
        Thread.Sleep(2000);
        messageLogTB.Text += "animation abgeschlossen";

  1. Variante mit Signalen
            messageLogTB.Clear();

        TranslateTransform translateTransform = new TranslateTransform();
        animatedButton.RenderTransform = translateTransform;




        AutoResetEvent trigger = new AutoResetEvent(false);


        // Animation erstellen, Signal wird im Completed Event der Animation gesetzt
        DoubleAnimation animation = new DoubleAnimation(0, 200.0, new Duration(TimeSpan.FromMilliseconds(2000)));
        animation.Completed += delegate(object source, EventArgs args) 
            {
                trigger.Set();
                messageLogTB.Text += "\nsignalisiert / animation beendet";
            };



        // Animation über Dispatcher starten
        messageLogTB.Text += "starting animation";

        Dispatcher.Invoke(
        new Action(
            delegate()
            {
                translateTransform.BeginAnimation(TranslateTransform.XProperty, animation);
            }
        ), null);



        // Warten, bis die Animation ihr Ende signalisiert - leider hängt der Code schon, bevor die Animation ausgeführt wird, ähnlich wie bei der 1. Variante
        trigger.WaitOne();
        messageLogTB.Text += "\nDiese Stelle sollte nach dem Signal / Ende der Animation erreicht werden";

6.862 Beiträge seit 2003
vor 13 Jahren

Hallo,

was du willst ist nicht umsetzbar. Die Animationen verändern die GUI und wenn du den GUI Thread blockierst kann auch nichts animiert werden. Gerade deshalb bleibt nur die Möglichkeit über ein Event benachrichtigt zu werden wenn die Animation fertig ist. Wozu musst du denn wirklich den Programmfluss anhalten bis die Animation fertig ist?

Baka wa shinanakya naoranai.

Mein XING Profil.

925 Beiträge seit 2004
vor 13 Jahren

Hmmm... Geht es nur darum, dass während der Animation keine Eingaben mehr getätigt werden können?

Indem du einen VisualBrush von der GUI erzeugst und diesen als Background eines über die gesamte GUI gelegten Adorners darstellst. Dann blockiert die GUI zwar nicht, aber sie nimmt auch keine Eingaben mehr an.

Ansonsten kann ich nur sagen, dass du schon zuviel Komplexität in den GUI Thread gelegt hast, wenn dieser auch nur an einer einzigen Stelle synchron mit der Datenverarbeitung arbeiten muss.