C#自定义控件简介(二)

来源:互联网 发布:淘宝外贸原单鞋店推荐 编辑:程序博客网 时间:2024/06/03 17:26

      接着上一篇文章讲,这次来说说C#自定义控件中的扩展控件(Extended Controls)的创建和使用。所谓的扩展控件就是在原有控件的基础上派生出新的控件,为了让大家更好的理解,这次就用C#中最基本的组件——Button来演示。最终的效果如下:

 

      测试Demo下载

 

好了,下面来说说创建的步骤:

一. 创建一个Windows窗口控件库项目,命名为MyButton;

二.编写控件代码,代码如下:(请自行添加System.Reflection命名空间)

namespace MyButton{    [DefaultEvent("Click"), ToolboxBitmap(typeof(MyButton),"Res.MyICO.ico")]    public partial class MyButton : Button    {        private State _buttonState = State.Normal;        //从资源文件载入图片        private Image _normalImg = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"MyButton.Res.btn_normal.png"));        private Image _highLightImg = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"MyButton.Res.btn_highlight.png"));        private Image _downImg = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"MyButton.Res.btn_down.png"));        private Image _focusedImg = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"MyButton.Res.btn_focus.png"));        private Image _disabledImg = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"MyButton.Res.btn_disabled.png"));        #region  Properties        [Category("自定义属性"),Description("控件的正常背景图片")]        public Image NormalImg        {            get            {                return _normalImg;            }            set            {                _normalImg = value;                BackgroundImage = value;            }         }        [Category("自定义属性"), Description("当鼠标进入控件的可见部分是的背景图片")]        public Image HighLightImg        {            get            {                return _highLightImg;            }            set            {                _highLightImg = value;            }        }        [Category("自定义属性"), Description("当控件被按下时的背景图片")]        public Image DownImg        {            get            {                return _downImg;            }            set            {                _downImg = value;            }        }        [Category("自定义属性"), Description("当控件拥有焦点时的背景图片")]        public Image FocusedImg        {            get            {                return _focusedImg;            }            set            {                _focusedImg = value;            }        }        [Category("自定义属性"), Description("控件禁止时的背景图片")]        public Image DisabledImg        {            get            {                return _disabledImg;            }            set            {                _disabledImg = value;            }        }        #endregion  Properties        //===============================================================================================        // Constructor        public MyButton(): base()        {            SetStyle(ControlStyles.UserPaint, true);            SetStyle(ControlStyles.AllPaintingInWmPaint, true);            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);            SetStyle(ControlStyles.ResizeRedraw, true);            SetStyle(ControlStyles.SupportsTransparentBackColor, true);        }        #region  OverrideMethods        protected override void OnMouseEnter(EventArgs e)        {            base.OnMouseEnter(e);            _buttonState = State.Highlight;        }        protected override void OnMouseLeave(EventArgs e)        {            if (_buttonState == State.Highlight && Focused)            {                _buttonState = State.Focused;            }            else if (_buttonState == State.Focused)            {                _buttonState = State.Focused;            }            else            {                _buttonState = State.Normal;            }            base.OnMouseLeave(e);        }        protected override void OnMouseDown(MouseEventArgs mevent)        {            if (mevent.Button == MouseButtons.Left && mevent.Clicks == 1)            {                _buttonState = State.Down;                base.OnMouseDown(mevent);            }        }        protected override void OnMouseUp(MouseEventArgs mevent)        {            if (mevent.Button == MouseButtons.Left && mevent.Clicks == 1)            {                if (ClientRectangle.Contains(new Point(mevent.X, mevent.Y)))                {                    _buttonState = State.Highlight;                }                else                {                    _buttonState = State.Focused;                }                base.OnMouseUp(mevent);            }        }        // The event of OnLeave and OnEnter to make object lost focus or get focus         protected override void OnLeave(EventArgs e)        {            _buttonState = State.Normal;            base.OnLeave(e);        }        protected override void OnEnter(EventArgs e)        {            _buttonState = State.Focused;            base.OnEnter(e);        }        protected override void OnPaint(PaintEventArgs pevent)        {            base.OnPaint(pevent);            base.OnPaintBackground(pevent);            Graphics g = pevent.Graphics;            if (Enabled == false)            {                _buttonState = State.Disabled;            }            switch (_buttonState)            {                case State.Highlight:                    g.DrawImage(_highLightImg, new Rectangle(0, 0, Width, Height));                    break;                case State.Down:                    g.DrawImage(_downImg, new Rectangle(0, 0, Width, Height));                    break;                case State.Focused:                    g.DrawImage(_focusedImg, new Rectangle(0, 0, Width, Height));                    break;                case State.Disabled:                    g.DrawImage(_disabledImg, new Rectangle(0, 0, Width, Height));                    break;                default:                    g.DrawImage(_normalImg, new Rectangle(0, 0, Width, Height));                    break;            }            DrawText(g);        }        protected override void Dispose(bool disposing)        {            if (_normalImg != null || _highLightImg != null || _downImg != null || _focusedImg != null || _disabledImg != null)            {                _normalImg.Dispose();                _highLightImg.Dispose();                _downImg.Dispose();                _focusedImg.Dispose();                _disabledImg.Dispose();            }            base.Dispose(disposing);        }        #endregion  OverrideMethods        #region  PrivateMethods        private void DrawText(Graphics g)        {            int x = 0;            int y = 0;            Size s = g.MeasureString(Text, Font).ToSize();            x = (Width - s.Width) / 2;            y = (Height - s.Height) / 2;            g.DrawString(Text, Font, Brushes.Black, new Point(x, y));        }        #endregion  PrivateMethods        #region Enum        internal enum State        {            Normal,  //正常            Highlight,  // 鼠标进入            Down,  //鼠标按下            Focused,  // 获得焦点            Disabled  //控件禁止        }        #endregion  Enum    }}

三.删除有VS设计器自动生成的代码文件MyButton.Designer.cs。

四.此时按F5测试项目时会发现出现异常,因为这个时候把启动项设成了控件的项目,但是启动项必须是可运行的项目(包含Form窗体的),解决方法是找一个包含Form窗体的宿主项目,可以往解决方案中添加已有的项目,再把其设置为启动项,这里我在解决方案中创建了新的Windows窗体项目Test,并设置为启动项。此时按F5即可。

方案布局如下:

 

五.此时我们的自定义控件就生成了,是个dll文件,这里建议看下我的上一篇文章C#自定义控件简介(一),因为待会可能会用能。好了我们现在用宿主项目来测试下控件是否如设计的那样,把DLL控件加载到宿主项目的工具箱中,或者直接把dll拖放到工具箱中,但是当把控件添加到宿主项目的Form1中,你会发现有错误。这又是什么情况呢???容我慢慢的向你道来。

