люди, я столкнулся с проблемой, когда собирался показать моей дочери силу анимации WPF по решению проблемы Ханоя. Коды, связанные с проблемой, приведены ниже:wpf можно ли блокировать поток ui во время анимации?
void MoveSet(Disk[] disks, int maxIndex, char from, char via, char to)
{
if (maxIndex > 0) MoveSet(disks, maxIndex - 1, from, to, via);
MoveOne(disks[maxIndex], from, to);
if (maxIndex > 0) MoveSet(disks, maxIndex - 1, via, from, to);
}
Приведенные выше коды перемещают диски рекурсивно. И я добавил анимацию в метод MoveOne следующим образом:
void MoveOne(Disk disk, char from, char to)
{
// set animation parameters
... upAnimation...
... levelShiftAnimation...
... downAnimation...
Storyboard.SetTarget(upAnimation, disk);
Storyboard.SetTarget(levelShiftAnimation, disk);
Storyboard.SetTarget(downAnimation, disk);
storyboard.Begin(disk);
}
Эти коды работают хорошо. Но все анимации работают почти одновременно. После нескольких неупорядоченных анимаций все диски изменили положение. Это выглядит не круто. Поэтому я хочу показать анимацию каждого диска по одному. Я изменил метод MoveOne и внесли такие изменения:
void MoveOne(Disk disk, char from, char to)
{
...
Storyboard.SetTarget(upAnimation, disk);
Storyboard.SetTarget(levelShiftAnimation, disk);
Storyboard.SetTarget(downAnimation, disk);
AutoResetEvent signaler=new AutoResetEvent(false);
EventHandler eh = null;
eh = (s, e) =>
{
storyboard.Completed -= eh;
signaler.Set();
};
storyboard.Completed+=eh;
storyboard.Begin(disk);
signaler.WaitOne();
}
Вышеуказанные модификации сделали всю программу застрявшей. Я думаю, причина в том, что и анимация, и метод MoveOne работают только в одном потоке пользовательского интерфейса, блокируя блоки метода MoveOne и анимацию. Поэтому я попытался создать и запустить (используя диспетчер UI для вызова) анимацию в другой вновь созданной задаче, она еще не работала. Наконец-то я определил свои настоящие требования. Я хочу запустить одну анимацию и заблокировать другие анимации, и все они работают на одном единственном потоке пользовательского интерфейса. Кажется, это противоречиво. Я не знаю, есть ли у меня неправильное понимание. И есть ли какое-либо решение по этому поводу?
Попробуйте использовать анимацию ключевого кадра и используйте неперекрывающийся KeyTime в каждом кадре. См. Эту ссылку MSDN для примеров: https://msdn.microsoft.com/en-us/library/ms742524%28v=vs.100%29.aspx – Peter