- 浏览: 139050 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
老八牛:
利用迭代器让异步操作更加“人性化”-山寨版的AsyncEnumerator -
老八牛:
为什么看不到代码?
利用迭代器让异步操作更加“人性化”-山寨版的AsyncEnumerator -
xi4nyu:
如果启动Application中的settings 的debu ...
玩蛇记-使用Tornado构建高性能Web之二-autoreload -
huacnlee:
"且在python下工作多日才发现原来在.NET下的 ...
玩蛇记-使用tornado构建高性能Web应用之一 -
jasongreen:
异步数据库操作,在web上有什么作用吗?
玩蛇记-使用tornado构建高性能Web应用之一
最近有个需求是需要窗体上要有很炫的效果,比如动画划过的panel,跟随鼠标移动的动画,动画扩大缩小的panel,诸如此类,如果单独写这些效果一是要被烦死,二是窗体内的代码会一团糟,所以弄了个指挥其他控件移动变形的控件。
使用方法很简单,首先把这个控件拖到窗体
然后在需要移动其他控件的时候,比如我想在窗体上让一个按钮移动到鼠标当前点击的位置,那么只需要在窗体的mouse_click事件里这么写:
private void Form1_MouseClick(object sender, MouseEventArgs e)<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->
{
trans.MoveTo(button1.Location, e.Location, button1,10);
}
这样当你在窗体上点击鼠标左键的时候,按钮就会跟着你的鼠标跑啦。
效果如下,由于屏幕录像的原因效果很粗糙
<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的事件里操作窗体控件不用处理线程的问题。
有的时候可能需要移动和变形的是多个控件,我们将控件的移动行为抽象为一个行为的对象:
移动和变形的数据都是两个int的元组,所以用一个类Data来抽象
class Data<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->
{
public int X { get; set; }
public int Y { get; set; }
public Data(int x, int y)
{
X = x;
Y = y;
}
}
由于数据不知道是变形还是位移,所以用一个Action来把为控件赋值的操作独立出来,为了减少在Timmer的事件里的计算,加快速度,所以在移动和变形前就计算好每一个步骤的值,这些值放在Steps中,好了,接下来为Item增加计算所有步骤的方法:
public void Compute(int Step)<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->
{
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);
}
参数Steps是设定要计算多少个中间步骤,数值越大移动越慢,数值越小移动越快。
接下来在控件中增加一个list来存储需要移动的行为,并初始化
然后在Timmer的事件里驱动移动的步骤:
private void ProcessItems(object sender, EventArgs e)<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->
{
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();
}
}
移动完成的就把项目从列表里移除。如果没有项目可以移动了就关闭timmer节约资源
最后实现两个方法来启动移动和形变的过程:
public void MoveTo(Point From, Point To, Control Target, int Step)<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->
{
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();
}
}
如果你跟着本文的步骤一起做了,那么现在就可以来尝试玩一玩这个东西了。
最后强调一下,一定要把窗体和控件的双缓冲都打开,不然就是眼睛被闪了,置于如何开双缓冲就不在本文范围内了
发表评论
-
关于ORM和内存数据库的遐想
2007-01-23 13:21 535最近有消息说韩国电信 ... -
继续ORM-欧德巴赫猜想-Mapping
2007-01-23 14:34 632最近从项目组单离出来开始在公司实施过程化管理,整个QA Off ... -
剑走偏锋,小心走火入魔
2007-01-23 15:07 675这是很久前写好的文字,闲得无聊就发上来,几个月前的感想,上午一 ... -
手把手教你写ORM(三)
2007-01-24 11:50 576昨天处于晕死状态,少写了一个组件,还需要一个组件用来专门管理C ... -
手把手教你写ORM(四)
2007-01-24 13:51 599现在中午不睡一会儿就头晕。前一篇有人留言说为什么不写web.c ... -
手把手教你写ORM(五)
2007-01-24 15:29 573CMMI是魔鬼继续上面的内容,这里我们要实现一个插件的结构来动 ... -
谈谈我们的学习和我们的Blog
2007-01-24 20:07 365第一,学习编程是一个很枯燥的过程,所以我们更要讲究效率(要把有 ... -
手把手教你写代码生成器(也算ORM的续)
2007-01-25 11:45 673因为ORM还是需要配置,还是需要EntityObject,所以 ... -
粒度细到控件的权限管理系统的设计(概要篇)
2007-01-25 21:40 1027其实这个设计是已经做过了,那个时候我才进公司还在试用期,给我的 ... -
粒度细到控件的权限管理组件(构想篇)
2007-01-26 10:34 712说老实话我现在还没开 ... -
手把手教你写ORM大全篇
2007-01-26 19:36 637根据dudu boss的建议将本系列作一个归纳,下一个系列正在 ... -
架构设计的非侵入性原则
2007-01-27 00:41 658最近常常看到JAVA社区热 ... -
手把手教你可复用SSO组件的设计(原理篇)
2007-01-27 14:55 727在结构设计上复用性 ... -
对《万事欠备设计先行》的一点想法,兼谈XP和CMMI
2007-01-29 09:31 608周末陪女友,故沉默了,其实大脑并没有沉默,之前看到《万事欠备设 ... -
手把手教你可复用的SSO组件设计(设计篇)
2007-01-29 16:24 556周末陪女朋友去了,没写,告罪,上班后急忙补上。 这里说到了可复 ... -
手把手教你可复用的SSO组件设计(实现篇)
2007-01-29 22:30 574费了一夜的功夫写完这些代码,有些凌乱,望见谅。 首先是对加密解 ... -
玩具级嵌入式内存对象数据库^V^
2007-02-01 19:46 459纯粹是为了好玩:} 最近几天很忙所以写得少了,昨天在清理硬盘的 ... -
差之毫厘谬以千里-计算中的精度问题
2007-02-27 10:04 548如果你只是i++来作计数 ... -
动态语言,涅磐重生还是死路一条?
2007-03-06 10:31 542最近花时间一直在看python和ruby,为了在Web应用又看 ... -
ASP.NET's MVC is what a joke!
2007-03-08 13:43 455很早前还在毁人不倦的 ...
相关推荐
VB控件教程 VB控件大全 VB控件详解 VB控件用法 所有控件介绍
Windows中的许多窗体都能任意改变... 那么我们如何让VB控件大小随窗体的改变而改变呢?本资源包含的源程序代码将为您解答。 本资源压缩包内包含实现此功能的所有代码(不含控件),简单修改即可适应您的要求。
c#常用控件的属性方法, 1、窗体 2、Label 控件 3、TextBox 控件 4、RichTextBox控件 5、NumericUpDown 控件 6、Button 控件 7、GroupBox 控件 8、RadioButton控件 9、CheckBox 控件 10、ListBox 控件 11、...
用c#编写的示例程序,可以单击或双击后拖动控件到窗体任何位置,鼠标移动到控件边沿可以改变光标形状,按下鼠标左键后拖动可以改变控件大小,改变主窗体大小控件大小跟随改变
wpf界面上 控件拖动,以及控件之间的位置对换
ListCtrl控件和下拉框,编辑框等控件组合使用ListCtrl控件和下拉框,编辑框等控件组合使用ListCtrl控件和下拉框,编辑框等控件组合使用ListCtrl控件和下拉框,编辑框等控件组合使用ListCtrl控件和下拉框,编辑框等...
C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习C#控件学习
js日期控件js日期控件js日期控件js日期控件
js日历控件js日历控件js日历控件js日历控件js日历控件js日历控件js日历控件js日历控件js日历控件js日历控件
VB中的控件大小也能在运行时动态改变,你听说过吗?将鼠标放到VB窗体中的控件的边框上,鼠标也会变成双向指针,拖动鼠标即可改变控件大小。 那么我们如何让VB动态改变控件尺寸呢?本资源包含的源程序代码将为您...
.net 工业控件 .net 工业控件 .net 工业控件
.net 控件拖放,PictureBox控件, Treeview控件, textbox控件
而且,ASP.NET集成的日历控件用起来不是很方便,其效果并非我们所想要。所以,大部分人还是选择了JS日历控件,也有很多人从事这方面的研究。在这里将我收藏的几种JS日历控件推荐给大家,附有JS源代码,希望给你带来...
C#控件大全 C#属性大全 C#事件大全 C#控件及常用设计整 1、窗体 1 2、Label 控件 3 3、TextBox 控件 4 4、RichTextBox控件 5 5、NumericUpDown 控件 7 6、Button 控件 7 7、GroupBox 控件 7 8、RadioButton控件 8 9...
vb控件多媒体控件 vb控件多媒体控件
.net日期控件.net日期控件.net日期控件.net日期控件.net日期控件.net日期控件.net日期控件
OCR控件 OCR控件OCR控件OCR控件OCR控件OCR控件OCR控件OCR控件OCR控件OCR控件OCR控件
vc++ MFC 界面设计编程 各种控件设计,包括树控件,视图控件,静态文本,按钮控件,旋转控件,组合狂,tab控件等等,欢迎下载啊。(树控件)
C/C++ MFC CListCtrl列表控件和CTreeCtrl树控件的完美结合,对话框模式的完整程序,有VC6.0 VS2008,VS2010的工程文件