Простая анимация в WinForms
Вопрос
Представьте, что вы хотите анимировать какой-то объект в WinForm.Вы настраиваете таймер для обновления состояния или модели и переопределяете событие рисования формы.Но исходя из этого, каков наилучший способ постоянно перерисовывать Форму для анимации?
- Аннулировать форму, как только вы закончите рисовать?
- Настроить второй таймер и аннулировать форму через регулярные промежутки времени?
- Может быть, есть какая-то общая закономерность для этой штуки?
- Есть ли какие-нибудь полезные .СЕТЕВЫЕ классы, которые могли бы помочь?
Каждый раз, когда мне нужно это сделать, я обнаруживаю новый метод с новым недостатком.Каков опыт и рекомендации сообщества SO?
Решение
В некоторых ситуациях быстрее и удобнее рисовать не с помощью события рисования, а получать графический объект из элемента управления / формы и рисовать "на нем".Это может вызвать некоторые проблемы с непрозрачностью / сглаживанием / текстом и т.д., но может стоить того, чтобы не перекрашивать весь шабанг.Что-то вроде:
private void AnimationTimer_Tick(object sender, EventArgs args)
{
// First paint background, like Clear(Control.Background), or by
// painting an image you have previously buffered that was the background.
animationControl.CreateGraphics().DrawImage(0, 0, animationImages[animationTick++]));
}
Я сам использую это в некоторых элементах управления и поместил изображения в буфер, чтобы "очистить" фон, когда интересующий объект перемещается или его нужно удалить.
Другие советы
Я создал библиотеку, которая могла бы помочь в этом.Это называется Transitions, и с ним можно ознакомиться здесь: http://code.google.com/p/dot-net-transitions/
Он использует таймеры, запущенные в фоновом потоке, для анимации объектов.Библиотека с открытым исходным кодом, поэтому, если она вам пригодится, вы можете взглянуть на код, чтобы увидеть, что он делает.
То, что вы делаете, - это единственное решение, которое я когда-либо использовал в WinForms (таймер с постоянными перерисовками).Существует множество методов, которые вы можете использовать, чтобы сделать работу пользователя с ним более плавной (например, двойная буферизация).
Возможно, вы захотите попробовать WPF.В WPF есть встроенные средства для создания анимации, и они намного более плавные (и требуют меньше кода и никакой синхронизации с вашей стороны), чем решение на основе таймера.
Обратите внимание, что для этого решения вам не нужно использовать WPF во всем вашем приложении;можно упаковать эту функциональность в элемент управления WPF и встроить элемент управления в приложение WinForms (или неуправляемое приложение, если уж на то пошло).: