C#自定义控件一步一步走

cyliao 2006-07-20 03:35:03
最近用C#做mobile,但发现在windows mobile中可用的控件太少,只好自己定义了,下面以自定义一个button为例来说说C#中自定义控件如何做.
(先说明一下,我用的是.net2005)
一.新建一个控件库项目.
二.想好要定义控件的需求:能设定字体,设定背景色和前景色,字符对齐方式,有一个click事件,就这么简单.
三.定义一个枚举类型,来设定对齐方式:
public enum ButtonTextAlignment
{
Left=0,
Middle,
Right
}
四.定义一些内部变量:
private Color mBackColor = Color.White; //背景色
private Color mForeColor = Color.Black; //前景色
private string mText = "Button"; //文字

private EventHandler mOnClicked; //事件触发器

private ButtonTextAlignment mTextAlignment = ButtonTextAlignment.Middle;//对齐方式

private Font mFont = null; //字体
五.定义属性:
//字体
public override Font Font
{
get
{
return base.Font;
}
set
{
mFont = value;
base.Font = mFont;
Invalidate();
}
}

//对齐方式属性
public ButtonTextAlignment TextAlignment
{
get
{
return mTextAlignment;
}
set
{
mTextAlignment = value;
Invalidate();
}
}

//前景色
public override Color ForeColor
{
get
{
return mForeColor;
}
set
{
mForeColor = value;
base.ForeColor = mForeColor ;
Invalidate();
}
}

//背景色属性
public override Color BackColor
{
get
{
return mBackColor;
}
set
{
mBackColor = value;
base.BackColor = mBackColor;
Invalidate();
}
}

public string ButtonText
{
get
{
return mText;
}
set
{
mText = value;
Invalidate();
}
}
要注意的是,这里前景色,背景色和字体是重载了基类的属性.(本来字符我也想重载基类的Text,但重载后发现这个属性没有出来,不知为什么,哪位大侠知道告诉我).
六.画控件
应该说上面几步都是最简单的操作,这步才是关键,在做这步之前,你要想好你的控件最后是一个什么样子的.
//重画控件
private void DrawCtl(PaintEventArgs e)
{
float xPox = 3;
float yPox;

SolidBrush brush = new SolidBrush(mForeColor);
Pen pen = new Pen(Color.Black);
Rectangle rect = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);

//写文本
SizeF textSize = e.Graphics.MeasureString(mText, mFont);
switch (mTextAlignment)
{
case ButtonTextAlignment.Left:
xPox = 3;
break;
case ButtonTextAlignment.Middle:
xPox = (ClientRectangle.Width - textSize.Width) / 2;
break;
case ButtonTextAlignment.Right:
xPox = ClientRectangle.Width - textSize.Width - 3;
break;
}
yPox = (ClientRectangle.Height - textSize.Height) / 2;

e.Graphics.DrawString(mText, mFont, brush, xPox, yPox);
brush.Dispose();

//画边框
e.Graphics.DrawRectangle(pen,rect);

if (mouseUp)
{
pen = new Pen(Color.White, 1);
}
else
{
pen = new Pen(Color.Gray, 1);
}
e.Graphics.DrawLine(pen,1,1,ClientRectangle.Width-2,1);
e.Graphics.DrawLine(pen,1,1,1,ClientRectangle.Height-2);
pen.Dispose();
if (mouseUp)
{
pen = new Pen(Color.Gray, 1);
}
else
{
pen = new Pen(Color.White, 1);
}
e.Graphics.DrawLine(pen, 1,ClientRectangle.Height-2, ClientRectangle.Width - 2, ClientRectangle.Height - 2);
e.Graphics.DrawLine(pen, ClientRectangle.Width - 2,1, ClientRectangle.Width - 2, ClientRectangle.Height - 2);
pen.Dispose();
}
因为这个button要在mouseup和mousedown显示不同的样式,所以上面的函数中有if(mouseUp)的判断,同时还要对mouseup和mousedown事件进行重载.
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);

mouseUp = true;
Invalidate();

if (mOnClicked != null)
{
mOnClicked.Invoke(this, EventArgs.Empty);
}
}

protected override void OnClick(EventArgs e)
{
base.OnClick(e);

if (mOnClicked != null)
{
mOnClicked.Invoke(this, EventArgs.Empty);
}
}
最后还要重载控件重画事件.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

DrawCtl(e);
}
七.处理click事件
public event EventHandler ClickEventHandler
{
add
{
mOnClicked += value;
}
remove
{
mOnClicked = value;
}
}

重载控件的click事件
protected override void OnClick(EventArgs e)
{
base.OnClick(e);

if (mOnClicked != null)
{
mOnClicked.Invoke(this, EventArgs.Empty);
}
}
八.测试控件
OK,到这里为止控件已经做好,测试一下吧.
加入一个项目,在新加入的项目中加入一个窗体,把刚刚做好的控件编译一下,会在工具箱中发现你刚做好的控件,把它拖到窗体上,可以看到效果了.
在窗体的load事件中加入:
button.ClickEventHandler += new EventHandler(ButtonClick);
再写一个你要处理的click事件函数
private void ButtonClick(object sender,EventArgs e){
MessageBox.show("test my control");
}
九.OK
是不是看到效果了,如果是的话,不错,大功告成,如果不是的话,重头现来吧.

这里只是说了自定义控件的最一般方法,其它的大家发辉吧.比如这里只有属性和事件,没有方法,大家可以加上.
...全文
7992 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
scutLiu 2010-06-08
  • 打赏
  • 举报
回复
mark,学习了
最近正好要做个项目自己做一些控件
刚好可以用来借鉴参考
谢谢啦
l_hb00 2007-03-09
  • 打赏
  • 举报
回复
楼主真牛人也~~~~~~~~~~~
bomb_boy 2006-09-08
  • 打赏
  • 举报
回复
gdi++ 图片合成
cyliao 2006-08-24
  • 打赏
  • 举报
回复
可能是mouseUp没有定义,定义一下就行了
  • 打赏
  • 举报
回复
我按照你说的作了 

控件编译时提示

if (mouseUp) //错误 2 当前上下文中不存在名称“mouseUp”

{
pen = new Pen(Color.White, 1);
}
else
{
pen = new Pen(Color.Gray, 1);
}
e.Graphics.DrawLine(pen,1,1,ClientRectangle.Width-2,1);
e.Graphics.DrawLine(pen,1,1,1,ClientRectangle.Height-2);
pen.Dispose();
if (mouseUp)
{
pen = new Pen(Color.Gray, 1);
}
else
{
pen = new Pen(Color.White, 1);
}
请问是什么问题?
njqibin 2006-07-20
  • 打赏
  • 举报
回复
哇,学到了。

晚上回家练习。
cyliao 2006-07-20
  • 打赏
  • 举报
回复
还忘了一步,在控件生成时对变量赋初值:
public ButtonCtl()
{
InitializeComponent();
mBackColor = base.BackColor;
mForeColor = base.ForeColor;
mFont = base.Font;
}

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