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 自定义控件并使用(例如带水印和字体图标的文本框)

WPF 自定义控件将文本框文本重置为默认值

wpf中我自定义了一个自定义控件,add到了界面,如何设置显示在最底层?后台代码如何控制?

WPF自定义控件与样式-TextBox & RichTextBox & PasswordBox样式水印Label标签功能扩展

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

WPF 自定义搜索框