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控件的基本属性,起个抛砖引玉的作用,更好的设计还望读者自行编写扩展,如若有不足之处,还请各位批评指正。
- C#自定义控件简介(二)
- C#自定义控件简介(一)
- C# 自定义控件(二) 新闻控件的优化
- mojoportal自定义控件简介
- 自定义控件简介
- C#学习总结之二——自定义控件
- C#窗体控件简介
- c# 控件,自定义控件问题
- C# 自定义用户控件
- C#自定义评分控件
- C#自定义控件
- C#自定义控件
- C# 自定义控件入门
- C# 自定义控件入门
- C# 自定义控件
- c#自定义分页控件
- C#自定义可视化控件
- C# 自定义用户控件
- Adler-32校验码算法简介
- Android ADT-20.0.0插件无法安装的解决办法
- 一个无限的比特流每次只能读一个比特 判断当前的数是不是被3整除
- xCode4里面设置NSZombieEnabled
- 调试由URL scheme启动的进程
- C#自定义控件简介(二)
- STL学习笔记
- CodeDom使用笔记(三)
- ubuntu sudo权限错误的解决方法
- thinkphp多图片上传(插入数据库,并且不出现覆盖现象)
- html5游戏开发-愤怒的小鸟-开源讲座(二)-跟随小鸟的镜头
- java swing图像放大、缩小、剪切
- 经典SQL语句大全之(数据开发,管理常识)
- 这些年,我收集的JavaScript代码(一)