Entwickler-Ecke

WinForms - C# Animation abwarten


Delete - Di 01.11.16 20:47
Titel: C# Animation abwarten
Hallo Forum,
ich habe eine Funktion in C# gebaut, die Usercontrols bewegt animiert. Nun dauert diese funktion 15 ms. wenn nun der code ausgeführt wird, der darunter steht, ist die animation noch nicht fertig. ich benutze das metroframework. gibt es irgwndwie eine möglichkeit zu warten, bis die animation ausgeführt wurde?


Moderiert von user profile iconChristian S.: Topic aus Basistechnologien verschoben am Do 03.11.2016 um 09:42


Palladin007 - Mi 02.11.16 01:30

Ich gehe davon aus, dass Du mit WPF arbeitest?
Dann sollte das Thema hier auch im WPF-Forum landen ;)

Eine Timeline hat ein Completed-Event.
Sowohl Storyboard als auch die Animations darin leiten von Timeline ab, sie haben also alle das Completed-Event.
Mit einem EventTrigger kannst Du auch in XAML daran horchen. In der System.Windows.Interactivity.dll gibts auch eine andere mMn. bessere Trigger-Variante, die DLL muss bloß eingebunden werden.


Delete - Mi 02.11.16 09:12

Uns. Sorry, dass habe ich leider nicht gesagt. Ich arbeite mit Windows forms. Das Problem ist, dass die Buttons in ein und derselben Funktion animiert werden über eine foreach Schleife.


Palladin007 - Mi 02.11.16 13:04

WinForms hat (soweit ich weiß) kein eigenes Animations-System.
Wenn Du da etwas animierst, dann machst Du das selber und dann liegt es auch in deiner Hand, wie Du damit umgehst.
Oder Du nutzt etwas von diesem Framework, was ich nicht kenne :D

Zitat:
wenn nun der code ausgeführt wird, der darunter steht, ist die animation noch nicht fertig


Das klingt nach asynchroner Programmierung. Nutzt Du Tasks?
Die haben eine Methode namens ContinueWith


Delete - Mi 02.11.16 16:52

Nein. Mit Tasks mache ich noch nichts. Am besten, ich sende mal einen beispielcode:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
private void AddFriends(object sender, EventArgs e)
        {
            for(int i = 0; i < 10; i++)
            {
                FreundItem freund = new MS_Network.FreundItem();
                freund.Location = new Point(0, freund.Height);
                AddintionalPadding += freund.Height + 20;
                this.panel2.Controls.Add(freund);

                MetroFramework.Animation.MoveAnimation ann = new MetroFramework.Animation.MoveAnimation();
                ann.Start(freund, new Point(40, AddintionalPadding), MetroFramework.Animation.TransitionType.EaseInCubic, 15);
            }
        }



Aber wenn die Schleife jetzt einmal durchlaufen wurde, muss gewartet werden, bis die eine animations zu ende ist


Palladin007 - Mi 02.11.16 17:56

Ich kanns nicht austesten, aber ich hab das gefunden:

https://searchcode.com/file/95132409/MetroFramework/Animation/AnimationBase.cs

Da gibt's in Zeile 34 ein AnimationCompleted-Event, das klingt nach dem, was Du haben willst.


Delete - Mi 02.11.16 20:07

Das stimmt. Das AnimationCompleted event. aber irgendwie muss ich das ja mit der funktion verbinden, sprich an.animationcompleted += new eventhandler(dieaktuellefunktion); aber das funktioniert nicht


Palladin007 - Mi 02.11.16 20:09

"funktioniert nicht" ist keine Fehlermeldung ;)


Delete - Mi 02.11.16 20:19

