好吧所以我正在为一些使用C#的人创建一个“Windows Forms Application”,我想让他的UI更有趣。
主表格看起来像一个大表盘,上面有自定义按钮。 (我说的是自定义按钮,因为它们实际上是我创建的简单用户控件,它有一个 PictureBox 和一个 Label ,当用户指向它时会放大,然后缩小鼠标光标移到它外面。还有一个图像属性,用于设置 PictureBox 的图像,并用作所谓的自定义按钮的图标。)
我使用了两个名为 tmrEnlarge 和 tmrShrink 的计时器,它们分别在 MouseEnter 和 MouseLeave 事件上激活。基本上只有几个简单的函数来增加和减少我的自定义控件中使用的 PictureBox 的大小,并使它看起来像放大......
它工作得很好,但问题是,当鼠标同时徘徊几个控件时,动画会减慢dows(在我看来这是正常的,因为定时器不是像我这样做的最佳方式!) 我也试过使用线程,但问题还在这里! : - (
我想知道的是,做这样的事情最好的方法是什么?
修改
这是我用于直接在控件上绘制图像而不使用 PictureBox 的代码:
(它只是一个快速版本,在绘制图像后会留下残留,这对我来说并不重要)
public partial class DDAnimatingLabel : UserControl
{
public Image Image { get; set; }
public DDAnimatingLabel()
{
InitializeComponent();
}
private void DDAnimatingLabel_MouseEnter(object sender, EventArgs e)
{
tmrEnlarge.Enabled = true;
}
protected override void OnPaint(PaintEventArgs e)
{
if (Image != null)
{
e.Graphics.DrawImage(this.Image, e.ClipRectangle);
}
else
base.OnPaint(e);
}
private void tmrEnlarge_Tick(object sender, EventArgs e)
{
if (Size.Width >= MaximumSize.Width)
{
tmrEnlarge.Enabled = false;
return;
}
Size s = Size;
s.Height += 4;
s.Width += 4;
Size = s;
Point p = Location;
p.X -= 2;
p.Y -= 2;
Location = p;
}
private void tmrShrink_Tick(object sender, EventArgs e)
{
if (tmrEnlarge.Enabled)
return;
if (Size.Width == MinimumSize.Width)
{
tmrShrink.Enabled = false;
return;
}
Size s = Size;
s.Height -= 4;
s.Width -= 4;
Size = s;
Point p = Location;
p.X += 2;
p.Y += 2;
Location = p;
}
private void DDAnimatingLabel_MouseLeave(object sender, EventArgs e)
{
tmrShrink.Enabled = true;
}
}
答案 0 :(得分:0)
我原本误解了你的问题。前段时间我为这种事情建立了一个动画系统。在这里您可以找到该代码: http://pastebin.com/k1XmRapH
这是我的动画系统的旧版本。它很粗糙,但相对较小且易于理解。下面是一个使用动画系统的演示应用程序。
该系统的关键点是:
演示应用程序使用AnimationGroup来改变Size和Location属性。当鼠标进入按钮时,我们首先取消任何现有动画,然后运行动画来增长按钮。当鼠标离开按钮时,我们再次取消任何现有动画,然后运行动画使其恢复正常。将AnimationTerminate.Cancel指定为AnimationManager.Remove会取消正在运行的动画而不调用其End方法(这将完成动画)。这使按钮的属性处于我们取消时所处的状态,并平滑地将按钮恢复为正常大小。
using System;
using System.Drawing;
using System.Windows.Forms;
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
const int PulseInterval = 20;
const int ButtonAnimateTime = 250;
AnimationManager animate;
Point[] buttonLocationsNormal, buttonLocationsHover;
Size buttonSizeNormal, buttonSizeHover;
public Form1()
{
Text = "Demo";
ClientSize = new Size(480, 100);
animate = new AnimationManager { PulseInterval = PulseInterval };
buttonLocationsNormal = new Point[4];
buttonLocationsHover = new Point[4];
buttonSizeNormal = new Size(100, 80);
buttonSizeHover = new Size(120, 100);
for (int n = 0, x = 10; n < 4; n++, x += 120)
{
Point normalLocation = new Point(x, 10);
buttonLocationsNormal[n] = normalLocation;
buttonLocationsHover[n] = new Point(x - 10, 0);
Button button = new Button { Text = "Text", Location = normalLocation, Size = buttonSizeNormal };
button.MouseEnter += (s, e) => AnimateButton(s as Button, true);
button.MouseLeave += (s, e) => AnimateButton(s as Button, false);
Controls.Add(button);
}
}
private void AnimateButton(Button button, bool hovering)
{
int index = Controls.IndexOf(button);
AnimationGroup group = button.Tag as AnimationGroup;
if (group != null)
animate.Remove(group, AnimationTerminate.Cancel);
Point newLocation;
Size newSize;
if (hovering)
{
newLocation = buttonLocationsHover[index];
newSize = buttonSizeHover;
}
else
{
newLocation = buttonLocationsNormal[index];
newSize = buttonSizeNormal;
}
group = new AnimationGroup(
new PropertyAnimation("Location", button, newLocation, TimeSpan.FromMilliseconds(ButtonAnimateTime), new PointAnimator())
, new PropertyAnimation("Size", button, newSize, TimeSpan.FromMilliseconds(ButtonAnimateTime), new SizeAnimator())
);
button.Tag = group;
animate.Add(group);
}
}