Простая анимация в WinForms
Представьте, что вы хотите анимировать какой-то объект в WinForm. Вы устанавливаете таймер для обновления состояния или модели и переопределяете событие рисования формы. Но, исходя из этого, как лучше всего постоянно перерисовывать форму для анимации?
- Сделать форму недействительной, как только вы закончите рисовать?
- Установить второй таймер и регулярно аннулировать форму?
- Может, у этой штуки есть общая закономерность?
- Есть ли какие-нибудь полезные классы .NET, которые могут помочь?
Каждый раз, когда мне это нужно, я обнаруживаю новый метод с новым недостатком. Каков опыт и рекомендации сообщества SO?
Ответов (3)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 (или неуправляемое приложение, если на то пошло):