Анимация wpf - событие нажатия мыши не работает

Существует синий прямоугольник, перемещающийся с левой стороны окна вправо на разное расстояние каждый раз.

Если щелкнуть прямоугольник или анимация завершена, прямоугольник снова начнет двигаться с левой стороны.

Если щелкнуть прямоугольник, его цвет станет зеленым с продолжительностью 0,3 с.

Но событие MouseDown, по-видимому, не запускало ColorAnimation, и расстояние перемещения / длительность прямоугольника также не были правильными.

private int i;
private Storyboard hitTargetStoryboard;
private List<double> disList;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    disList = new List<double>{.......};  // init with a list of values.

    /* Create a rectangle */
    Rectangle rect = new Rectangle();
    this.RegisterName("rect", rect);
    rect.Height = this.ActualHeight;
    rect.Width = 50;
    Canvas.SetTop(rect, 0);
    Canvas.SetLeft(rect, 0);

    /* Fill rect with a solid brush */
    SolidColorBrush targetRectBrush = new SolidColorBrush(Colors.Blue);
    this.RegisterName("targetRectBrush", targetRectBrush);
    rect.Fill = targetRectBrush;

    /* Add mouse down event */
    rect.MouseDown += Rect_MouseDown;

    /* Add rect to Canvas */
    myCanvas.Children.Add(rect);

    /* Create ColorAnimation to change color smoothly */
    ColorAnimation hitCA = new ColorAnimation();
    hitCA.To = Colors.Green;
    hitCA.Duration = TimeSpan.FromSeconds(0.3);
    hitCA.Completed += HitCA_Completed;

    /* Create storyboard and add ColorAnimation to it */
    hitTargetStoryboard = new Storyboard();
    Storyboard.SetTargetName(hitCA, "targetRectBrush");
    Storyboard.SetTargetProperty(hitCA, new PropertyPath(SolidColorBrush.ColorProperty));
    hitTargetStoryboard.Children.Add(hitCA);

    i = 0;
    TargetAnimation(i);
}


/* move the rect from 0--disList[i] */
private void TargetAnimation(int i)
{
    (this.FindName("rect") as Rectangle).Fill = Brushes.Blue;
    DoubleAnimation da = new DoubleAnimation();
    da.From = 0;
    da.To = disList[i];
    da.Duration = TimeSpan.FromSeconds(5);

    Storyboard.SetTargetName(da, "rect");
    Storyboard.SetTargetProperty(da, new PropertyPath(Canvas.LeftProperty));
    Storyboard storyboard = new Storyboard();
    storyboard.Children.Add(da);
    storyboard.Completed += Storyboard_Completed;
    storyboard.Begin(this);
}

/* If rect clicked, it will change color to green */
private void Rect_MouseDown(object sender, MouseButtonEventArgs e)
{
    hitTargetStoryboard.Begin(this);
}

/* After color changed, rect starts over */
private void HitCA_Completed(object sender, EventArgs e)
{
    TargetAnimation(++i);
}

/* If rect not clicked, it will start over */
private void Storyboard_Completed(object sender, EventArgs e)
{
    TargetAnimation(++i);
}

ОБНОВИТЬ:

delete: (this.FindName ("rect") как Rectangle).ill = Brushes.Blue;

добавить: hitCA.From = Colors.Blue;

ColorAnimation работает хорошо.

Еще:

Если я удалю Storyboard_Completed или же HitCA_Completedдвижение прямоугольника идет хорошо. Хотя, если у меня есть и то и другое, движение идет не в ту сторону.

ОБНОВЛЕНИЕ 2:

редактировать: storyboard.Begin(this, true) в TargetAnimation(int i) метод.

добавлять: stroyboard.Stop(this) в HitCA_Completed метод.

без настройки isControallable быть trueраскадровка не будет управляемой.

РЕШИТЬ

1 ответ

Решение

Ваша проблема здесь:

(this.FindName("rect") as Rectangle).Fill = Brushes.Blue;

Прежде всего, было бы намного проще сделать rect поле и установите Fill собственность напрямую:

rect.Fill = Brushes.Blue;

Это не поможет вашей цветовой анимации. Вы настроили анимацию для работы с targetRectBrush - который больше не заполняет rect так как вы только что заменили его. Удаление этой строки оживляет цвет.

ОБНОВИТЬ

Вот слегка подправленная версия:

public partial class MainWindow
{
    private int i;
    private Storyboard hitTargetStoryboard;
    private List<double> disList;
    private Rectangle rect;

    public MainWindow()
    {
        InitializeComponent();
        Loaded += Window_Loaded;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        disList = new List<double> {10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };  // init with a list of values.

        /* Create a rectangle */
        rect = new Rectangle();
        this.RegisterName("rect", rect);
        rect.Height = this.ActualHeight;
        rect.Width = 50;
        Canvas.SetTop(rect, 0);
        Canvas.SetLeft(rect, 0);

        /* Fill rect with a solid brush */
        SolidColorBrush targetRectBrush = new SolidColorBrush(Colors.Blue);
        this.RegisterName("targetRectBrush", targetRectBrush);
        rect.Fill = targetRectBrush;

        /* Add mouse down event */
        rect.MouseDown += Rect_MouseDown;

        /* Add rect to Canvas */
        myCanvas.Children.Add(rect);

        /* Create ColorAnimation to change color smoothly */
        ColorAnimation hitCA = new ColorAnimation
            {
                From = Colors.Blue, // (Instead of setting Fill to Blue)
                To = Colors.Green,
                Duration = TimeSpan.FromSeconds(0.3),
                FillBehavior = FillBehavior.Stop, // Returns to Blue
            };
        hitCA.Completed += HitCA_Completed;

        /* Create storyboard and add ColorAnimation to it */
        hitTargetStoryboard = new Storyboard();
        Storyboard.SetTargetName(hitCA, "targetRectBrush");
        Storyboard.SetTargetProperty(hitCA, new PropertyPath(SolidColorBrush.ColorProperty));
        hitTargetStoryboard.Children.Add(hitCA);

        i = 0;
        TargetAnimation(i);
    }


    /* move the rect from 0--disList[i] */
    private void TargetAnimation(int i)
    {
        i = i % disList.Count; // Don't overflow

        DoubleAnimation da = new DoubleAnimation
            {
                From = 0,
                To = disList[i],
                Duration = TimeSpan.FromSeconds(5),
            };

        Storyboard.SetTargetName(da, "rect");
        Storyboard.SetTargetProperty(da, new PropertyPath(Canvas.LeftProperty));
        Storyboard storyboard = new Storyboard();
        storyboard.Children.Add(da);
        storyboard.Completed += Storyboard_Completed;
        storyboard.Begin(this);
    }

    /* If rect clicked, it will change color to green */
    private void Rect_MouseDown(object sender, MouseButtonEventArgs e)
    {
        hitTargetStoryboard.Begin(this);
    }

    /* After color changed, rect starts over */
    private void HitCA_Completed(object sender, EventArgs e)
    {
        TargetAnimation(++i);
    }

    /* If rect not clicked, it will start over */
    private void Storyboard_Completed(object sender, EventArgs e)
    {
        TargetAnimation(++i);
    }
}

Какую проблему вы видите с расстоянием / продолжительностью?

Другие вопросы по тегам