У меня есть панель в моей форме C #, и у меня есть кнопка. Когда я нажимаю кнопку, отображается невидимая панель. Вместо этого я хочу, чтобы панель двигалась внутрь или выдвигалась. Например, когда вы нажимаете на поле со списком, раскрывающийся список не появляется просто так. Я хочу, чтобы моя панель выглядела вот так. Как я могу это сделать ?
Как добавить движущиеся эффекты к элементам управления на C #?
Ответы (4)
Оконная анимация - это встроенная функция Windows. Вот класс, который его использует:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public static class Util {
public enum Effect { Roll, Slide, Center, Blend }
public static void Animate(Control ctl, Effect effect, int msec, int angle) {
int flags = effmap[(int)effect];
if (ctl.Visible) { flags |= 0x10000; angle += 180; }
else {
if (ctl.TopLevelControl == ctl) flags |= 0x20000;
else if (effect == Effect.Blend) throw new ArgumentException();
}
flags |= dirmap[(angle % 360) / 45];
bool ok = AnimateWindow(ctl.Handle, msec, flags);
if (!ok) throw new Exception("Animation failed");
ctl.Visible = !ctl.Visible;
}
private static int[] dirmap = { 1, 5, 4, 6, 2, 10, 8, 9 };
private static int[] effmap = { 0, 0x40000, 0x10, 0x80000 };
[DllImport("user32.dll")]
private static extern bool AnimateWindow(IntPtr handle, int msec, int flags);
}
Пример использования:
private void button2_Click(object sender, EventArgs e) {
Util.Animate(button1, Util.Effect.Slide, 150, 180);
}
Animation failed
исключение, что может быть не так?
- person Vahid Nateghi; 11.11.2013
animation failed
исключение при попытке применить стиль смешанной анимации. Не уверен, что это за анимация
- person swdev; 24.03.2014
Если вы используете .NET 4 (если не замените Task на Thread), функция, подобная этой, может быть началом:
private void slideToDestination(Control destination, Control control, int delay, Action onFinish)
{
new Task(() =>
{
int directionX = destination.Left > control.Left ? 1 : -1;
int directionY = destination.Bottom > control.Top ? 1 : -1;
while (control.Left != destination.Left || control.Top != destination.Bottom)
{
try
{
if (control.Left != destination.Left)
{
this.Invoke((Action)delegate()
{
control.Left += directionX;
});
}
if (control.Top != destination.Bottom)
{
this.Invoke((Action)delegate()
{
control.Top += directionY;
});
}
Thread.Sleep(delay);
}
catch
{
// form could be disposed
break;
}
}
if (onFinish != null) onFinish();
}).Start();
}
Использование:
slideToDestination(sender as Control, panel1, 10, () => MessageBox.Show("Done!"));
slideToDestination(sender as Control, panel1, 0, null);
В качестве действия вы должны отправить некоторую логическую переменную, для которой установлено значение true, чтобы вы знали, что анимация завершена, или какой-то код, который нужно запустить после нее. Остерегайтесь тупиковых ситуаций при вызове с нулевым действием. Вы можете запустить две анимации на одном элементе управления в двух разных направлениях с одинаковой скоростью, и он останется там, где был навсегда, и, конечно же, две анимации одновременно могут заставить элемент управления двигаться бесконечно в каком-то направлении, потому что while никогда не закончится :)
Посмотрите библиотеку, которую я написал в прошлом году:
Библиотека анимации WinForm [.Net3.5 +]
Простая библиотека для анимации элементов управления / значений в .Net WinForm (.Net 3.5 и новее). Ключевой кадр (путь) на основе и полностью настраиваемый.
https://falahati.github.io/WinFormAnimation/
new Animator2D(
new Path2D(new Float2D(-100, -100), c_control.Location.ToFloat2D(), 500))
.Play(c_control, Animator2D.KnownProperties.Location);
Это перемещает элемент управления c_control
с -100, -100 на первое место за 500 мс.
Для WinForms вы можете начать с того, что расположение панели отключено.
Используйте таймер и в событии Tick медленно перемещайте расположение панели в поле зрения, пока она не окажется в ваших предопределенных координатах.
Есть много способов снять шкуру с кошки, но я бы сделал это так.