版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://wynfeeisolate./logs/35782738.html
很久没有写Blog,以后这样的时候还会更多...因为要考研....
一直很喜欢.Net,虽然有些人很鄙视它,我也一直不明白为什么,实际上JDK+JVM和.NET几乎是一个样子,没有什么大的区别,不是我没有使
用过Java,用Java开发程序我也做过...虽然不多,但是至少写过一些,差别真的不大,要真有差别,就是Java封装的函数少了点,要自己多写写,
实际上要是用二者都做了程序会发现,实际上.NET中要是不知道那些封装的函数,你还是要自己写...
好了,废话不说,还是看一下我们如何写一个自定义的控件...
发个效果图...
<->
<->
<->
动态效果哦!!!
明确开发环境:Visual Studio 2008 Team Suite语言:C#
阅读要求:熟悉C# 2.0及之后的版本和Visual Studio 2005及之后的版本,了解GDI+
小提示:如果懂得Photoshop或者Fireworks作图,可以理解本程序更加快一些
由于我们自定义绘制一个Button,所以我们要对它增加一些引用库:
using System.Drawing.Drawing2D
这个是为我们绘制Button所做的铺垫,
然后我们首先新建一个项目,然后选择Windows控件库,然后创建一个新的目录,就叫VistaButton好了,名字也叫
VistaButton,和我的代码统一起来...这里需要提示的是不要把控件库的输出位置放置在带#的结尾的目录中,为什么呢?因为我在输出的时候遇到
这个问题,当我输出一个控件在路径:C:/WinterVacation
Create/C#/VistaButton时,会提示找不到该路径,而且提示出故障的路径中多了一个"C5",不知道是什么原因,是Vista的原因
么?不晓得,总之不要输出在带#的路径里面就对了。
然后我们首先在Designer中添加我们需要代码:
private void InitializeComponent()
{
this.Name = "VistaButton";//控件名
this.Size = new System.Drawing.Size(100, 32);//控件的默认大小
this.Paint += new System.Windows.Forms.PaintEventHandler(this.VistaButton_Paint);//控件的Paint事件
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyUp);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyDown);
this.MouseEnter += new System.EventHandler(this.VistaButton_MouseEnter);
this.MouseLeave += new System.EventHandler(this.VistaButton_MouseLeave);
this.MouseUp += new MouseEventHandler(VistaButton_MouseUp);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.VistaButton_MouseDown);
this.GotFocus += new EventHandler(VistaButton_MouseEnter);
this.LostFocus += new EventHandler(VistaButton_MouseLeave);
this.mFadeIn.Tick += new EventHandler(mFadeIn_Tick);
this.mFadeOut.Tick += new EventHandler(mFadeOut_Tick);
this.Resize += new EventHandler(VistaButton_Resize);
//设置一些针对这个控件的事件
}
事实上你完全可以在编辑器中完成这个工作,只需要点击鼠标就可以完成设置,但是我在做控件的时候常常喜欢直接写代码,自我感觉这样会比较保险...如果你不确定你写的函数存在,那么还是用编辑器作比较合适,比如你不确定Resize函数存不存在一样...
然后我们回到正题,开始写些代码
如果你的和我写的一模一样,或者你干脆就知道构造函数的位置,那么就可以写一下我们的设计要求,如下:
public VistaButton()
{
InitializeComponent();
#region 相关优化设置
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
//该设置忽略WM_ERASEBKGND系统消息来减少闪烁(true),WM_ERASEBKGND是操作系统指示整个窗体被擦除的时候才被调用
//那么,这段话主要就是要求在双缓存中绘制图形,然后再显示到Screen上,这个要求USERPaint是开启(true)的状态
this.SetStyle(ControlStyles.DoubleBuffer, true);
//这个就是为绘制开启双缓存,前提就是上面的设置,因为要使用双缓存必须启用WM_Paint...,则要求所有的绘制都在WM_Paint中,那么就是ALLPaintInWm_Paint
this.SetStyle(ControlStyles.ResizeRedraw, true);
//这个标签是通知系统,当控件大小发生改变的时候应该进行重绘
this.SetStyle(ControlStyles.Selectable, true);
//通知系统该控件接受焦点,即可以被选中....
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
//通知系统该控件支持透明的背景色,其启用条件是USERPaint为true,且其父控件派生自Control才可以,我们这个控件是派生自Button,所以是可以使用的
//this.SetStyle(ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
//设置本空间的的背景色为透明...
mFadeIn.Interval = 30;
mFadeOut.Interval = 30;
//这里有两个特殊的变量,这两个变量是Timer类型的,Timer类型就是按照用户定义类型来引发事件的计时器
#endregion
}
如果你是用设计器编辑的话,那么建议你创建2个Timer控件,然后把名字改成mFadeIn和mFadeOut,这样会比较直观,因为我全部是用
代码写的,所以缺失了两个控件的显示(这两个Timer)使得编辑器里无法显示这个按钮的样子...真不幸...不过好在如果你把它作为一个控件库引入到
一个Windows
Form中,就可以显示出来了...主要问题在于我们这里是绘制的,不是单纯的拖控件组合...所以...那控件编辑器制作本程序的估计也看不出什么,因
为我写的时候压根没有想到使用编辑器....
然后让我们设置两个可能出现的枚举:
enum State { None, Hover, Pressed };//设置控件的状态....主要是针对鼠标...正如英文所说的那样...没有鼠标影响、鼠标悬停,和鼠标按下三个状态,当然,也可以设置更多,完全是用户自己的事情
public enum Style//设置控件的Style属性,有flat和默认两种
{
Default,//本例中正常绘制的外观即为Default
Flat//本例中为绘制Flat效果设置的外观
};
我的程序只是个Demo,所以没有什么特别深厚的设计,很简单实现某个功能而已,如果想增加什么功能或者完善,请读者自便...
之后设置一些私有变量:
#region 一些程序需要的私有变量
private bool calledbykey = false;
private State mButtonState = State.None;
private Timer mFadeIn = new Timer();
private Timer mFadeOut = new Timer();
private int mGlowAlpha = 0;
#endregion
我想我的变量名字起的很好理解...我就不解释了...
然后设置一些我们所能操作的变量,以属性的形式给予赋值...至于Category这个标签,就是我们看到的IDE中显示为文本、布局之类的名称,
即标的我们当前设置的属性应该在那个Category中显示出来,没有特殊规定的,会从Control继承...所以,大胆的开发吧...
#region 在Text(即文本)这个分类中包含的属性和设置其初始值....
private string mText;
[Category("Text"),
Description("The text that is displayed on the button.")]
//定义属性...buttonText
public string ButtonText
{
get { return mText; }//控件所设置的文本时可以获取的....
set { mText = value; this.Invalidate(); }//一旦对ButtonText设置了新的文字,则对控件重绘...
}
//设置mForeColor属性....,默认值为白色
private Color mForeColor = Color.White;
[Category("Text"),
Browsable(true),//该属性是不是显示在IDE属性窗口中
DefaultValue(typeof(Color), "White"),
Description("The color with which the text is drawn.")]
public override Color ForeColor//改写Control的Forecolor属性为mForeColor,以此影响Forecolor的取值,一旦变化了,立即重绘控件
{
get { return mForeColor; }
set { mForeColor = value; this.Invalidate(); }
}
//设置文字的默认对齐方式
private ContentAlignment mTextAlign = ContentAlignment.MiddleCenter;
[Category("Text"),
DefaultValue(typeof(ContentAlignment), "MiddleCenter"),
Description("The alignment of the button text " +
"that is displayed on the control.")]
public ContentAlignment TextAlign
{
get { return mTextAlign; }
set { mTextAlign = value; this.Invalidate(); }
}
#endregion
#region 允许用户在控件上添加图片的Images分类
private Image mImage;
[Category("Image"),
DefaultValue(null),
Description("The image displayed on the button that " +
"is used to help the user identify" +
"it's function if the text is ambiguous.")]
//下面的Images才是真正在属性菜单上显示的数据,mImage只是为Images获取参数而设置的
public Image Image
{
get { return mImage; }
set { mImage = value; this.Invalidate(); }
}
private ContentAlignment mImageAlign = ContentAlignment.MiddleLeft;
/// <summary>
/// The alignment of the image
/// in relation to the button.
/// </summary>
[Category("Image"),
DefaultValue(typeof(ContentAlignment), "MiddleLeft"),
Description("The alignment of the image " +
"in relation to the button.")]
public ContentAlignment ImageAlign
{
get { return mImageAlign; }
set { mImageAlign = value; this.Invalidate(); }
}
private Size mImageSize = new Size(24, 24);
/// <summary>
/// The size of the image to be displayed on the
/// button. This property defaults to 24x24.
/// </summary>
[Category("Image"),
DefaultValue(typeof(Size), "24, 24"),
Description("The size of the image to be displayed on the" +
"button. This property defaults to 24x24.")]
public Size ImageSize
{
get { return mImageSize; }
set { mImageSize = value; this.Invalidate(); }
}
#endregion
#region 设置Button的外观
private Style mButtonStyle = Style.Default;
///设置当鼠标不再客户区的时候,button的背景是不是被绘制,
[Category("Appearance"),
DefaultValue(typeof(Style), "Default"),
Description("Sets whether the button background is drawn " +
"while the mouse is outside of the client area.")]
public Style ButtonStyle
{
get { return mButtonStyle; }
set { mButtonStyle = value; this.Invalidate(); }
}
private int mCornerRadius = 8;
//设置button的圆角的弧度,弧度越大,越光滑...,弧度的大小不超过Button高的一半
[Category("Appearance"),
DefaultValue(8),
Description("The radius for the button corners. The " +
"greater this value is, the more 'smooth' " +
"the corners are. This property should " +
"not be greater than half of the " +
"controls height.")]
public int CornerRadius
{
get { return mCornerRadius; }
set { mCornerRadius = value; this.Invalidate(); }
}
private Color mHighlightColor = Color.White;
//设置高光颜色....
[Category("Appearance"),
DefaultValue(typeof(Color), "White"),
Description("The colour of the highlight on the top of the button.")]
public Color HighlightColor
{
get { return mHighlightColor; }
set { mHighlightColor = value; this.Invalidate(); }
}
private Color mButtonColor = Color.Black;
///设置Button的颜色...
[Category("Appearance"),
DefaultValue(typeof(Color), "Black"),
Description("The bottom color of the button that " +
"will be drawn over the base color.")]
public Color ButtonColor
{
get { return mButtonColor; }
set { mButtonColor = value; this.Invalidate(); }
}
private Color mGlowColor = Color.FromA#8dbdff;
//当鼠标在控件客户端范围内,绘制控件的暗光...
[Category("Appearance"),
DefaultValue(typeof(Color), "141,189,255"),
Description("The colour that the button glows when " +
"the mouse is inside the client area.")]
public Color GlowColor
{
get { return mGlowColor; }
set { mGlowColor = value; this.Invalidate(); }
}
private Image mBackImage;
//Button的背景图....
[Category("Appearance"),
DefaultValue(null),
Description("The background image for the button, " +
"this image is drawn over the base " +
"color of the button.")]
public Image BackImage
{
get { return mBackImage; }
set { mBackImage = value; this.Invalidate(); }
}
private Color mBaseColor = Color.Black;
//绘制在Button上凸显明净的颜色,产生玻璃效果(绘制在没有Glow色绘制的客户端区域),如果想要产生玻璃效果,尝试设置为透明色
[Category("Appearance"),
DefaultValue(typeof(Color), "Black"),
Description("The backing color that the rest of" +
"the button is drawn. For a glassier " +
"effect set this property to Transparent.")]
public Color BaseColor
{
get { return mBaseColor; }
set { mBaseColor = value; this.Invalidate(); }
}
#endregion
//在分类上添加的内容...
#endregion