        代码的前几行是从资源文件中导入我们需要的图片,但是在我们的解决方案中却找不到Res这个资源文件夹,所以问题就出现在这里,解决办法和简单,在解决方案中添加名为Res的文件夹,并把需要的图片文件放到文件夹中,有个最重要的步骤别忘了,就是把各个图片的属性栏的生成操作选项全部改成嵌入的资源,这样导入的图片才会被项目所使用。这一步也可以再写代码时同步完成。更改后项目布局如下:

 

        现在自定义的控件可以像一般的控件进行拖放使用了。由于本篇文章的侧重点为如何创建和使用自定义控件,所以关于代码我就简单的说下:

重写基类的方法来对控件的各个状态进行判断与赋值,并根据状态的不同绘制不同的背景图片,设置控件不同状态时图片的属性,便于用户根据自己的喜好更换背景图片,代码中用到了许多自定义控件的的特性,如下表所示:

 

DefaultEven在设计界面时双击控件时产生的默认事件ToolboxBitmap设置自定义控件在工具箱中显示的图片Category设置在属性栏中属性所处的类别,如“外观”,“设计”,“行为”等Description设置控件属性时,在属性窗口底端显示的该属性的描述DefaultValue设置控件属性的默认值

 

以上只是实现了button控件的基本属性,起个抛砖引玉的作用,更好的设计还望读者自行编写扩展,如若有不足之处,还请各位批评指正。

 

原创粉丝点击