Простая анимация в WinForms
Представьте, что вы хотите анимировать какой-либо объект в WinForm. Вы настраиваете таймер для обновления состояния или модели и переопределяете событие рисования формы. Но оттуда, какой лучший способ постоянно перерисовывать форму для анимации?
- Недействительность формы, как только вы закончите рисование?
- Установить второй таймер и аннулировать форму на регулярном интервале?
- Возможно, существует общий шаблон для этой вещи?
- Есть ли полезные классы .NET, чтобы помочь?
Каждый раз, когда мне нужно это делать, я обнаруживаю новый метод с новым недостатком. Каковы опыт и рекомендации сообщества SO?
Ответы
Ответ 1
В некоторых ситуациях быстрее и удобнее не рисовать, используя событие paint, но получая объект Graphics из элемента управления/формы и рисуя "on". Это может привести к некоторым неприятностям с непрозрачностью/сглаживанием/текстом и т.д., Но может стоить проблем с точки зрения необходимости перекрашивать весь шабанг. Что-то вроде:
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++]));
}
Я использую это в некоторых элементах управления самостоятельно и буферизованные изображения "очищают" фон, когда объект интереса перемещается или должен быть удален.
Ответ 2
Я создал библиотеку, которая может помочь с этим. Он называется Transitions и может быть найден здесь: http://code.google.com/p/dot-net-transitions/
Он использует таймеры, работающие на фоновом потоке для анимации объектов. Библиотека является открытым исходным кодом, поэтому, если она вам пригодится, вы можете посмотреть код, чтобы увидеть, что он делает.
Ответ 3
Что вы делаете, это единственное решение, которое я когда-либо использовал в WinForms (таймер с постоянными перерисовками). Существует множество методов, которые вы можете использовать, чтобы сделать пользователя более гладким (например, двойной буферизацией).
Возможно, вы захотите попробовать WPF. Есть встроенные средства для анимации в WPF, и они намного более плавные (и требуют меньше кода и никакой синхронизации с вашей стороны), чем решение на основе таймера.
Обратите внимание, что вам не нужно использовать WPF для всего вашего приложения для этого решения; можно упаковать эту функциональность в элемент управления WPF и внедрить элемент управления в приложение WinForms (или неуправляемое приложение, если на то пошло):
http://www.codeproject.com/KB/WPF/WPF_UserControls.aspx