我正在尝试实现一种方法来优雅地动画(翻译,淡化)控件(可能同时超过一个)。例如,假设我在左上角有一张图片,在右下角有一个文本框,我希望它们能够平滑地滑过窗口并切换位置。我已经工作了一段时间,但还没有想出任何可以顺利或轻松地实现这一目标的方法。
5 回答
查看 Google Code 上的dot-net-transitions项目。现在这里有一个 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();
我建议您切换到 WPF;这会让事情变得容易得多。
在 WinForms 中淡化控件是完全不可能的;Windows 控件不能具有不透明度。
您可以获得的最接近的方法是将窗体上的控件及其区域呈现为一对位图,然后使用 ColorMatrix 在 PictureBox 中交叉淡入淡出位图。
要在 WinForms 中滑动控件,您可以使用 Timer 逐渐更改控件的Top
和/或Left
属性并在表单中移动它们。然而,你会得到一个恼人的闪烁,这是 (AFAIK) 无法移除的。
你可以在 WinForms 中做这件事,付出很大的努力,所以我不得不支持使用 WPF 的建议(它本质上就是为这种事情而构建的)。
在 WinForms 中执行此操作的主要障碍是控件位置由整数指定,这意味着您不能将控件的Left
属性设置为45.3425
,例如。这基本上使控件的平滑动画(假设您想要改变速度和方向的运动)完全不可能 - 您将通过这种方式获得不可避免的运动抖动(我已经尝试过,所以我知道)。
正如 SLaks 建议的那样,在 WinForms 中执行此操作的唯一方法是通过拍摄每个控件的“快照”来“伪造”它。基本上,您将从一个不可见的位图开始,该位图与您的表单大小一样,使用表单的 BackColor 绘制。然后,您将通过在要设置动画的每个控件上调用 DrawToBitmap() 来创建“快照”,并通过将快照绘制到画布上来创建移动效果(System.Drawing
可以使用浮点坐标绘制图像,避免整数位置的抖动) .
不过,这该死的工作太多了。只需使用 WPF。:)
编辑: 我应该提到,在 WinForms 中做这样的事情实际上很容易,只要你不介意它看起来很糟糕、生涩和业余。我上面的评论提到了做好这件事的困难。
将每个项目的 x 和 y 值的副本保存为浮点数。
使用计时器,并在每个刻度上为左上角项目的 x 和 y 位置添加一个值。从右下角项目的 x 和 y 中减去相同的值。
确保在此处使用缓存的浮点值,否则在表单上重新定位项目时可能会出现舍入错误。
如果您在用于图像/控件的任何表面上绘画,请在每个刻度上使其无效。
应该很容易。
编辑:
对于透明控制,请查看 Bob Powell 的提示和技巧:
https://web.archive.org/web/20141227200000/http://bobpowell.net/transcontrols.aspx
这是他自己对如何制作半透明控件的回复:
http://www.mofeel.net/67-microsoft-public-dotnet-framework-windowsforms-controls/4860.aspx
我相信这个使用内置 AnimateWindow 的答案对于这个目的要好得多: 如何在 C# 中向我的控件添加移动效果?