转自
http://www.cnblogs.com/stg609/archive/2008/03/29/1128411.html 这几天为了什么"评估",搞得莫名的紧张,现在评估组走了,反而开始觉得有点无聊了.
为了完善仿Windows的画板,做了一个很原始的颜色抬取控件.现在将大致的过程介绍下.大家也可以直接下载工程文件.
平台:VS 2005 WINFORM
语言:C#
最终效果图:
光看看图片似乎说明不了什么问题,还是接着往下看吧!
要想在VS 2005 winform 中编辑自定义控件,步骤如下:
1.点击文件->新建项目->选择Windows控件库
2.编辑控件
3.点击生成->生成 项目名称 ,完成这一步后会在bin或debug目录下看到"项目名称.dll"文件,这个便是你的控件库了
4.在需要使用该控件的程序中点击工具->选择工具项->浏览->选择刚才的那个.dll文件,这样你便会在你的工具箱中找到你的那个控件
今天要写的主要是第二个步骤,其它的大家自己去掌握.
新建一个项目后会得到如右图所示的界面:
首先我们对这个自定义控件取个名字:ColorHatch;
接下来我们对这个界面进行布局修改成和效果图类似的界面.
然后就开始对代码进行编辑了.
分析1:我们需要一个panel1来显示我们所选择的颜色
;同时我们希望可以在调用控件的程序中直接对其初始颜色进行设置;
那么现在我们就来实现分析1中的要求:
这里主要的问题就是如何来给我们的这个控件定义一个外部属性,以至我们可以在属性设计视图中对其进行设置.
定义属性的方法是首先声明一个private 变量 private Color hatchColor;
然后我们编写set与get方法,也就是对应的属性赋值与取值的方法
[Description("设置当前颜色")] //显示在属性设计视图中的描述
[DefaultValue(typeof(Color), "Black")]//给予初始值
public Color HatchColor
{
get
{ return hatchColor; }
set
{
hatchColor = value;
panel1.BackColor = value;
}
}
public delegate void ColorChangedEventHandler(object sender, ColorChangedEventArgs e);//事件所需的委托
//当颜色改变时触发事件
public event ColorChangedEventHandler ColorChanged;//定义一个ColorChanged事件
protected virtual void OnColorChanged(ColorChangedEventArgs e)
{//事件触发方法
if (ColorChanged != null)
{//判断事件是否为空
ColorChanged(this, e);//触发事件
}
}
ColorChanged(this,e)其实是使用委托调用一个事件处理方法,这个事件处理方法就是我们双击事件时自动生成的一个方法.就好像我们双击click时,便会自动生成一个private panel1_click(object sender,EventArgs e).
但是单单写完这些我们还无法在调用方找到这个事件,因为我们现在只是完成了一个事件,还没有和我们的控件进行关联.我们必须在控件需要调用这个事件的地方,加上事件触发方法.我们要知道使用这个事件的前提是panel1中的颜色被改变,也就是说在我们选取了新的颜色时触发此方法,如下:
private void panel_Click(object sender, EventArgs e)
{
Panel p = sender as Panel;
if (p != null)
{
hatchColor = p.BackColor;
panel1.BackColor = hatchColor;
OnColorChanged(new ColorChangedEventArgs(hatchColor));//因为颜色改变所以触发事件
}
}
加了以上这步后,我们就可以在调用这个控件的窗体的事件中找到这个自定义事件了.这样我们就可以像使用一般事件一样,双击进行事件处理方法的编写了.
这时有些朋友可能会问ColorChangedEventArgs是什么了?这个东西是不是很眼熟?是不是和EventArgs很像?我们在click事件中可以经常碰见.EventArgs是用户传入的参数,我们这个ColorChangedEventArgs就是继承自这个EventArgs的一个类,目的是用来传递我们选中的颜色给调用方.
下面我们来看一下这个ColorChangedEventArgs类
public class ColorChangedEventArgs : EventArgs
{
private Color color;
/** <summary>
/// 颜色改变事件数据
/// </summary>
/// <param name="c">改变后的颜色</param>
public ColorChangedEventArgs(Color c)
{
color = c;
}
/** <summary>
/// 获取颜色
/// </summary>
public Color GetColor
{
get
{ return color; }
}
}
为了完善仿Windows的画板,做了一个很原始的颜色抬取控件.现在将大致的过程介绍下.大家也可以直接下载工程文件.
平台:VS 2005 WINFORM
语言:C#
最终效果图:
![](https://i-blog.csdnimg.cn/blog_migrate/9c8a2c22af05d43a7db55b00f43b3cc7.jpeg)
光看看图片似乎说明不了什么问题,还是接着往下看吧!
要想在VS 2005 winform 中编辑自定义控件,步骤如下:
1.点击文件->新建项目->选择Windows控件库
2.编辑控件
3.点击生成->生成 项目名称 ,完成这一步后会在bin或debug目录下看到"项目名称.dll"文件,这个便是你的控件库了
4.在需要使用该控件的程序中点击工具->选择工具项->浏览->选择刚才的那个.dll文件,这样你便会在你的工具箱中找到你的那个控件
今天要写的主要是第二个步骤,其它的大家自己去掌握.
![](https://i-blog.csdnimg.cn/blog_migrate/d1f284629b5fb408e537d357104e3c13.gif)
新建一个项目后会得到如右图所示的界面:
![](https://i-blog.csdnimg.cn/blog_migrate/bf7fe7290aa2963a8a9c86447fdf7a20.jpeg)
首先我们对这个自定义控件取个名字:ColorHatch;
接下来我们对这个界面进行布局修改成和效果图类似的界面.
然后就开始对代码进行编辑了.
分析1:我们需要一个panel1来显示我们所选择的颜色
![](https://i-blog.csdnimg.cn/blog_migrate/aae7dc9a5ed068254211e1b7b5a28d54.jpeg)
那么现在我们就来实现分析1中的要求:
这里主要的问题就是如何来给我们的这个控件定义一个外部属性,以至我们可以在属性设计视图中对其进行设置.
定义属性的方法是首先声明一个private 变量 private Color hatchColor;
然后我们编写set与get方法,也就是对应的属性赋值与取值的方法
![](https://i-blog.csdnimg.cn/blog_migrate/d88255cde07b317242efa84ac1a0e7cb.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4a24b7d660a6ee38d2cbf3f237ba0b42.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0b58abe1fa5054480c3df6fa1759382d.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0f893af0b86d0e00622f1d98987a0c83.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/ed2aaa747428a966e8e17e275e97087c.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/ed2fb016175722a56a13370dcf48d8a8.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/936ddece4856758a615191ea2f5747a4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/47a6e8d752ffddb17e3521fa642b83ca.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b93b59ba30c03df49fd672e341214244.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/93dd1f80b155971809a8b28de5738b40.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/49bfc53aeb32d5b9cf1a838643031e81.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/714fa15853a021a67ebadd1310f745cb.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/700d616b8835779e99339b82d7fd6a6c.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/c7e9b231feaafad954f091fd51af0d8c.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6f6236d5498d69ce1dd3f4f8e8403d37.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/fa17c7961cf5a76eec4e2615aa28643b.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/960e23bd9985f9d9b933a6c3c63acc4a.gif)
这样我们的这个外部属性就做好了.这个效果只能在调用这个控件的窗体中才能查看.
分析2:当调用该控件的窗体运行时,我们希望能有一个方法将所选中的颜色传递给所调用的窗体;我们可以联想下其它控件是如何与主窗体传递信息的(不是通过属性就是事件),我们这里肯定是要在选择某种颜色后便将颜色传递给主窗体,所以我们要采用事件来进行处理.
因为控件本身并不提供此事件,所以我们自然是要自己定义一个事件.
关于"事件",详细讲起来就差不多可以专门写一片了.我们这里只是简单介绍下如何自己定义事件,大家可以去网上查查资料,记得陈广的c#语言参考视频中就有讲到.
编写事件的主要步骤如下:
1.创建一个委托(关于委托这里不做介绍)2.声明一个事件 3.定义一个触发事件的方法
现在我们就来写一下这个事件:
![](https://i-blog.csdnimg.cn/blog_migrate/72b0c94b42e96cf0036faf4b58fbdfa5.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/dc2e69b4ec7b134846180f9986741085.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0496f9cf404cc9b36bdceb693b864691.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37cef11a5cfce5d03929d73406914e49.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/5ca112092965e22458982ecf76b7ee32.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f727242870d4ff49df83c9f319630854.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a51f620f8cecab1c5f10d1578a89a27b.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4ca432488a074739cd36b75de13e7cbd.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/5096529ee7ff2ac34a81ebd265d64a16.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/49227351233151ebf67b6e3599b35269.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/9eb5a58395ce96e9781f732b39a9b895.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/07bd84aeff8ae8f7dabcdcb625be44f4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f41e903e588e246b01a73ae50c6f05ee.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0951d56d192ab4844be625e863428488.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6677f150d0ae0d7901208a000c735b32.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/55133ccdc99c18f7a46456f1553c6701.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/ca6cc992ba243971e2ec24a81866b355.gif)
ColorChanged(this,e)其实是使用委托调用一个事件处理方法,这个事件处理方法就是我们双击事件时自动生成的一个方法.就好像我们双击click时,便会自动生成一个private panel1_click(object sender,EventArgs e).
但是单单写完这些我们还无法在调用方找到这个事件,因为我们现在只是完成了一个事件,还没有和我们的控件进行关联.我们必须在控件需要调用这个事件的地方,加上事件触发方法.我们要知道使用这个事件的前提是panel1中的颜色被改变,也就是说在我们选取了新的颜色时触发此方法,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/31416af8c7771a4529d7c96cc419b051.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4c13cfe8f76313d7da922026885ca67f.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/88ef9e0ef82d89e68cbcbbed8650ae1d.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/82b22a03f7f98d15af3942ff666abe4a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/21a0816e5bef2461912266880cda3225.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/74b614edfef34a48191b8cacf2f1e8a0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/44b6ef9131420d17981e8b87bcf3aecb.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/8296953f340367b5f1d744371c2224d7.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/55ad49aa2051ebbf5ae3b6b55f7d7acc.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/56fa6e196c9cb0532b4dcf1df6c21166.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/43daf3d531a6aa090cfdd4a6d72c5807.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1d0290dd55abf8d767c2a03cae0d246d.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/113064131a70e8ad6b6ff5f8ebdb6aa9.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4b1c607f4f948b68ba65ed7d9460353e.gif)
加了以上这步后,我们就可以在调用这个控件的窗体的事件中找到这个自定义事件了.这样我们就可以像使用一般事件一样,双击进行事件处理方法的编写了.
这时有些朋友可能会问ColorChangedEventArgs是什么了?这个东西是不是很眼熟?是不是和EventArgs很像?我们在click事件中可以经常碰见.EventArgs是用户传入的参数,我们这个ColorChangedEventArgs就是继承自这个EventArgs的一个类,目的是用来传递我们选中的颜色给调用方.
下面我们来看一下这个ColorChangedEventArgs类
![](https://i-blog.csdnimg.cn/blog_migrate/156ef1533f1fd4c5463cd6036f77961d.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4610d7b3df248491b61f71e53dfa1f97.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/07203c480a0f218dd278d620141f13a5.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34c68036dd1a6708ec78c6e29545745b.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b184b1c2e5c26650672ca727f449b949.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/d4fe9aac3bb0fbb8d98c3fd5c17940d3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/859243f1a7fe1c05eec989192e0aa9fa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a2bef4ca75b952729e76a6a2574977b6.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4d801afc8fa7db6d70360e53bf7ddc66.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/551b5be374cf39b0e3ce7f12e48d48b9.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/067bfbf1fac39341f0446a5fcff335db.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/35333c48f75f0054baa17141a4b2ad04.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/621638a112a50a2b894e86a1e2e7fe7c.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/71d2bfbc44790c6f4556c09ee36b2eee.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b05f4f1171534f586c5a34e3d399892b.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/3f0423dac24f806b65d1f99b425d0a0d.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/dc4b61496ff0b23281003df1d2a3b5a8.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7877d3958943898fa6766bef4c9627b1.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/5a11cbda6c2339a259e3d76c9ab38c00.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/85a64660794afe0b46594d5f6a25858f.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/57f9f131d099b4a66945ee1e5fa409ad.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/af89155337f3e2a349309be6a1a1b50f.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/11da39a7ed0ed557ae50efa674efd824.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/02372d9a0cbc07c23e6363829ac6ac4f.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/d4e13acf7baf0e521ef0ea87886dd0b9.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/ff60824d0d4c1144cca5d30bf7af3983.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/31730534b666b4b3819ec2770385b252.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1d120cf087e451025940ee5d4ca860c5.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/e49e9be024a9cf188d8af2d4cfba91c0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/5e6572e07e8f7d066cf82f69ae521832.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b820032bfef0b295bf397990b9ffd881.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a86dd73419c96adc693a3ac46c8af274.gif)
这样一个自定义控件的主要问题就已经解决了,可能有的朋友看得比较晕,所以建议先去了解一下.NET中的事件.
最后我们来看下在调用这个控件的窗体中的效果:
附:
隐藏的办法:
屏蔽KeyPress事件使其在客户端不可见
[Browsable(false)]
public new event KeyPressEventHandler KeyPress;
需要特别注意的是,KeyPress被隐藏之后,控件本身的KeyPress事件也将不能被触发