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

转自:http://bbs.csdn.net/topics/90150862


最近用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
是不是看到效果了,如果是的话,不错,大功告成,如果不是的话,重头现来吧.

这里只是说了自定义控件的最一般方法,其它的大家发辉吧.比如这里只有属性和事件,没有方法,大家可以加上.


还忘了一步,在控件生成时对变量赋初值:
        public ButtonCtl()
        {
            InitializeComponent();
            mBackColor = base.BackColor;
            mForeColor = base.ForeColor;
            mFont = base.Font;
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值