Я пытаюсь реализовать способ анимировать (переведите, исчезните), средства управления вокруг (больше чем один одновременно возможно) изящно. Например, позволяет, говорят, что у меня были изображение в верхнем левом углу и текстовое поле в правом нижнем угле, я хотел бы смочь иметь их, гладко скользят по местам переключателя и окну. Я работал некоторое время, но не придумал ничего, что достигает этого гладко или легко.
Посмотрите проект dot-net-transitions на Google Code. Сейчас есть клон на Github здесь. Он также доступен на nuget как dot-net-transitions
. Он поддерживает различные линейные/нелинейные переходы, включая составные переходы, которые можно использовать для более сложных эффектов, таких как пульсация.
Вот рабочий пример, демонстрирующий желаемое поведение:
var pictureBox = new PictureBox
{
ImageLocation = "http://icons2.iconarchive.com/icons/klukeart/summer/128/hamburger-icon.png",
SizeMode = PictureBoxSizeMode.AutoSize
};
var textBox = new TextBox
{
Text = "Hello World",
Location = new Point(140, 140)
};
var form = new Form
{
Controls =
{
textBox,
pictureBox
}
};
form.Click += (sender, e) =>
{
// swap the Left and Top properties using a transition
var t = new Transition(new TransitionType_EaseInEaseOut(1000));
t.add(pictureBox, "Left", textBox.Left);
t.add(pictureBox, "Top", textBox.Top);
t.add(textBox, "Left", pictureBox.Left);
t.add(textBox, "Top", pictureBox.Top);
t.run();
};
form.ShowDialog();
Сохраните копию значений x и y каждого из элементов в виде числа с плавающей запятой.
Используйте таймер и после каждого тика добавляйте значение к позициям x и y верхнего левого элемента. Вычтите одно и то же значение из значений x и y нижнего правого элемента.
Убедитесь, что вы используете здесь кэшированные значения с плавающей запятой, иначе вы можете получить ошибки округления при перемещении элемента в форме.
Если вы рисуете на любой поверхности, которую используете для изображений / элементов управления, делайте это недействительным для каждой отметки.
Должно быть проще простого.
Редактировать:
Для прозрачных элементов управления ознакомьтесь с советами и приемами Боба Пауэлла:
http://www.bobpowell.net/transcontrols.htm
И вот его собственный ответ о том, как сделать полупрозрачным элементы управления:
http://www.mofeel.net/67-microsoft-public-dotnet-framework-windowsforms-controls/4860.aspx
Я рекомендую вам перейти на WPF; это значительно упростит задачу.
В WinForms совершенно невозможно затушевать элементы управления; элементы управления Windows не могут иметь непрозрачность.
Самое близкое, чего вы можете добиться, это рендеринг элемента управления и его области на форме в пару растровых изображений, затем перекрестное изменение растровых изображений в PictureBox с помощью ColorMatrix.
Для сдвига элементов управления в WinForms можно использовать таймер, чтобы постепенно изменять свойства Top
и/или Left
элементов управления и перемещать их по форме. Однако при этом вы получите раздражающее мерцание, которое (AFAIK) невозможно устранить.
Вы могли бы сделать это в WinForms, приложив большие усилия, поэтому я бы поддержал рекомендации использовать WPF (который, по сути, создан именно для таких вещей).
Основным препятствием для выполнения этого в WinForms является тот факт, что расположение элемента управления задается целым числом, что означает, что вы не можете установить свойство Left
элемента управления, например, в 45.3425
. Это в принципе делает плавную анимацию элементов управления (если вы хотите, чтобы движение меняло скорость и направление) совершенно невозможной - вы получите неизбежный рывок при движении таким образом (я пробовал, поэтому знаю).
Как предложил SLaks, единственный способ сделать это в WinForms - "сымитировать" это, делая "снимки" каждого элемента управления. В принципе, вы должны начать с невидимого Bitmap размером с вашу форму, нарисованного с BackColor формы. Затем вы создадите "снимки", вызвав DrawToBitmap() для каждого элемента управления, который вы хотите анимировать, и создадите эффект движения, рисуя снимки на холсте (System.Drawing
может рисовать изображения с координатами с плавающей точкой, избегая рывков целочисленного расположения).
Однако это слишком много чертовой работы. Просто используйте WPF. :)
Edit: Я должен упомянуть, что на самом деле легко сделать что-то подобное в WinForms, если вы не возражаете, что это выглядит ужасно, отрывисто и по-любительски. Мои комментарии выше относятся к трудностям, связанным с хорошим выполнением этого.