Naja das funktioniert schon, aber dann wird die methode immer öfter ausgeführt, als normal. :(


Ralf Jansen - Mi 02.11.16 20:24

Welche Methode? Was ist für dich normal? Was ist genau anders als normal.

Biete versuche deine Problem so zu schildern das auch jemand der nicht mit dir auf deinem Monitor schaut das verstehen kann.
Du brauchst Hilfe zu irgendeinem Framework das du irgendwo gefunden. Die Wahrscheinlichkeit das das jemand kennt und deshalb deine Fragen mal so eben aus der Lamäng beantworten könnte geht gegen null.
Also musst du das schon genau beschreiben damit wir das mit Allgemeinwissen vielleicht lösen können.


Delete - Mi 02.11.16 20:33

Sorry, Probleme zu beschreiben ist nicht meine stärke. ich versuche es mal:
es gibt eine methode "addfriends". in dieser werden durch eine schleife usercontrols erzeugt, die animiert werden sollen (durch das metroframework). wenn die animation fertig ist, stellt das framework ein event "animationcompleted" bereit. dieses event wird gefeurt, wenn die animation fertig ist. wenn man in dieser for schleife nun aber immer das completed event mit der aktuellen methode verknüft, quadriert sich die anzahl der methodenaufrufe immer (wegen dem +=). in meinem fall möchte ich aber warten, bis die animation zu ende ist und dann soll die for schleife weiter laufen.


Ralf Jansen - Mi 02.11.16 20:49

Du willst uns alle sagen das die 10 Animationen die du über die for Schleife startest parallel laufen du willst die aber nacheinander?
Oder willst du das der Code der nach den 10 Animation stattfindet erst stattfindet wenn alle 10 fertig sind die 10 dürfen aber ruhig parallel laufen?

Zeig uns den Code mit dem registrieren des Events. Dieser Pseudocode an.animationcompleted += new eventhandler(dieaktuellefunktion); macht mir Angst.


Delete - Do 03.11.16 03:51

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Do 03.11.16 15:20

Also ich habe die .MoveAnimation jetzt über den Konstruktor öffentlich initialisiert:


C#-Quelltext
1:
public MetroFramework.Animation.MoveAnimation an2 = new MetroFramework.Animation.MoveAnimation();                    


Wenn ich diese Methode nun in der Schleife ausführe, dann werden die Usercontrols zwar hinzugefügt, aber anscheinend wird die Animationsmethode nicht ausgeführt:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
foreach (string s in S)
                    {
                        FreundItem freund = new FreundItem();
                        freund.Location = new Point(0, AddintionalPadding);
                        freund.label1.Text = "uhuh";
                        freund.label2.Text ="ijojoij";
                        freund.label3.Text = "uiihuihui";
                        freund.label4.Text = "oiiohjojoijoij";
                        this.panel2.Controls.Add(freund);

                        an2.Start(freund, new Point(40, AddintionalPadding), MetroFramework.Animation.TransitionType.EaseInCubic, 15);
                        AddintionalPadding += freund.Height + 20;
                }


Delete - Do 03.11.16 16:32

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Do 03.11.16 16:43

Nein. Die UserControls werden ja dem Panel hinzugefügt, aber die werden an der Location 0x geadded. Danach müsste ja eigentlich die Animation angreifen und diese verschieben :(


Th69 - Do 03.11.16 17:01

In welcher Methode bzw. Ereignis wird denn die Animation ausgeführt? Die Form muß dabei wenigstens das Shown-Ereignis durchlaufen haben...


Delete - Do 03.11.16 17:04

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delete - Do 03.11.16 17:15

Doch doch, die Controls werden erzeigt. Sie werden auch dem Panel hinzugefügt. Für die Animation setzt ich die Location erst auf 0x, damit sie auf 40x animiert wird.
Ich habe zum Test in der foreach Schleife die Methode .MoveAnimation neu instanziert. Jetzt funktioniert es, aber alle UserControls werden gleichzeitig verschoben. Ich möchte aber, dass sie nacheinander verschoben werden


Th69 - Do 03.11.16 17:21

Dann beschreibe mal genau was du haben möchtest.
So etwa:
- zuerst alle UserControls auf dem Panel an Position 0 erzeugen
- dann der Reihe nach die UserControls bewegen
???

Für so ein Szenario würde ich jeweils im AnimationCompleted die nächste Animation starten (solange es welche gibt) - und die erste dann direkt nach der UserControl-Erzeugungsschleife. Speichere dir dazu am besten die Animationen in einer Liste.


Delete - Do 03.11.16 17:48

Zitat:
Für so ein Szenario würde ich jeweils im AnimationCompleted die nächste Animation starten (solange es welche gibt) - und die erste dann direkt nach der UserControl-Erzeugungsschleife. Speichere dir dazu am besten die Animationen in einer Liste.


Das verstehe ich nicht. Was soll mir die Liste dann bringen bzw. soll ich da dann die Events reinschreiben?


Delete - Do 03.11.16 20:59

- Nachträglich durch die Entwickler-Ecke gelöscht -


Th69 - Do 03.11.16 21:00

Aus der Liste (anhand eines Zählers) nimmst du dir dann immer die nächste Animation (Alternative: ein Stack, wo du immer den obersten benutzt und danach entfernst).

Edit:
@Frühlingsrolle: ja so ginge es auch (kommt drauf an, was man evtl. noch mit der Liste anfangen will).


Delete - Do 03.11.16 21:28

- Nachträglich durch die Entwickler-Ecke gelöscht -