Простая анимация в WinForms

Представьте, что вы хотите анимировать какой-то объект в WinForm. Вы устанавливаете таймер для обновления состояния или модели и переопределяете событие рисования формы. Но, исходя из этого, как лучше всего постоянно перерисовывать форму для анимации?

  • Сделать форму недействительной, как только вы закончите рисовать?
  • Установить второй таймер и регулярно аннулировать форму?
  • Может, у этой штуки есть общая закономерность?
  • Есть ли какие-нибудь полезные классы .NET, которые могут помочь?

Каждый раз, когда мне это нужно, я обнаруживаю новый метод с новым недостатком. Каков опыт и рекомендации сообщества SO?

Ответов (3)

Решение

В некоторых ситуациях быстрее и удобнее рисовать не с помощью события рисования, а получать объект Graphics из элемента управления / формы и рисовать «на нем». Это может вызвать некоторые проблемы с непрозрачностью / сглаживанием / текстом и т. Д., Но может стоить проблем с точки зрения отсутствия необходимости перекрашивать весь шабанг. Что-то вроде:

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++])); 
}

Я сам использую это в некоторых элементах управления и использую буферизованные изображения для «очистки» фона, когда интересующий объект перемещается или его нужно удалить.

Я создал библиотеку, которая может в этом помочь. Он называется переходами, и его можно найти здесь: https://github.com/UweKeim/dot-net-transitions . Доступен на nuget как пакет dot-net-transitions

Он использует таймеры, работающие в фоновом потоке, для анимации объектов. Библиотека с открытым исходным кодом, поэтому, если она вам пригодится, вы можете посмотреть на код, чтобы увидеть, что он делает.

То, что вы делаете, - единственное решение, которое я когда-либо использовал в WinForms (таймер с постоянной перерисовкой). Существует множество методов, которые можно использовать для более плавного взаимодействия с пользователем (например, двойная буферизация).

Возможно, вы захотите попробовать WPF. В WPF есть встроенные средства для создания анимации, и они намного более плавные (и требуют меньше кода и никакой синхронизации с вашей стороны), чем решение на основе таймера.

Обратите внимание, что вам не нужно использовать WPF во всем приложении для этого решения; можно упаковать эту функциональность в элемент управления WPF и встроить элемент управления в приложение WinForms (или неуправляемое приложение, если на то пошло):

http://www.codeproject.com/KB/WPF/WPF_UserControls.aspx