Pergunta

Eu tenho me ensinando WPF através Sells / Griffiths' 'Programação WPF', e eu achei um grande recurso, mas eu estou tentando tirar alguns dos conceitos que eles me apresentaram e ir um passo a mais, e eu estou correndo em um obstáculo conceitual sobre como colocar os pedaços juntos para realizar o que eu estou tentando fazer.

Neste exercício, eu estou tentando criar animações auto-encerramento; FrameworkElements que são criados por eventos, execute uma animação, e depois excluir-se. Estou tendo problemas para descobrir como chamar de volta para o FrameworkElement pai a partir do evento animation.Completed.

Eu fiz esta pergunta originalmente apenas usando DoubleAnimations que estavam incontido e não parte do Storyboard. Tenho visto que acrescentou o Storyboard, e fez os recursos Storyboard e do retângulo para que possam ser reutilizados facilmente.

Aqui está o que eu tenho até agora:
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);
        }
    }

Isso funciona, mas não da maneira que eu gostaria. Desde a tela está vazia, e todas as animações são do mesmo comprimento, quando uma animação acabamentos, será sempre aquele que foi chamado para o primeiro filho da tela.

No entanto, eu gostaria de implementar animaitons que levam um período de tempo aleatório, o que significa que as animações nem sempre começar e terminar na mesma ordem. De alguma forma, no caso SB_Completed, eu gostaria de acessar o controle que estava sendo chamado, mas eu não consigo encontrar o caminho para isso ainda.

Existe uma maneira de obter a partir do Media.Animation.ClockGroup que chama o evento SB_Completed ao controle que a animação está sendo chamado de?

Foi útil?

Solução

mudar a linha onde você atribuir o manipulador de eventos para o seguinte:

SB.Completed += (s,e) => myCanvas.Children.Remove(myRect);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top