`

让你的控件舞动起来

阅读更多

最近有个需求是需要窗体上要有很炫的效果,比如动画划过的panel,跟随鼠标移动的动画,动画扩大缩小的panel,诸如此类,如果单独写这些效果一是要被烦死,二是窗体内的代码会一团糟,所以弄了个指挥其他控件移动变形的控件。

使用方法很简单,首先把这个控件拖到窗体

image

然后在需要移动其他控件的时候,比如我想在窗体上让一个按钮移动到鼠标当前点击的位置,那么只需要在窗体的mouse_click事件里这么写:

 private void Form1_MouseClick(object sender, MouseEventArgs e)
{
trans.MoveTo(button1.Location, e.Location, button1,
10);
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

这样当你在窗体上点击鼠标左键的时候,按钮就会跟着你的鼠标跑啦。

效果如下,由于屏幕录像的原因效果很粗糙

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://active.macromedia.com/flash5/cabs/swflash.cab#version=7,0,0,0" width="797" height="773"> <param name="movie" value="http://files.cnblogs.com/Alexander-Lee/movingmouse.xml"> <param name="play" value="true"> <param name="loop" value="false"> <param name="wmode" value="transparent"> <param name="quality" value="low"> <embed src="http://files.cnblogs.com/Alexander-Lee/movingmouse.xml" quality="low" loop="false" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" width="797" height="773"></embed></object> <script src="http://files.cnblogs.com/Alexander-Lee/movingmouse.js"></script>

 

 

当然不止能让控件移动,改变大小的动画也行,这些动画都是缓动的,也就是开始很快,然后慢慢变慢直到停止。接下来我们来看看是如何实现这些效果的。首先动画的原理大家都知道是视觉暂留原理,由于GDI+的绘图很繁重,暂时无法实现24帧每秒的完美动画,所以我们暂定为20帧每秒。而驱动动画的肯定是Timmer控件了,所以这里Timmer的间隔时间为50ms。

所以第一步我们是新建一个自动控件。并拖入一个Timmer控件,注意,是winform的Timmer,只有这个Timmer的事件里操作窗体控件不用处理线程的问题。

image image

有的时候可能需要移动和变形的是多个控件,我们将控件的移动行为抽象为一个行为的对象:

image

移动和变形的数据都是两个int的元组,所以用一个类Data来抽象

 

 class Data
{
public int X { get; set; }
public int Y { get; set; }
public Data(int x, int y)
{
X
= x;
Y
= y;
}
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

由于数据不知道是变形还是位移,所以用一个Action来把为控件赋值的操作独立出来,为了减少在Timmer的事件里的计算,加快速度,所以在移动和变形前就计算好每一个步骤的值,这些值放在Steps中,好了,接下来为Item增加计算所有步骤的方法:

 

 public void Compute(int Step)
{
int XDirection = To.X.CompareTo(From.X);
int YDirection = To.Y.CompareTo(From.Y);
Steps.Add(From);
int x = From.X;
int y = From.Y;
double itemX = ((double)Math.Abs(From.X - To.X)) / StepToItem(Step);
double itemY = ((double)Math.Abs(From.Y - To.Y)) / StepToItem(Step);
for (int i = Step; i > 0; i--)
{
double offsetX = (i * 2 - 1) * itemX;
double offsetY = (i * 2 - 1) * itemY;
if (XDirection > 0)
{
x
= (int)(x + offsetX);
}
if (XDirection < 0)
{
x
= (int)(x - offsetX);
}
if (YDirection > 0)
{
y
= (int)(y + offsetY);
}
if (YDirection < 0)
{
y
= (int)(y - offsetY);
}
Steps.Add(
new Data(x, y));
}
Steps.Add(To);
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

参数Steps是设定要计算多少个中间步骤,数值越大移动越慢,数值越小移动越快。

接下来在控件中增加一个list来存储需要移动的行为,并初始化

image

然后在Timmer的事件里驱动移动的步骤:

 

 private void ProcessItems(object sender, EventArgs e)
{
List
<Item> removelist = new List<Item>();
foreach (Item item in Items)
{
item.MoveStep
++;
if (item.MoveStep < item.Steps.Count)
{
item.CurrentStep
= item.Steps[item.MoveStep];
item.Moving();
}
else { removelist.Add(item); } } if (removelist.Count > 0)
{
foreach (Item item in removelist)
{
Items.Remove(item);
}
}
if (Items.Count < 1 )
{
ProcessTimer.Stop();
}
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

移动完成的就把项目从列表里移除。如果没有项目可以移动了就关闭timmer节约资源

 

最后实现两个方法来启动移动和形变的过程:

 

 public void MoveTo(Point From, Point To, Control Target, int Step)
{
Item item
= new Item()
{
CurrentStep
= new Data(From.X,From.Y),
From
= new Data(From.X,From.Y),
To
= new Data(To.X,To.Y),
MoveStep
= 0,
Steps
= new List<Data>(),
Target
= Target
};
item.SetValue
= (d, c) => { c.Location = new Point(d.X, d.Y);
};
item.Compute(Step);
Items.Add(item);
if (!ProcessTimer.Enabled)
{
ProcessTimer.Start();
}
}

public void ScaleTo(Size From,Size To,Control Target,int Step)
{
Item item
= new Item()
{
CurrentStep
= new Data(From.Width, From.Height),
From
= new Data(From.Width, From.Height),
To
= new Data(To.Width, To.Height),
MoveStep
= 0,
Steps
= new List<Data>(),
Target
= Target
};
item.SetValue
= (d, c) => { c.Size = new Size(d.X, d.Y);
};
item.Compute(Step);
Items.Add(item);
if (!ProcessTimer.Enabled)
{
ProcessTimer.Start();
}
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

如果你跟着本文的步骤一起做了,那么现在就可以来尝试玩一玩这个东西了。

最后强调一下,一定要把窗体和控件的双缓冲都打开,不然就是眼睛被闪了,置于如何开双缓冲就不在本文范围内了

分享到:
评论

相关推荐

    Duilib动画控件深度解析:让界面元素舞动起来

    Duilib使用XML来定制窗口,实现UI与逻辑的分离,减少在代码中创建UI控件的需求。 Duilib的主要特点包括: - 界面与业务逻辑分离,使用XML配置界面。 - 灵活的界面布局方式,内置常用的控件,同时支持自定义控件。 -...

    C#自定义控件库

    4. **数据绑定**:在.NET中,数据绑定是将控件与数据源连接起来的技术。自定义控件可以支持数据绑定,使得控件的值能直接反映数据源的变更,这在MVVM(Model-View-ViewModel)架构中尤为重要。 5. **控件状态管理**...

    c# 动态改变控件位置、控件大小、拖动控件

    如果你希望用户能够通过拖动控件的边框来改变大小,可以修改控件的样式,使其具有可调整大小的边框,然后监听`MouseDown`和`MouseMove`事件。在`MouseMove`事件中,根据鼠标与边框的关系来判断是否改变控件大小。这...

    VB控件教程 VB控件大全 VB控件详解 VB控件用法 所有控件介绍

    VB(Visual Basic)是Microsoft开发的一种面向对象的编程语言,尤其在Windows应用程序开发中广泛应用。VB控件是VB环境中用于构建...通过深入学习VB控件教程、控件大全以及相关资源,你可以进一步提升自己的编程技能。

    WPF查找一个控件下的子控件

    除了VisualTreeHelper,还可以利用DependencyObject类的FindName()方法,如果你知道子控件的名称,可以快速找到它: ```csharp FrameworkElement child = parentControl.FindName("childName") as FrameworkElement...

    wpf控件拖动,控件换位置

    在Windows Presentation Foundation (WPF) 中,开发人员可以创建丰富的用户界面,包括让控件具有拖放功能,允许用户自由调整控件的位置。本篇将深入探讨如何实现控件的拖动以及控件之间位置的交换,同时也会涉及到在...

    c#工业控件集合

    在IT行业中,尤其是在工业自动化和监控系统开发领域,自定义控件扮演着至关重要的角色。本文将深入探讨“C#工业控件集合”,一个专为工业应用设计的自定义控件库,它包含了丰富的可视化元素,如图表、温度计和仪表盘...

    让VB控件大小随窗体的改变而改变

    Windows中的许多窗体都能任意改变... 那么我们如何让VB控件大小随窗体的改变而改变呢?本资源包含的源程序代码将为您解答。 本资源压缩包内包含实现此功能的所有代码(不含控件),简单修改即可适应您的要求。

    很强大的C#控件类库,各种高能控件,绝不后悔

    在IT领域,C#是一种广泛使用的编程语言...通过深入研究和应用这些控件,你可以打造出功能强大且视觉上引人入胜的应用程序,让用户体验达到新的高度。所以,如果你是C#开发者,这个资源绝对值得你投入时间和精力去探索。

    图形控件(含示波器控件,VC)

    4. **数据传输**:为了将你的应用程序中的数据传递给示波器控件,你需要编写代码来读取和解析数据,然后调用示波器控件的接口方法来绘制波形。这可能涉及到实时数据流的处理,需要考虑性能优化。 5. **事件处理**:...

    DTPicker控件

    首先,你需要将控件添加到你的表单(Form)上。在VB的工具箱(Toolbox)中,你可以找到DTPicker控件,如果没有,可以通过右键点击工具箱并选择"选择项"(Components),然后在弹出的对话框中找到"Microsoft Date and...

    Qt控件集合下载

    **Qt控件集合详解** Qt是一款跨平台的C++图形用户界面应用程序开发框架,它提供了丰富的控件和API,使得开发者能够创建出美观且功能强大的应用程序。本集合中包含了一系列Qt编写的控件,既有开源作品也有原创设计,...

    Excel VBA日期控件使用说明

    9. 自定义样式:如果你希望日期控件看起来更符合你的界面设计,可以通过修改控件的属性来调整其外观,如边框颜色、字体样式等。 总之,Excel VBA中的日期控件是提升用户体验和程序功能的有效手段。熟练掌握其使用,...

    WinForm 实现半透明控件

    总结起来,实现WinForm中的半透明控件涉及到对控件属性的理解、图形绘制技术的运用以及可能的像素级操作。通过对`TransparencyKey`、`BackColor`、`Pen.Color`以及`Bitmap.LockBits`等方法的合理使用,我们可以创建...

    C#控件大全(C#所有的控件)

    C#控件大全 C#控件大全是指C#语言中提供的所有控件的集合,包括窗体、按钮、文本框、列表框、组合框、checkbox、RadioButton、 label、ProgressBar、TextBox、RichTextBox、DataGridView、ListView、TreeView等。...

    树形控件和列表控件的结合

    这个项目的实践价值在于,它提供了一个实际的示例,让开发者学习如何在MFC中结合使用树形控件和列表控件,这对于构建具有复杂数据展示需求的应用程序非常有用。同时,它也展示了如何跨版本地管理代码,这对于维护和...

    wps中excel日期控件下载

    首先,要启用WPS Excel的日期控件,你需要访问WPS Office的官方网站或者通过WPS软件内置的更新和插件中心来查找相关的日期控件插件。比如压缩包中的“samradapps_datepicker_221114.xlam”文件很可能就是这样一个...

    qt工业级控件

    QT工业级控件是开发高质量GUI(图形用户界面)应用程序的重要工具,尤其在工业领域,其强大而丰富的控件库能够满足各种复杂的功能需求。QT框架最初由 Trolltech 公司开发,现在由 The Qt Company 维护,并且是开源的...

    C# Winform遍历控件(窗体、Panel的子控件)Controls

    ### C# Winform遍历控件(窗体、Panel的子控件)Controls #### 一、概述 在Windows Forms (Winform) 开发中,窗体(Form)扮演着...这不仅能够帮助我们更好地管理和操作控件,还能让我们的应用程序更加灵活和强大。

    labview图标控件

    它可能包括各种按钮、指示器和其他UI元素,具有现代感和一致的视觉效果,使你的LabVIEW应用看起来更加专业。 2. **System Button - Transperant Red Theme (Medium) (1.0.0.1.vip)** 这是一个透明红色主题的系统...

Global site tag (gtag.js) - Google Analytics