博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF 自定义TextBox,可控制键盘输入内容
阅读量:7237 次
发布时间:2019-06-29

本文共 17105 字,大约阅读时间需要 57 分钟。

非原创,整理之前的代码的时候找出来的,可用,与大家分享一下!

 

1   public class NumbericBoxWithZero : NumericBox  2     {  3         public NumbericBoxWithZero()  4             : base()  5         {  6   7   8         }  9         protected override void SetTextAndSelection(string text) 10         { 11             if (text.IndexOf('.') == -1) 12             { 13                 text = text + ".00"; 14             } 15             else 16             { 17                 if (text.IndexOf('.') != text.Length - 1) 18                 { 19                     string front = text.Substring(0,text.IndexOf('.')); 20                     string back = text.Substring(text.IndexOf('.') + 1, text.Length - text.IndexOf('.') - 1); 21                     if(back != "00") 22                         text = string.Format("{0}.{1:d2}",front,int.Parse(back)); 23                 } 24             } 25             base.SetTextAndSelection(text); 26         } 27     } 28     ///  29     /// NumericBox功能设计 30     /// 只能输入0-9的数字和至多一个小数点; 31     ///能够屏蔽通过非正常途径的不正确输入(输入法,粘贴等); 32     ///能够控制小数点后的最大位数,超出位数则无法继续输入; 33     ///能够选择当小数点数位数不足时是否补0; 34     ///去除开头部分多余的0(为方便处理,当在开头部分输入0时,自动在其后添加一个小数点); 35     ///由于只能输入一个小数点,当在已有的小数点前再次按下小数点,能够跳过小数点; 36     ///  37     public class NumericBox : TextBox 38     { 39         #region Dependency Properties 40         ///  41         /// 最大小数点位数 42         ///  43         public int MaxFractionDigits 44         { 45             get { return (int)GetValue(MaxFractionDigitsProperty); } 46             set { SetValue(MaxFractionDigitsProperty, value); } 47         } 48         // Using a DependencyProperty as the backing store for MaxFractionDigits.  This enables animation, styling, binding, etc... 49         public static readonly DependencyProperty MaxFractionDigitsProperty = 50             DependencyProperty.Register("MaxFractionDigits", typeof(int), typeof(NumericBox), new PropertyMetadata(2)); 51  52         ///  53         /// 不足位数是否补零 54         ///  55         public bool IsPadding 56         { 57             get { return (bool)GetValue(IsPaddingProperty); } 58             set { SetValue(IsPaddingProperty, value); } 59         } 60         // Using a DependencyProperty as the backing store for IsPadding.  This enables animation, styling, binding, etc... 61         public static readonly DependencyProperty IsPaddingProperty = 62             DependencyProperty.Register("IsPadding", typeof(bool), typeof(NumericBox), new PropertyMetadata(true)); 63  64         #endregion 65  66         public NumericBox() 67         { 68             TextBoxFilterBehavior behavior = new TextBoxFilterBehavior(); 69             behavior.TextBoxFilterOptions = TextBoxFilterOptions.Numeric | TextBoxFilterOptions.Dot; 70             Interaction.GetBehaviors(this).Add(behavior); 71             this.TextChanged += new TextChangedEventHandler(NumericBox_TextChanged); 72         } 73  74         ///  75         /// 设置Text文本以及光标位置 76         ///  77         ///  78         protected virtual void SetTextAndSelection(string text) 79         { 80             //保存光标位置 81             int selectionIndex = this.SelectionStart; 82             this.Text = text; 83             //恢复光标位置 系统会自动处理光标位置超出文本长度的情况 84             this.SelectionStart = selectionIndex; 85         } 86  87         ///  88         /// 去掉开头部分多余的0 89         ///  90         private void TrimZeroStart() 91         { 92             string resultText = this.Text; 93             //计算开头部分0的个数 94             int zeroCount = 0; 95             foreach (char c in this.Text) 96             { 97                 if (c == '0') { zeroCount++; } 98                 else { break; } 99             }100 101             //当前文本中包含小数点102             if (this.Text.Contains('.'))103             {104                 //0后面跟的不是小数点,则删除全部的0105                 if (this.Text[zeroCount] != '.')106                 {107                     resultText = this.Text.TrimStart('0');108                 }109                 //否则,保留一个0110                 else if (zeroCount > 1)111                 {112                     resultText = this.Text.Substring(zeroCount - 1);113                 }114             }115             //当前文本中不包含小数点,则保留一个0,并在其后加一个小数点,并将光标设置到小数点前116             else if (zeroCount > 0)117             {118                 resultText = "0." + this.Text.TrimStart('0');119                 this.SelectionStart = 1;120             }121 122             SetTextAndSelection(resultText);123         }124 125         void NumericBox_TextChanged(object sender, TextChangedEventArgs e)126         {127             int decimalIndex = this.Text.IndexOf('.');128             if (decimalIndex >= 0)129             {130                 //小数点后的位数131                 int lengthAfterDecimal = this.Text.Length - decimalIndex - 1;132                 if (lengthAfterDecimal > MaxFractionDigits)133                 {134                     SetTextAndSelection(this.Text.Substring(0, this.Text.Length - (lengthAfterDecimal - MaxFractionDigits)));135                 }136                 else if (IsPadding)137                 {138                     SetTextAndSelection(this.Text.PadRight(this.Text.Length + MaxFractionDigits - lengthAfterDecimal, '0'));139                 }140             }141             TrimZeroStart();142         }143     }144     /// 145     /// TextBox筛选行为,过滤不需要的按键146     /// 147     public class TextBoxFilterBehavior : Behavior
148 {149 private string _prevText = string.Empty;150 public TextBoxFilterBehavior()151 {152 }153 #region Dependency Properties154 ///
155 /// TextBox筛选选项,这里选择的为过滤后剩下的按键156 /// 控制键不参与筛选,可以多选组合157 /// 158 public TextBoxFilterOptions TextBoxFilterOptions159 {160 get { return (TextBoxFilterOptions)GetValue(TextBoxFilterOptionsProperty); }161 set { SetValue(TextBoxFilterOptionsProperty, value); }162 }163 164 // Using a DependencyProperty as the backing store for TextBoxFilterOptions. This enables animation, styling, binding, etc...165 public static readonly DependencyProperty TextBoxFilterOptionsProperty =166 DependencyProperty.Register("TextBoxFilterOptions", typeof(TextBoxFilterOptions), typeof(TextBoxFilterBehavior), new PropertyMetadata(TextBoxFilterOptions.None));167 #endregion168 169 protected override void OnAttached()170 {171 base.OnAttached();172 this.AssociatedObject.KeyDown += new KeyEventHandler(AssociatedObject_KeyDown);173 this.AssociatedObject.TextChanged += new TextChangedEventHandler(AssociatedObject_TextChanged);174 }175 176 protected override void OnDetaching()177 {178 base.OnDetaching();179 this.AssociatedObject.KeyDown -= new KeyEventHandler(AssociatedObject_KeyDown);180 this.AssociatedObject.TextChanged -= new TextChangedEventHandler(AssociatedObject_TextChanged);181 }182 183 #region Events184 185 ///
186 /// 处理通过其它手段进行的输入187 /// 188 ///
189 ///
190 void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)191 {192 //如果符合规则,就保存下来193 if (IsValidText(this.AssociatedObject.Text))194 {195 _prevText = this.AssociatedObject.Text;196 }197 //如果不符合规则,就恢复为之前保存的值198 else199 {200 int selectIndex = this.AssociatedObject.SelectionStart - (this.AssociatedObject.Text.Length - _prevText.Length);201 this.AssociatedObject.Text = _prevText;202 203 if (selectIndex < 0)204 selectIndex = 0;205 206 this.AssociatedObject.SelectionStart = selectIndex;207 }208 209 }210 211 ///
212 /// 处理按键产生的输入213 /// 214 ///
215 ///
216 void AssociatedObject_KeyDown(object sender, KeyEventArgs e)217 {218 bool handled = true;219 //不进行过滤220 if (TextBoxFilterOptions == TextBoxFilterOptions.None ||221 KeyboardHelper.IsControlKeys(e.Key))222 {223 handled = false;224 }225 //数字键226 if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Numeric))227 {228 handled = !KeyboardHelper.IsDigit(e.Key);229 }230 //小数点231 //if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Dot))232 //{233 // handled = !(KeyboardHelper.IsDot(e.Key, e.PlatformKeyCode) && !_prevText.Contains("."));234 // if (KeyboardHelper.IsDot(e.Key, e.PlatformKeyCode) && _prevText.Contains("."))235 // {236 // //如果输入位置的下一个就是小数点,则将光标跳到小数点后面237 // if (this.AssociatedObject.SelectionStart< this.AssociatedObject.Text.Length && _prevText[this.AssociatedObject.SelectionStart] == '.')238 // {239 // this.AssociatedObject.SelectionStart++;240 // } 241 // }242 //}243 if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Dot))244 {245 handled = !(KeyboardHelper.IsDot(e.Key) && !_prevText.Contains("."));246 if (KeyboardHelper.IsDot(e.Key) && _prevText.Contains("."))247 {248 //如果输入位置的下一个就是小数点,则将光标跳到小数点后面249 if (this.AssociatedObject.SelectionStart < this.AssociatedObject.Text.Length && _prevText[this.AssociatedObject.SelectionStart] == '.')250 {251 this.AssociatedObject.SelectionStart++;252 }253 }254 }255 //字母256 if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Character))257 {258 handled = !KeyboardHelper.IsDot(e.Key);259 }260 e.Handled = handled;261 }262 263 #endregion264 265 #region Private Methods266 ///
267 /// 判断是否符合规则268 /// 269 ///
270 ///
271 private bool IsValidChar(char c)272 {273 if (TextBoxFilterOptions == TextBoxFilterOptions.None)274 {275 return true;276 }277 else if (TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Numeric) &&278 '0' <= c && c <= '9')279 {280 return true;281 }282 else if (TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Dot) &&283 c == '.')284 {285 return true;286 }287 else if (TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Character))288 {289 if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))290 {291 return true;292 }293 }294 return false;295 }296 297 ///
298 /// 判断文本是否符合规则299 /// 300 ///
301 ///
302 private bool IsValidText(string text)303 {304 //只能有一个小数点305 if (text.IndexOf('.') != text.LastIndexOf('.'))306 {307 return false;308 }309 foreach (char c in text)310 {311 if (!IsValidChar(c))312 {313 return false;314 }315 }316 return true;317 }318 #endregion319 }320 ///
321 /// TextBox筛选选项322 /// 323 [Flags]324 public enum TextBoxFilterOptions325 {326 ///
327 /// 不采用任何筛选328 /// 329 None = 0,330 ///
331 /// 数字类型不参与筛选332 /// 333 Numeric = 1,334 ///
335 /// 字母类型不参与筛选336 /// 337 Character = 2,338 ///
339 /// 小数点不参与筛选340 /// 341 Dot = 4,342 ///
343 /// 其它类型不参与筛选344 /// 345 Other = 8346 }347 348 ///
349 /// TextBox筛选选项枚举扩展方法350 /// 351 public static class TextBoxFilterOptionsExtension352 {353 ///
354 /// 在全部的选项中是否包含指定的选项355 /// 356 ///
所有的选项357 ///
指定的选项358 ///
359 public static bool ContainsOption(this TextBoxFilterOptions allOptions, TextBoxFilterOptions option)360 {361 return (allOptions & option) == option;362 }363 }364 ///
365 /// 键盘操作帮助类366 /// 367 public class KeyboardHelper368 {369 ///
370 /// 键盘上的句号键371 /// 372 public const int OemPeriod = 190;373 374 #region Fileds375 376 ///
377 /// 控制键378 /// 379 private static readonly List
_controlKeys = new List
380 {381 Key.Back,382 Key.CapsLock,383 //Key.Ctrl,384 Key.Down,385 Key.End,386 Key.Enter,387 Key.Escape,388 Key.Home,389 Key.Insert,390 Key.Left,391 Key.PageDown,392 Key.PageUp,393 Key.Right,394 //Key.Shift,395 Key.Tab,396 Key.Up397 };398 399 #endregion400 401 ///
402 /// 是否是数字键403 /// 404 ///
按键405 ///
406 public static bool IsDigit(Key key)407 {408 bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;409 bool retVal;410 //按住shift键后,数字键并不是数字键411 if (key >= Key.D0 && key <= Key.D9 && !shiftKey)412 {413 retVal = true;414 }415 else416 {417 retVal = key >= Key.NumPad0 && key <= Key.NumPad9;418 }419 return retVal;420 }421 422 ///
423 /// 是否是控制键424 /// 425 ///
按键426 ///
427 public static bool IsControlKeys(Key key)428 {429 return _controlKeys.Contains(key);430 }431 432 ///
433 /// 是否是小数点434 /// Silverlight中无法识别问号左边的那个小数点键435 /// 只能识别小键盘中的小数点436 /// 437 ///
按键438 ///
439 public static bool IsDot(Key key)440 {441 bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;442 bool flag = false;443 if (key == Key.Decimal)444 {445 flag = true;446 }447 if (key == Key.OemPeriod && !shiftKey)448 {449 flag = true;450 }451 return flag;452 }453 454 ///
455 /// 是否是小数点456 /// 457 ///
按键458 ///
平台相关的按键代码459 ///
460 public static bool IsDot(Key key, int keyCode)461 {462 463 //return IsDot(key) || (key == Key.Unknown && keyCode == OemPeriod);464 return IsDot(key) || (keyCode == OemPeriod);465 }466 467 ///
468 /// 是否是字母键469 /// 470 ///
按键471 ///
472 public static bool IsCharacter(Key key)473 {474 return key >= Key.A && key <= Key.Z;475 }476 }
View Code

使用:

 

转载于:https://www.cnblogs.com/xiamojinnian/p/4578920.html

你可能感兴趣的文章
如何安装python
查看>>
Android系统手机端抓包方法
查看>>
【Java学习笔记之十三】初探Java面向对象的过程及代码实现
查看>>
【POI xls Java map】使用POI处理xls 抽取出异常信息 --java1.8Group by ---map迭代 -- 设置单元格高度...
查看>>
Ubuntu 14.04 安装VMware 12
查看>>
Hbase多版本的读写(Shell&Java API版)
查看>>
判断单链表是否有环的两种方法
查看>>
网页上用js禁用鼠标右键
查看>>
【&#9733;】微信之于QQ的市场哲学
查看>>
抓取某一个网站整站的记录
查看>>
Android依赖管理与私服搭建
查看>>
常用正则表达式大全!(例如:匹配中文、匹配html)
查看>>
结合抓包工具深入分析slb、vpc网络配置ftp服务
查看>>
关于db link权限分配的苦旅(二)
查看>>
CentOS7下如何查看vsftpd服务的状态
查看>>
阿里云Redis华北5 (呼和浩特)开放售卖
查看>>
SAP后台配置中“公司”与“公司代码”概念的不同
查看>>
JSP application对象
查看>>
使用消息系统进行微服务间通讯时,如何保证数据一致性
查看>>
Java---俄罗斯方块小游戏
查看>>