zoukankan      html  css  js  c++  java
  • 编写C#控件的3种方式

    很多时候我们需要使用到自定义控件 而在C#中 我们主要以3中方式创建自定义控件,还有些需要注意的地方时常被忽略 比如Click事件,用户控件的Click并不像系统的Button单击
    
    1.继承自.NET类库中已有的控件 如TextBox MenuStrip Pannel
    
    2.继承自Control类
    
    3.继承自UserControl类
    
     
    
    下面是3个小示例
    
    1.继承自类库中现有的控件
    
    下面自定义一个ExtendTextBox 该控件扩展了一个属性,可以现在文本框只能输入数字,字母或者所有字符
    
     
    
    
    
     1 public class ExtendTextBox : System.Windows.Forms.TextBox
     2 {
     3     private AllowType _allowType = AllowType.All;
     4     public AllowType AllowType
     5     {
     6         get { return _allowType; }
     7         set { _allowType = value; }
     8     }
     9 
    10     protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
    11     {
    12         //设置此属性为true 基方法将不再处理此KeyPress事件
    13         e.Handled = true;
    14 
    15         if (_allowType == AllowType.Number)
    16         {
    17             //如果输入是0-9 交由基方法处理 允许输入
    18             if (e.KeyChar >= '0' && e.KeyChar <= '9')
    19                 e.Handled = false;
    20         }
    21         else if (_allowType == AllowType.Letter)
    22         {
    23             //如果输入是A-Z或a-z 交由基方法处理 允许输入
    24             if (e.KeyChar >= 'A' && e.KeyChar <= 'z')
    25                 e.Handled = false;
    26         }
    27         else if (_allowType == AllowType.All)
    28         {
    29             e.Handled = false;
    30         }
    31         base.OnKeyPress(e);
    32     }
    33 }
    34 public enum AllowType
    35 {
    36     Number,
    37     Letter,
    38     All
    39 }
    
     
    
     
    
    2.继承自UserControl类 此方法主要用于编写组合控件 UserControl容器可以提供其组成控件的所有功能。可以编写代码指定新的用户控件可公开其子控件的哪些属性
    
    UserControl支持直接将背景色设置为透明 而Control则不支持
    
     
    
    public class UserControl1 : Usercontrol
    {
    }
     
    
    3.继承自Control类 Control类提供基本控件功能,但不提供图形界面或任何特定功能 ,必须编写代码指定控件的属性 方法 事件,还必须重写OnPaint和OnPaintBackground方法以创建界面,通常需要使用到GDI+
    
    Control 类实现向用户显示信息的类所需的最基本功能。它处理用户通过键盘和指针设备所进行的输入。它还处理消息路由和安全。虽然它并不实现绘制,但是它定义控件的边界(其位置和大小)。它提供窗口句柄 (hWnd)。
    
     
    
    下面是一个椭圆按钮简单的例子 但是有几个地方是要引起注意的,关于自定义控件里由基类继承而来的Click事件,包括UserControl和Control Click事件是鼠标单击事件 鼠标左键单击和右键单击都将触发这个事件 如果没有定义双击事件 则双击控件将两次触发Click事件。这里的Click和.Net类库中的Button的Click事件是区别的 传统的Button按钮,鼠标左键单击才会响应 聚焦后按Enter键也会响应。而自定义控件里的Click事件不会响应键盘的Enter 并且鼠标左键或者右键的单击都会触发它 。所以要对其进行一些处理,例子中自定义了一个椭圆按钮 并且它不会对右键单击产生反应
    
    1 public class EllipesButton : System.Windows.Forms.Control
    字段和重写OnPaint和OnPaintBackground
    
     
    
    
    
     1 private bool _mouseEntered;
     2 protected override void OnPaint(PaintEventArgs e)
     3 {
     4     //将文本绘制到正中央
     5     SizeF stringSize = e.Graphics.MeasureString(Text, Font);
     6     float startx = (Width - stringSize.Width) / 2;
     7     float starty = (Height - stringSize.Height) / 2;
     8     e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), startx, starty);
     9     base.OnPaint(e);
    10 }
    11 protected override void OnPaintBackground(PaintEventArgs pevent)
    12 {
    13     //绘制过程为 控件整体背景色->控件有效区背景色->控件状态表示区域->控件外框
    14 
    15     //**********
    16     //控件整体背景色
    17     //**********
    18     if (this.Parent != null)
    19         pevent.Graphics.FillRectangle(new SolidBrush(Parent.BackColor), 0, 0, this.Width, this.Height);
    20     //使用高质量平滑模式消除椭圆边缘锯齿
    21     pevent.Graphics.SmoothingMode = SmoothingMode.HighQuality;
    22 
    23     //***********
    24     //控件有效区背景色
    25     //************** Control.MouseButtons静态成员
    26     if (_mouseEntered && (MouseButtons & MouseButtons.Left) == MouseButtons.Left)
    27     {
    28         Color mouseDownColor = Color.FromArgb(128, BackColor);
    29         pevent.Graphics.FillEllipse(new SolidBrush(mouseDownColor), 0, 0, Width - 1, Height - 1);
    30     }
    31     else
    32         pevent.Graphics.FillEllipse(new SolidBrush(BackColor), 0, 0, Width - 1, Height - 1);
    33 
    34     //***********
    35     //控件状态表示区域
    36     //************
    37     //左键未按下时绘制状态表示区域
    38     if ((MouseButtons & MouseButtons.Left) != MouseButtons.Left)
    39     {
    40         //鼠标进入 绘制橙色边框
    41         if (_mouseEntered)
    42         {
    43             Pen mouseEnterPen = new Pen(Color.Orange, 2);
    44             pevent.Graphics.DrawEllipse(mouseEnterPen, 1, 1, Width - 3, Height - 3);
    45             mouseEnterPen.Dispose();
    46         }
    47         //控件获得焦点 但鼠标未进入 绘制蓝色边框
    48         else if (Focused)
    49         {
    50             Pen focusedPen = new Pen(Color.PowderBlue, 2);
    51             pevent.Graphics.DrawEllipse(focusedPen, 1, 1, Width - 3, Height - 3);
    52             focusedPen.Dispose();
    53         }
    54     }
    55     //如果有焦点,绘制焦点框
    56     if (Focused)
    57     {
    58         Pen focusedDotPen = new Pen(Color.Black);
    59         focusedDotPen.DashStyle = DashStyle.Dot;
    60         pevent.Graphics.DrawEllipse(focusedDotPen, 3, 3, Width - 7, Height - 7);
    61         focusedDotPen.Dispose();
    62     }
    63 
    64     //*********
    65     //控件外框
    66     //**********
    67     pevent.Graphics.DrawEllipse(Pens.Black, 0, 0, Width - 1, Height - 1);
    68 
    69     //base.OnPaintBackground(pevent);
    70 }
    
     
    
    非关键代码
    
     
    
    
    
     1 protected override void OnMouseEnter(EventArgs e)
     2 {
     3     _mouseEntered = true;
     4     this.Refresh();
     5     base.OnMouseEnter(e);
     6 }
     7 protected override void OnMouseLeave(EventArgs e)
     8 {
     9     _mouseEntered = false;
    10     this.Refresh();
    11     base.OnMouseLeave(e);
    12 }
    13 protected override void OnGotFocus(EventArgs e)
    14 {
    15     this.Refresh();
    16     base.OnGotFocus(e);
    17 }
    18 protected override void OnLostFocus(EventArgs e)
    19 {
    20     this.Refresh();
    21     base.OnLostFocus(e);
    22 }
    
     
    
     
    
    需要注意的地方
    
    
    
     1 //这里需要判断是左键还是右键按下
     2 protected override void OnMouseDown(MouseEventArgs e)
     3 {
     4     if (e.Button == MouseButtons.Left)
     5     {
     6         this.Focus();
     7         this.Refresh();
     8     }
     9     base.OnMouseDown(e);
    10 }
    11 protected override void OnMouseUp(MouseEventArgs e)
    12 {
    13     if (e.Button == MouseButtons.Left)
    14         this.Refresh();
    15     base.OnMouseUp(e);
    16 }
    17 //这里将消息对象强制转换为鼠标消息 判断是哪个键单击 只有当左键单击的时候才
    18 //执行,Click事件的委托是由OnClick来调用的 所以通过判断消息决定是否触发Click
    19 protected override void OnClick(EventArgs e)
    20 {
    21     MouseEventArgs m = (MouseEventArgs)e;
    22     if (m.Button == MouseButtons.Left)
    23         base.OnClick(e);
    24 }

    1.首先在usercontrol后台添加如下代码:

     public partial class UXUserControl: UserControl

    {

           //添加事件代理
           public event EventHandler UXEvent;

           //在需要响应的事件中添加

            private void btn_MouseClick(object sender, MouseEventArgs e)
            {
                if (UXEvent!= null)
                {
                    UXEvent(this, e);
                    //Or use :
                    //UXEvent(this, new EventArgs());
                }

            }

    }

    2.在窗体或页面添加一个用户控件,在Page_Load或Form_Load事件中添加:

     private void Form1_Load(object sender, EventArgs e)
     {
          (UXUserControl)UC.UXEvent+= new EventHandler(uxEvent);
     }

            private void uxEvent(object sender, EventArgs e)
            {
                //do something(including send message to other user controls)
            }

    java新手自学群 626070845
    java/springboot/hadoop/JVM 群 4915800
    Hadoop/mongodb(搭建/开发/运维)Q群481975850
    GOLang Q1群:6848027
    GOLang Q2群:450509103
    GOLang Q3群:436173132
    GOLang Q4群:141984758
    GOLang Q5群:215535604
    C/C++/QT群 1414577
    单片机嵌入式/电子电路入门群群 306312845
    MUD/LIB/交流群 391486684
    Electron/koa/Nodejs/express 214737701
    大前端群vue/js/ts 165150391
    操作系统研发群:15375777
    汇编/辅助/破解新手群:755783453
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    iOS开发--UIPickerView(选择器控件) 省份和城市的做法
    UITableView左滑设置更多的按钮
    UITableView的增,删,改例子
    UITableView的简单用法
    Block传值原理
    UIToolbar的简单用法
    用UIScrollView,UIPageControl来实现滚动视图。
    用UIPickerView来显示省和市
    如何设计好的UI控件
    UITextfield属性用法
  • 原文地址:https://www.cnblogs.com/cfas/p/3111740.html
Copyright © 2011-2022 走看看