前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
如果觉得写的还行,请点个 star 支持一下吧
准备工作
终于到文本框了,文本框将包含原文本框扩展,透明文本框,数字输入文本框,带边框文本框
本文将讲解数字输入文本框,可以通过加减按钮来改变数字
用到了无焦点窗体和键盘,如果你还没有了解,请前往查看
开始
添加用户控件,命名UCNumTextBox
有这些属性
1 [Description("弹出输入键盘时发生"), Category("自定义")] 2 public event EventHandler ShowKeyBorderEvent; 3 [Description("关闭输入键盘时发生"), Category("自定义")] 4 public event EventHandler HideKeyBorderEvent; 5 [Description("数字改变时发生"), Category("自定义")] 6 public event EventHandler NumChanged; 7 /// <summary> 8 /// 输入类型 9 /// </summary> 10 [Description("输入类型"), Category("自定义")] 11 public TextInputType InputType 12 { 13 get 14 { 15 return txtNum.InputType; 16 } 17 set 18 { 19 if (value == TextInputType.NotControl) 20 { 21 return; 22 } 23 txtNum.InputType = value; 24 } 25 } 26 27 [Description("数字是否可手动编辑"), Category("自定义")] 28 public bool IsNumCanInput 29 { 30 get 31 { 32 return txtNum.Enabled; 33 } 34 set 35 { 36 txtNum.Enabled = value; 37 } 38 } 39 /// <summary> 40 /// 当InputType为数字类型时,能输入的最大值 41 /// </summary> 42 [Description("当InputType为数字类型时,能输入的最大值。")] 43 public decimal MaxValue 44 { 45 get 46 { 47 return this.txtNum.MaxValue; 48 } 49 set 50 { 51 this.txtNum.MaxValue = value; 52 } 53 } 54 /// <summary> 55 /// 当InputType为数字类型时,能输入的最小值 56 /// </summary> 57 [Description("当InputType为数字类型时,能输入的最小值。")] 58 public decimal MinValue 59 { 60 get 61 { 62 return this.txtNum.MinValue; 63 } 64 set 65 { 66 this.txtNum.MinValue = value; 67 } 68 } 69 private KeyBoardType keyBoardType = KeyBoardType.UCKeyBorderNum; 70 [Description("键盘样式"), Category("自定义")] 71 public KeyBoardType KeyBoardType 72 { 73 get { return keyBoardType; } 74 set { keyBoardType = value; } 75 } 76 77 [Description("数值"), Category("自定义")] 78 public decimal Num 79 { 80 get { return txtNum.Text.ToDecimal(); } 81 set { txtNum.Text = value.ToString(); } 82 } 83 [Description("字体"), Category("自定义")] 84 public new Font Font 85 { 86 get 87 { 88 return txtNum.Font; 89 } 90 set 91 { 92 txtNum.Font = value; 93 } 94 } 95 96 [Description("增加按钮点击事件"), Category("自定义")] 97 public event EventHandler AddClick; 98 [Description("减少按钮点击事件"), Category("自定义")] 99 public event EventHandler MinusClick;
一些事件
1 void txtNum_TextChanged(object sender, EventArgs e) 2 { 3 if (NumChanged != null) 4 { 5 NumChanged(txtNum.Text.ToString(), e); 6 } 7 } 8 Forms.FrmAnchor m_frmAnchor; 9 private void txtNum_MouseDown(object sender, MouseEventArgs e) 10 { 11 if (IsNumCanInput) 12 { 13 if (KeyBoardType != HZH_Controls.Controls.KeyBoardType.Null) 14 { 15 switch (keyBoardType) 16 { 17 case KeyBoardType.UCKeyBorderAll_EN: 18 19 UCKeyBorderAll keyAll = new UCKeyBorderAll(); 20 keyAll.RetractClike += (a, b) => { m_frmAnchor.Hide(); }; 21 keyAll.EnterClick += (a, b) => { m_frmAnchor.Hide(); }; 22 m_frmAnchor = new Forms.FrmAnchor(this, keyAll); 23 m_frmAnchor.VisibleChanged += m_frmAnchor_VisibleChanged; 24 25 m_frmAnchor.Show(this.FindForm()); 26 break; 27 case KeyBoardType.UCKeyBorderNum: 28 29 UCKeyBorderNum keyNum = new UCKeyBorderNum(); 30 keyNum.EnterClick += (a, b) => { m_frmAnchor.Hide(); }; 31 m_frmAnchor = new Forms.FrmAnchor(this, keyNum); 32 m_frmAnchor.VisibleChanged += m_frmAnchor_VisibleChanged; 33 m_frmAnchor.Show(this.FindForm()); 34 break; 35 } 36 } 37 } 38 } 39 40 void m_frmAnchor_VisibleChanged(object sender, EventArgs e) 41 { 42 if (m_frmAnchor.Visible) 43 { 44 if (ShowKeyBorderEvent != null) 45 { 46 ShowKeyBorderEvent(this, null); 47 } 48 } 49 else 50 { 51 if (HideKeyBorderEvent != null) 52 { 53 HideKeyBorderEvent(this, null); 54 } 55 } 56 } 57 58 public void NumAddClick() 59 { 60 btnAdd_MouseDown(null, null); 61 } 62 63 public void NumMinusClick() 64 { 65 btnMinus_MouseDown(null, null); 66 } 67 68 private void btnAdd_MouseDown(object sender, MouseEventArgs e) 69 { 70 if (AddClick != null) 71 { 72 AddClick(this, e); 73 } 74 decimal dec = this.txtNum.Text.ToDecimal(); 75 dec++; 76 txtNum.Text = dec.ToString(); 77 78 } 79 80 private void btnMinus_MouseDown(object sender, MouseEventArgs e) 81 { 82 if (MinusClick != null) 83 { 84 MinusClick(this, e); 85 } 86 decimal dec = this.txtNum.Text.ToDecimal(); 87 dec--; 88 txtNum.Text = dec.ToString(); 89 } 90 91 private void UCNumTextBox_Load(object sender, EventArgs e) 92 { 93 this.txtNum.BackColor = this.BackColor; 94 } 95 96 private void txtNum_FontChanged(object sender, EventArgs e) 97 { 98 txtNum.Location = new Point(txtNum.Location.X, (this.Height - txtNum.Height) / 2); 99 } 100 101 private void UCNumTextBox_BackColorChanged(object sender, EventArgs e) 102 { 103 Color c = this.BackColor; 104 Control control = this; 105 while (c == Color.Transparent) 106 { 107 control = control.Parent; 108 if (control == null) 109 break; 110 c = control.BackColor; 111 } 112 if (c == Color.Transparent) 113 return; 114 txtNum.BackColor = c; 115 }
完整代码
1 // 版权所有 黄正辉 交流群:568015492 QQ:623128629 2 // 文件名称:UCNumTextBox.cs 3 // 创建日期:2019-08-15 16:03:54 4 // 功能描述:TextBox 5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 6 using System; 7 using System.Collections.Generic; 8 using System.ComponentModel; 9 using System.Drawing; 10 using System.Data; 11 using System.Linq; 12 using System.Text; 13 using System.Windows.Forms; 14 15 namespace HZH_Controls.Controls 16 { 17 [DefaultEvent("NumChanged")] 18 public partial class UCNumTextBox : UserControl 19 { 20 [Description("弹出输入键盘时发生"), Category("自定义")] 21 public event EventHandler ShowKeyBorderEvent; 22 [Description("关闭输入键盘时发生"), Category("自定义")] 23 public event EventHandler HideKeyBorderEvent; 24 [Description("数字改变时发生"), Category("自定义")] 25 public event EventHandler NumChanged; 26 /// <summary> 27 /// 输入类型 28 /// </summary> 29 [Description("输入类型"), Category("自定义")] 30 public TextInputType InputType 31 { 32 get 33 { 34 return txtNum.InputType; 35 } 36 set 37 { 38 if (value == TextInputType.NotControl) 39 { 40 return; 41 } 42 txtNum.InputType = value; 43 } 44 } 45 46 [Description("数字是否可手动编辑"), Category("自定义")] 47 public bool IsNumCanInput 48 { 49 get 50 { 51 return txtNum.Enabled; 52 } 53 set 54 { 55 txtNum.Enabled = value; 56 } 57 } 58 /// <summary> 59 /// 当InputType为数字类型时,能输入的最大值 60 /// </summary> 61 [Description("当InputType为数字类型时,能输入的最大值。")] 62 public decimal MaxValue 63 { 64 get 65 { 66 return this.txtNum.MaxValue; 67 } 68 set 69 { 70 this.txtNum.MaxValue = value; 71 } 72 } 73 /// <summary> 74 /// 当InputType为数字类型时,能输入的最小值 75 /// </summary> 76 [Description("当InputType为数字类型时,能输入的最小值。")] 77 public decimal MinValue 78 { 79 get 80 { 81 return this.txtNum.MinValue; 82 } 83 set 84 { 85 this.txtNum.MinValue = value; 86 } 87 } 88 private KeyBoardType keyBoardType = KeyBoardType.UCKeyBorderNum; 89 [Description("键盘样式"), Category("自定义")] 90 public KeyBoardType KeyBoardType 91 { 92 get { return keyBoardType; } 93 set { keyBoardType = value; } 94 } 95 96 [Description("数值"), Category("自定义")] 97 public decimal Num 98 { 99 get { return txtNum.Text.ToDecimal(); } 100 set { txtNum.Text = value.ToString(); } 101 } 102 [Description("字体"), Category("自定义")] 103 public new Font Font 104 { 105 get 106 { 107 return txtNum.Font; 108 } 109 set 110 { 111 txtNum.Font = value; 112 } 113 } 114 115 [Description("增加按钮点击事件"), Category("自定义")] 116 public event EventHandler AddClick; 117 [Description("减少按钮点击事件"), Category("自定义")] 118 public event EventHandler MinusClick; 119 public UCNumTextBox() 120 { 121 InitializeComponent(); 122 txtNum.TextChanged += txtNum_TextChanged; 123 } 124 125 void txtNum_TextChanged(object sender, EventArgs e) 126 { 127 if (NumChanged != null) 128 { 129 NumChanged(txtNum.Text.ToString(), e); 130 } 131 } 132 Forms.FrmAnchor m_frmAnchor; 133 private void txtNum_MouseDown(object sender, MouseEventArgs e) 134 { 135 if (IsNumCanInput) 136 { 137 if (KeyBoardType != HZH_Controls.Controls.KeyBoardType.Null) 138 { 139 switch (keyBoardType) 140 { 141 case KeyBoardType.UCKeyBorderAll_EN: 142 143 UCKeyBorderAll keyAll = new UCKeyBorderAll(); 144 keyAll.RetractClike += (a, b) => { m_frmAnchor.Hide(); }; 145 keyAll.EnterClick += (a, b) => { m_frmAnchor.Hide(); }; 146 m_frmAnchor = new Forms.FrmAnchor(this, keyAll); 147 m_frmAnchor.VisibleChanged += m_frmAnchor_VisibleChanged; 148 149 m_frmAnchor.Show(this.FindForm()); 150 break; 151 case KeyBoardType.UCKeyBorderNum: 152 153 UCKeyBorderNum keyNum = new UCKeyBorderNum(); 154 keyNum.EnterClick += (a, b) => { m_frmAnchor.Hide(); }; 155 m_frmAnchor = new Forms.FrmAnchor(this, keyNum); 156 m_frmAnchor.VisibleChanged += m_frmAnchor_VisibleChanged; 157 m_frmAnchor.Show(this.FindForm()); 158 break; 159 } 160 } 161 } 162 } 163 164 void m_frmAnchor_VisibleChanged(object sender, EventArgs e) 165 { 166 if (m_frmAnchor.Visible) 167 { 168 if (ShowKeyBorderEvent != null) 169 { 170 ShowKeyBorderEvent(this, null); 171 } 172 } 173 else 174 { 175 if (HideKeyBorderEvent != null) 176 { 177 HideKeyBorderEvent(this, null); 178 } 179 } 180 } 181 182 public void NumAddClick() 183 { 184 btnAdd_MouseDown(null, null); 185 } 186 187 public void NumMinusClick() 188 { 189 btnMinus_MouseDown(null, null); 190 } 191 192 private void btnAdd_MouseDown(object sender, MouseEventArgs e) 193 { 194 if (AddClick != null) 195 { 196 AddClick(this, e); 197 } 198 decimal dec = this.txtNum.Text.ToDecimal(); 199 dec++; 200 txtNum.Text = dec.ToString(); 201 202 } 203 204 private void btnMinus_MouseDown(object sender, MouseEventArgs e) 205 { 206 if (MinusClick != null) 207 { 208 MinusClick(this, e); 209 } 210 decimal dec = this.txtNum.Text.ToDecimal(); 211 dec--; 212 txtNum.Text = dec.ToString(); 213 } 214 215 private void UCNumTextBox_Load(object sender, EventArgs e) 216 { 217 this.txtNum.BackColor = this.BackColor; 218 } 219 220 private void txtNum_FontChanged(object sender, EventArgs e) 221 { 222 txtNum.Location = new Point(txtNum.Location.X, (this.Height - txtNum.Height) / 2); 223 } 224 225 private void UCNumTextBox_BackColorChanged(object sender, EventArgs e) 226 { 227 Color c = this.BackColor; 228 Control control = this; 229 while (c == Color.Transparent) 230 { 231 control = control.Parent; 232 if (control == null) 233 break; 234 c = control.BackColor; 235 } 236 if (c == Color.Transparent) 237 return; 238 txtNum.BackColor = c; 239 } 240 } 241 }
1 namespace HZH_Controls.Controls 2 { 3 partial class UCNumTextBox 4 { 5 /// <summary> 6 /// 必需的设计器变量。 7 /// </summary> 8 private System.ComponentModel.IContainer components = null; 9 10 /// <summary> 11 /// 清理所有正在使用的资源。 12 /// </summary> 13 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> 14 protected override void Dispose(bool disposing) 15 { 16 if (disposing && (components != null)) 17 { 18 components.Dispose(); 19 } 20 base.Dispose(disposing); 21 } 22 23 #region 组件设计器生成的代码 24 25 /// <summary> 26 /// 设计器支持所需的方法 - 不要 27 /// 使用代码编辑器修改此方法的内容。 28 /// </summary> 29 private void InitializeComponent() 30 { 31 this.txtNum = new HZH_Controls.Controls.TextBoxEx(); 32 this.btnMinus = new System.Windows.Forms.Panel(); 33 this.btnAdd = new System.Windows.Forms.Panel(); 34 this.SuspendLayout(); 35 // 36 // txtNum 37 // 38 this.txtNum.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); 39 this.txtNum.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(247)))), ((int)(((byte)(247)))), ((int)(((byte)(247))))); 40 this.txtNum.BorderStyle = System.Windows.Forms.BorderStyle.None; 41 this.txtNum.DecLength = 3; 42 this.txtNum.Font = new System.Drawing.Font("Arial Unicode MS", 15F); 43 this.txtNum.InputType = TextInputType.Number; 44 this.txtNum.Location = new System.Drawing.Point(37, 11); 45 this.txtNum.Margin = new System.Windows.Forms.Padding(0); 46 this.txtNum.MaxValue = new decimal(new int[] { 47 1000000, 48 0, 49 0, 50 0}); 51 this.txtNum.MinValue = new decimal(new int[] { 52 0, 53 0, 54 0, 55 0}); 56 this.txtNum.MyRectangle = new System.Drawing.Rectangle(0, 0, 0, 0); 57 this.txtNum.Name = "txtNum"; 58 this.txtNum.OldText = null; 59 this.txtNum.PromptColor = System.Drawing.Color.Gray; 60 this.txtNum.PromptFont = new System.Drawing.Font("微软雅黑", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); 61 this.txtNum.PromptText = ""; 62 this.txtNum.RegexPattern = ""; 63 this.txtNum.Size = new System.Drawing.Size(78, 27); 64 this.txtNum.TabIndex = 9; 65 this.txtNum.Text = "1"; 66 this.txtNum.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; 67 this.txtNum.FontChanged += new System.EventHandler(this.txtNum_FontChanged); 68 this.txtNum.MouseDown += new System.Windows.Forms.MouseEventHandler(this.txtNum_MouseDown); 69 // 70 // btnMinus 71 // 72 this.btnMinus.BackColor = System.Drawing.Color.Transparent; 73 this.btnMinus.BackgroundImage = global::HZH_Controls.Properties.Resources.ic_remove_black_18dp; 74 this.btnMinus.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; 75 this.btnMinus.Dock = System.Windows.Forms.DockStyle.Left; 76 this.btnMinus.Location = new System.Drawing.Point(2, 2); 77 this.btnMinus.Name = "btnMinus"; 78 this.btnMinus.Size = new System.Drawing.Size(32, 40); 79 this.btnMinus.TabIndex = 6; 80 this.btnMinus.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnMinus_MouseDown); 81 // 82 // btnAdd 83 // 84 this.btnAdd.BackColor = System.Drawing.Color.Transparent; 85 this.btnAdd.BackgroundImage = global::HZH_Controls.Properties.Resources.ic_add_black_18dp; 86 this.btnAdd.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; 87 this.btnAdd.Dock = System.Windows.Forms.DockStyle.Right; 88 this.btnAdd.Location = new System.Drawing.Point(118, 2); 89 this.btnAdd.Name = "btnAdd"; 90 this.btnAdd.Size = new System.Drawing.Size(32, 40); 91 this.btnAdd.TabIndex = 5; 92 this.btnAdd.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnAdd_MouseDown); 93 // 94 // UCNumTextBox 95 // 96 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 97 this.Controls.Add(this.txtNum); 98 this.Controls.Add(this.btnMinus); 99 this.Controls.Add(this.btnAdd); 100 this.Name = "UCNumTextBox"; 101 this.Padding = new System.Windows.Forms.Padding(2); 102 this.Size = new System.Drawing.Size(152, 44); 103 this.Load += new System.EventHandler(this.UCNumTextBox_Load); 104 this.BackColorChanged += new System.EventHandler(this.UCNumTextBox_BackColorChanged); 105 this.ResumeLayout(false); 106 this.PerformLayout(); 107 108 } 109 110 #endregion 111 112 private System.Windows.Forms.Panel btnAdd; 113 private System.Windows.Forms.Panel btnMinus; 114 private TextBoxEx txtNum; 115 } 116 }
设计效果
用处及效果
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