Domanda

Ho insegnato io stesso WPF attraverso Sells / Griffiths' 'Programmazione WPF', e ho trovato una grande risorsa, ma sto cercando di prendere alcuni dei concetti che mi hanno introdotto da e andare un ulteriore passo avanti, e sto correndo in un intoppo concettuale su come mettere insieme i pezzi per realizzare quello che sto cercando di fare.

In questo esercizio, sto cercando di creare animazioni auto-terminazione; FrameworkElements che vengono creati da eventi, eseguire un'animazione, e quindi eliminare se stessi. Sto avendo dei problemi a capire come chiamare di nuovo alla FrameworkElement genitore dall'evento animation.Completed.

Ho fatto questa domanda originariamente solo utilizzando DoubleAnimations che erano incontrollato e non fa parte del Storyboard. Da allora ho aggiunto il Storyboard, e fatto le risorse Storyboard e rettangolo modo che possano essere riutilizzati facilmente.

Ecco quello che ho finora:
XAML:

<Window.Resources>
    <Storyboard x:Key="GrowSquare" x:Shared="False">
        <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" By="-50" Duration="0:0:2"/>
        <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" By="-50" Duration="0:0:2"/>
        <DoubleAnimation Storyboard.TargetProperty="(Ellipse.Width)" By="100" Duration="0:0:2"/>
        <DoubleAnimation Storyboard.TargetProperty="(Ellipse.Height)" By="100" Duration="0:0:2"/>
    </Storyboard>
    <Rectangle x:Key="MyRect" x:Shared="False" Width="20" Height="20">
    </Rectangle>
</Window.Resources>
<Canvas x:Name="myCanvas" MouseMove="myCanvas_MouseMove" Background="White"/>

.cs:

public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            lastFire = DateTime.Now;
        }

        DateTime lastFire;

        private void myCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            DateTime nowTime = DateTime.Now;
            TimeSpan T = nowTime.Subtract(lastFire);

            if (T.TotalMilliseconds > 200)
            {
                lastFire = nowTime;
                Random Rand = new Random();

                Rectangle myRect = (Rectangle)FindResource("MyRect");
                myRect.Fill = new SolidColorBrush(Color.FromRgb((byte)Rand.Next(256), (byte)Rand.Next(256), (byte)Rand.Next(256)));
                Point myLoc = e.GetPosition(myCanvas);
                Canvas.SetLeft(myRect, myLoc.X - 10);
                Canvas.SetTop(myRect, myLoc.Y - 10);
                myCanvas.Children.Add(myRect);

                Storyboard SB = (Storyboard)FindResource("GrowSquare");
                SB.Completed += new EventHandler(SB_Completed);
                SB.Begin(myRect);
            }

        }

        void SB_Completed(object sender, EventArgs e)
        {
            myCanvas.Children.RemoveAt(0);
        }
    }

Questo funziona, ma non nel modo in cui mi piacerebbe. Poiché la tela è vuota, e tutte le animazioni sono della stessa lunghezza, quando un'animazione termina, sarà sempre quello che è stato chiamato il primo figlio della tela.

Tuttavia, mi piacerebbe implementare animaitons che prendono un periodo di tempo casuale, il che significa che le animazioni non sempre iniziare e terminare nello stesso ordine. In qualche modo, in caso SB_Completed, mi piacerebbe accedere al controllo che era stato chiamato, ma io non riesco a trovare il percorso ancora.

C'è un modo per ottenere dal Media.Animation.ClockGroup che chiama l'evento SB_Completed al controllo che l'animazione viene chiamato?

È stato utile?

Soluzione

cambiare la linea in cui si assegna il gestore di eventi a questo:

SB.Completed += (s,e) => myCanvas.Children.Remove(myRect);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top