WPF自定义数字输入框控件
Posted 二逼青年,勇往直前
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF自定义数字输入框控件相关的知识,希望对你有一定的参考价值。
要求:只能输入数字和小数点,可以设置最大值,最小值,小数点前长度,小数点后长度(支持绑定设置);
代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Input; 9 10 namespace MyTool 11 { 12 /// <summary> 13 /// 数字输入框 14 /// author lixinmiao 15 /// </summary> 16 class NumTextBox : TextBox 17 { 18 public static readonly DependencyProperty NumTypeProperty = DependencyProperty.Register("NumType", typeof(Type), typeof(NumTextBox)); 19 public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(decimal), typeof(NumTextBox), new FrameworkPropertyMetadata( 20 new PropertyChangedCallback(CheckProperty))); 21 22 public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(decimal), typeof(NumTextBox), new FrameworkPropertyMetadata( 23 new PropertyChangedCallback(CheckProperty))); 24 public static readonly DependencyProperty PointLenthProperty = DependencyProperty.Register("PointLenth", typeof(int), typeof(NumTextBox)); 25 public static readonly DependencyProperty NumberLengthProperty = DependencyProperty.Register("NumberLength", typeof(int), typeof(NumTextBox)); 26 // private System.Globalization.CultureInfo cI; 27 public NumTextBox() 28 { 29 MinValue = decimal.MinValue; 30 MaxValue = decimal.MaxValue; 31 PointLenth = 2; 32 NumberLength = 13; 33 34 } 35 public enum Type { Decimal, UDecimal, Int, UInt } 36 /// <summary> 37 /// 设置或获取textbox的输入数据类型 38 /// </summary> 39 public Type NumType 40 { 41 get { return (Type)GetValue(NumTypeProperty); } 42 set { SetValue(NumTypeProperty, value); } 43 } 44 /// <summary> 45 /// 设定或获取最大值 46 /// </summary> 47 public decimal MaxValue 48 { 49 get { return (decimal)GetValue(MaxValueProperty); } 50 set { SetValue(MaxValueProperty, value); } 51 } 52 53 /// <summary> 54 /// 设定或获取最小值 55 /// </summary> 56 public decimal MinValue 57 { 58 get { return (decimal)GetValue(MinValueProperty); } 59 set { SetValue(MinValueProperty, value); } 60 } 61 /// <summary> 62 /// 设置或获取小数点前的位数 63 /// </summary> 64 public int NumberLength 65 { 66 get { return (int)GetValue(NumberLengthProperty); } 67 set { SetValue(NumberLengthProperty, value); } 68 } 69 /// <summary> 70 /// 设置或获取小数点后位数长度 71 /// </summary> 72 public int PointLenth 73 { 74 get { return (int)GetValue(PointLenthProperty); } 75 set { SetValue(PointLenthProperty, value); } 76 } 77 78 private string val = ""; 79 /// <summary> 80 /// 设定最大值最小值依赖属性回调函数 81 /// </summary> 82 /// <param name="d"></param> 83 /// <param name="e"></param> 84 private static void CheckProperty(DependencyObject d, DependencyPropertyChangedEventArgs e) 85 { 86 NumTextBox ntb = d as NumTextBox; 87 if (ntb.MaxValue < ntb.MinValue) 88 ntb.MaxValue = ntb.MinValue; 89 } 90 /// <summary> 91 /// 重写KeyDown事件,提供与事件有关的数据,过滤输入数据格式 92 /// </summary> 93 /// <param name="e"></param> 94 protected override void OnKeyDown(KeyEventArgs e) 95 { 96 string txt = this.Text; 97 int ind = this.CaretIndex; 98 if (txt.Contains(".")) 99 { 100 // Console.WriteLine(txt.Split(‘.‘)[0] + "he " + txt.Split(‘.‘)[1]); 101 if (txt.Split(‘.‘)[1].Length >= PointLenth && ind > txt.Split(‘.‘)[0].Length && this.SelectionLength == 0)//控制小数点后输入位数 102 { 103 e.Handled = true; 104 return; 105 } 106 else if (txt.Split(‘.‘)[0].Length >= NumberLength && ind <= txt.Split(‘.‘)[0].Length)//控制小数点前输入位数(有小数点) 107 { 108 e.Handled = true; 109 return; 110 } 111 } 112 else if (txt.Length == NumberLength && e.Key != Key.Decimal && e.Key != Key.OemPeriod)//控制小数点前输入位数(无小数点) 113 { 114 e.Handled = true; 115 return; 116 } 117 118 if (e.Key == Key.Decimal || e.Key == Key.OemPeriod) 119 { 120 val = "."; 121 } 122 else 123 { 124 125 val = ""; 126 } 127 switch (NumType) 128 { 129 130 case Type.UInt: 131 //屏蔽非法按键 132 if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) || e.Key.ToString() == "Tab") 133 { 134 e.Handled = false; 135 } 136 else if (((e.Key >= Key.D0 && e.Key <= Key.D9)) && e.KeyboardDevice.Modifiers != ModifierKeys.Shift) 137 { 138 e.Handled = false; 139 } 140 else 141 { 142 e.Handled = true; 143 if (e.Key.ToString() != "RightCtrl") 144 { } 145 } 146 break; 147 case Type.Int: 148 //屏蔽非法按键 149 if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) || e.Key == Key.Subtract || e.Key.ToString() == "Tab") 150 { 151 if ((txt.Contains("-") || this.CaretIndex != 0) && e.Key == Key.Subtract) 152 { 153 e.Handled = true; 154 return; 155 } 156 e.Handled = false; 157 } 158 else if (((e.Key >= Key.D0 && e.Key <= Key.D9) || e.Key == Key.OemMinus) && e.KeyboardDevice.Modifiers != ModifierKeys.Shift) 159 { 160 if ((txt.Contains("-") || this.CaretIndex != 0) && e.Key == Key.OemMinus) 161 { 162 e.Handled = true; 163 return; 164 } 165 e.Handled = false; 166 } 167 else 168 { 169 e.Handled = true; 170 if (e.Key.ToString() != "RightCtrl") 171 { } 172 } 173 break; 174 case Type.Decimal: 175 //屏蔽非法按键 176 if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) || e.Key == Key.Decimal || e.Key == Key.Subtract || e.Key.ToString() == "Tab") 177 { 178 if (txt.Contains(".") && e.Key == Key.Decimal) 179 { 180 e.Handled = true; 181 return; 182 } 183 else if ((txt.Contains("-") || this.CaretIndex != 0) && e.Key == Key.Subtract) 184 { 185 e.Handled = true; 186 return; 187 } 188 e.Handled = false; 189 } 190 else if (((e.Key >= Key.D0 && e.Key <= Key.D9) || e.Key == Key.OemPeriod || e.Key == Key.OemMinus) && e.KeyboardDevice.Modifiers != ModifierKeys.Shift) 191 { 192 if (txt.Contains(".") && e.Key == Key.OemPeriod) 193 { 194 e.Handled = true; 195 return; 196 } 197 else if ((txt.Contains("-") || this.CaretIndex != 0) && e.Key == Key.OemMinus) 198 { 199 e.Handled = true; 200 return; 201 } 202 e.Handled = false; 203 } 204 else 205 { 206 e.Handled = true; 207 if (e.Key.ToString() != "RightCtrl") 208 { } 209 } 210 break; 211 case Type.UDecimal: 212 default: 213 //屏蔽非法按键 214 if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) || e.Key == Key.Decimal || e.Key.ToString() == "Tab") 215 { 216 if (txt.Contains(".") && e.Key == Key.Decimal) 217 { 218 e.Handled = true; 219 return; 220 } 221 e.Handled = false; 222 } 223 else if (((e.Key >= Key.D0 && e.Key <= Key.D9) || e.Key == Key.OemPeriod) && e.KeyboardDevice.Modifiers != ModifierKeys.Shift) 224 { 225 if (txt.Contains(".") && e.Key == Key.OemPeriod) 226 { 227 e.Handled = true; 228 return; 229 } 230 e.Handled = false; 231 } 232 else 233 { 234 e.Handled = true; 235 if (e.Key.ToString() != "RightCtrl") 236 { } 237 } 238 239 break; 240 } 241 base.OnKeyDown(e); 242 } 243 /// <summary> 244 ///粘贴内容过滤,设定最大值、最小值,限制小数点输入长度 245 /// </summary> 246 /// <param name="e"></param> 247 protected override void OnTextChanged(TextChangedEventArgs e) 248 { 249 int t1 = this.Text.Length; 250 if (t1 != 0)//用于是否可以将文本空置空 251 { 252 decimal d = 0; 253 if (this.Text != "-" && this.Text != "." && this.Text != "-0" && this.Text != "-." && this.Text != "-0." && val != ".") 254 { 255 if (decimal.TryParse(this.Text, out d)) 256 { 257 if (NumType == Type.Decimal || NumType == Type.UDecimal) 258 { 259 if (d.ToString().Split(‘.‘)[0].Length > NumberLength)// 260 { 261 d = 0; 262 } 263 else 264 { 265 d = Math.Round(d, PointLenth, MidpointRounding.AwayFromZero); 266 } 267 } 268 else 269 if (d.ToString().Split(‘.‘)[0].Length > NumberLength)// 270 { 271 d = 0; 272 } 273 else 274 { 275 d = Math.Round(d, 0, MidpointRounding.AwayFromZero); 276 } 277 } 278 int t2 = d.ToString().Length; 279 if (Math.Abs(t1 - d.ToString().Length) > 0) 280 { 281 this.Text = d.ToString(); 282 this.CaretIndex = d.ToString().Length; 283 } 284 else 285 { 286 this.Text = d.ToString(); 287 } 288 289 } 290 if ((NumType == Type.UDecimal || NumType == Type.UInt) && this.Text.Contains("-")) 291 { 292 this.Text = Math.Abs(d).ToString(); 293 } 294 if ((NumType == Type.UInt || NumType == Type.Int) && this.Text.Contains(".")) 295 { 296 this.Text = int.Parse(d.ToString()).ToString(); 297 } 298 } 299 base.OnTextChanged(e); 300 } 301 302 /// <summary> 303 ///如果数据是0,得到光标,清空数据 304 /// </summary> 305 /// <param name="e"></param> 306 protected override void OnGotFocus(RoutedEventArgs e) 307 { 308 //InputMethod.SetPreferredImeState(this, InputMethodState.Off); 309 //cI = InputLanguageManager.GetInputLanguage(this); 310 //decimal d = 0; 311 //if (decimal.TryParse(this.Text, out d)) 312 //{ 313 if (this.Text == "0") 314 { 315 this.Text = ""; 316 } 317 //} 318 //else 319 //{ 320 // this.Text = ""; 321 //} 322 base.OnGotFocus(e); 323 } 324 325 /// <summary> 326 ///失去光标,确定最大值最小值 327 /// </summary> 328 /// <param name="e"></param> 329 protected override void OnLostFocus(RoutedEventArgs e) 330 { 331 decimal d = 0; 332 if (decimal.TryParse(this.Text, out d)) 333 { 334 if (d < MinValue) 335 { 336 d = MinValue; 337 this.Text = d.ToString(); 338 } 339 340 else if (d > MaxValue) 341 { 342 d = MaxValue; 343 this.Text = d.ToString(); 344 } 345 } 346 else if (string.IsNullOrEmpty(this.Text)) 347 { 348 this.Text = ""; 349 } 350 else 351 { 352 this.Text = d.ToString(); 353 } 354 base.OnLostFocus(e); 355 //System.Globalization.CultureInfo cI = InputLanguageManager.GetInputLanguage(this); 356 //InputMethod.SetPreferredImeState(this, InputMethodState.DoNotCare); 357 //InputLanguageManager.SetInputLanguage(this, cI); 358 //cI = null; 359 } 360 } 361 }
具体用法:
将改文件命名控件引用到要使用的xaml页面,然后采用引用控件的使用方法使用即可。
通过NumType设置绑定的数据类型,整数,正整数,小数,正小数;
其余的几个属性类似;
欢迎探讨。
有问题,请联系QQ:2860580831 或发邮件到[email protected]
以上是关于WPF自定义数字输入框控件的主要内容,如果未能解决你的问题,请参考以下文章
wpf中我自定义了一个自定义控件,add到了界面,如何设置显示在最底层?后台代码如何控制?
WPF自定义控件与样式-TextBox & RichTextBox & PasswordBox样式水印Label标签功能扩展