Чтобы разобраться в поведении, вам необходимо знать, как работает анимация в системе свойств WPF: анимации не работают, если для свойства заданы разные значения во времени.Они работают, предоставляя эффективное значение для свойства, которое временно имеет приоритет над «базовым» значением.Это тонкое различие, но именно это заставляет вас отклеиться.
При первом знакомстве с системой анимации большинство людей воображают, что она работает, неоднократно вызывая метод доступа set для свойства.Но это не так - если вы устанавливаете свойство таким образом, что до запуска анимации остается, исходное значение, которое вы установили, остается на месте.Просто получатель вернет значение, предоставленное системой анимации, вместо возврата «локального» значения.Фактически, вы можете даже изменить «локальное» значение, установив свойство во время работы анимации, но это локальное значение не станет видимым, пока анимация не остановится.
На самом деле, система свойств выполняет многотакого рода вещи - это не просто анимация.В этом разделе справки перечислены 11 различных мест, откуда может прийти значение свойства.Анимации являются вторым наивысшим приоритетом.Свойства, установленные обычным способом с помощью метода доступа set (или с помощью атрибутов в Xaml), являются следующим наивысшим приоритетом, но вы можете видеть, что все шаблоны, стили и триггеры предоставляют другие источники, когда нет локального значения свойства.
Система анимации в WPF имеет концепцию «базового» значения, и это, по сути, следующее по приоритету значение, доступное после текущего анимированного значения.Если у вас есть локальное значение, это будет базовое значение, но если у вас его нет, базовое значение будет получено из одного из других источников, перечисленных в этой статье.
Результат всего этогов том, что нет простого способа сделать то, что вы пытаетесь сделать.Я думаю, что вам нужно, чтобы анимация запускалась до конца и чтобы свойство сохраняло свое окончательное значение анимации до тех пор, пока вы не установите локальное значение на что-то другое.
Если вы скажете анимации остановитьсяпосле его завершения действующее значение возвращается к базовому значению.(Как вы говорите в комментарии, он уменьшается после завершения анимации.) И если вы скажете анимации удерживать после завершения (что является поведением по умолчанию), то анимация всегда будет предоставлять значение, которое имеет более высокий приоритет, чем локальные значенияВот почему вы видите, что изменение размера кнопки вручную больше не работает.Так что ни один из вариантов не делает то, что вы хотите.
Есть два способа справиться с этим.@ responsederNS5 опубликовал один - обработайте завершение анимации, измените локальное значение, чтобы отразить окончательное значение анимации, а затем остановите анимацию.(Вы можете считать это своего рода понижением свойства - оно преобразует его из высокоприоритетного, но временного значения свойства, предоставляемого анимацией, в немного более низкое приоритетное, но более постоянное локальное значение.) Я был бы склонен изменитьнемного кода:
private void myDoubleAnimation_Completed(object sender, EventArgs e)
{
// Animation complete, but holding, so Height will currently return
// return the final animated value.
double finalHeight = button.Height;
// Remove the animation.
button.BeginAnimation(Button.HeightProperty, null);
// Modify the local value to be the same as the final animated value.
button.Height = finalHeight;
}
Что я здесь изменил, так это то, что код больше не пытается угадать, где оказалась система анимации - это просто считывает любое значение, которое система анимации установила для свойства, иделает это новое локальное значение.Я предпочитаю это += 10
в обработчике Completed
, который для меня кажется слегка хрупким дублированием логики.
Другой способ справиться с этим - удалить анимацию в той точке, в которой выпопробуйте обновить свойство:
private void _resizeButton_Click(object sender, RoutedEventArgs e)
{
double currentHeight = button.Height;
button.BeginAnimation(Button.HeightProperty, null);
button.Height = currentHeight + 10;
}
private void _animateButton_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation animation = new DoubleAnimation
{
By = 10,
Duration = new Duration(TimeSpan.FromSeconds(1))
};
button.BeginAnimation(Button.HeightProperty, animation);
}
Это кажется мне несколько более надежным, потому что это будет работать, даже если анимация не была завершена к тому времени, когда вы нажмете кнопку изменения размера.