• 备份一段代码,用于提前测试textbox输入字符后的字符串


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace XYY.Windows.SAAS.WpfExtention.AttachedProperties
    {
        public class InputAttachedProperties
        {
            #region 附加属性
            public static bool GetEnableInputValidate(DependencyObject obj)
            {
                return (bool)obj.GetValue(EnableInputValidateProperty);
            }
            public static void SetEnableInputValidate(DependencyObject obj, bool value)
            {
                obj.SetValue(EnableInputValidateProperty, value);
            }
            //是否使用输入校验
            public static readonly DependencyProperty EnableInputValidateProperty =
                DependencyProperty.RegisterAttached("EnableInputValidate", typeof(bool), typeof(InputAttachedProperties), new PropertyMetadata(false, (a, b) =>
                {
                    if (a is TextBox tb && b.NewValue is bool en)
                    {
                        if (en)
                        {
                            tb.PreviewTextInput += Tb_PreviewTextInput;
                            tb.GotFocus += Tb_GotFocus;
                            tb.TextChanged += Tb_TextChanged;
                            tb.AcceptsReturn = false;
                            tb.AcceptsTab = false;
                            tb.PreviewDrop += Tb_PreviewDrop;
                            CommandManager.AddPreviewExecutedHandler(tb, tbPreviewCommandExcute);
                            //禁用输入法
                            if (tb.IsInputMethodEnabled)
                            {
                                InputMethod.SetIsInputMethodEnabled(tb, false);
                                InputMethod.Current.ImeState = InputMethodState.Off;
                            }
                        }
                        else
                        {
                            tb.PreviewTextInput -= Tb_PreviewTextInput;
                            tb.GotFocus -= Tb_GotFocus;
                            tb.AcceptsReturn = true;
                            tb.AcceptsTab = true;
                            tb.PreviewDrop -= Tb_PreviewDrop;
                            CommandManager.RemovePreviewExecutedHandler(tb, tbPreviewCommandExcute);
                            //禁用输入法
                            if (tb.IsInputMethodEnabled)
                            {
                                InputMethod.SetIsInputMethodEnabled(tb, true);
                                InputMethod.Current.ImeState = InputMethodState.DoNotCare;
                            }
                        }
    
                    }
                }));
    
            private static void Tb_GotFocus(object sender, RoutedEventArgs e)
            {
                var tb = sender as TextBox;
                tb.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, new Action(() =>
                {
                    tb.SelectAll();
                }));
            }
    
            public static bool GetIsNumber(DependencyObject obj)
            {
                return (bool)obj.GetValue(IsNumberProperty);
            }
            public static void SetIsNumber(DependencyObject obj, bool value)
            {
                obj.SetValue(IsNumberProperty, value);
            }
            //是否是数字 (不能有负号,小数)
            public static readonly DependencyProperty IsNumberProperty =
                DependencyProperty.RegisterAttached("IsNumber", typeof(bool), typeof(InputAttachedProperties), new PropertyMetadata(false));
    
    
            public static bool GetIsAmount(DependencyObject obj)
            {
                return (bool)obj.GetValue(IsAmountProperty);
            }
            public static void SetIsAmount(DependencyObject obj, bool value)
            {
                obj.SetValue(IsAmountProperty, value);
            }
            //是否是金额 (可以有负号,小数)
            public static readonly DependencyProperty IsAmountProperty =
                DependencyProperty.RegisterAttached("IsAmount", typeof(bool), typeof(InputAttachedProperties), new PropertyMetadata(false));
    
    
    
            public static int GetDecimalPlace(DependencyObject obj)
            {
                return (int)obj.GetValue(DecimalPlaceProperty);
            }
            public static void SetDecimalPlace(DependencyObject obj, int value)
            {
                obj.SetValue(DecimalPlaceProperty, value);
            }
            //小数位数
            public static readonly DependencyProperty DecimalPlaceProperty =
                DependencyProperty.RegisterAttached("DecimalPlace", typeof(int), typeof(InputAttachedProperties), new PropertyMetadata(3));
    
    
            #endregion
    
            #region 校验方法
            private static void tbPreviewCommandExcute(object sender, ExecutedRoutedEventArgs e)
            {
                var tb = sender as TextBox;
                var isNumber = GetIsNumber(sender as TextBox);
                var isAmount = GetIsAmount(sender as TextBox);
                if (e.Command == ApplicationCommands.Cut ||
                    e.Command == ApplicationCommands.Paste)
                {
                    e.Handled = true;
                }
                if (e.Command is RoutedUICommand rc)
                {
                    switch (rc.Name)
                    {
                        case "MoveUpByLine":
                        case "MoveDownByLine":
                            e.Handled = true;
                            return;
                        case "Space":
                            if (isAmount || isNumber)
                                e.Handled = true;
                            return;
                        case "DeletePreviousWord":
                        case "DeleteNextWord":
                        case "Backspace":
                        case "Delete":
                            var result = TestFutureText(null, sender as TextBox, rc.Name);
                            //只有多个连续的0替换成只有一个
                            if (Regex.IsMatch(result, @"^-?00+$"))
                            {
                                tb.Text = Regex.Replace(result, @"0+", m => "0");
                                tb.CaretIndex = tb.Text.Length;
                                e.Handled = true;
                                return;
                            }
                            //小数删得只有末尾的.,把.也删了
                            if (Regex.IsMatch(result, @".0*$"))
                            {
                                tb.Text = Regex.Replace(result, @".0*$", m => string.Empty);
                                tb.CaretIndex = tb.Text.Length;
    
                                e.Handled = true;
                                return;
                            }
                            //整数部分删得只有-,把整数部分改为0
                            if (Regex.IsMatch(result, @"^-(?!d)"))
                            {
                                tb.Text = result.Replace("-", "0");
                                tb.CaretIndex = 0;
                                tb.SelectionStart = 0;
                                tb.SelectionLength = 1;
                                e.Handled = true;
                                return;
                            }
                            //如果输入了.,但是没有整数部分,整数部分补0
                            if (Regex.IsMatch(result, @"^."))
                            {
                                tb.Text = "0" + result;
                                tb.CaretIndex = 0;
                                tb.SelectionStart = 0;
                                tb.SelectionLength = 1;
                                e.Handled = true;
                                return;
                            }
                            //整数无意义的0去掉
                            //小数无意义的0去掉
                            if (Regex.IsMatch(result, @"(^.*..*?)0+$"))
                            {
                                tb.Text = Regex.Match(result, @"(^.*..*?)0+$").Groups[1].Value;
                                tb.CaretIndex = tb.Text.Length;
                                e.Handled = true;
                                return;
                            }
    
                            break;
                        default:
                            break;
                    }
                }
            }
    
            private static void Tb_PreviewDrop(object sender, DragEventArgs e)
            {
                e.Handled = true;
                return;
            }
    
            private static void Tb_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
            {
    
                var previewText = e.Text;
                var tb = sender as TextBox;
                //禁用输入法
                if (tb.IsInputMethodEnabled)
                {
                    InputMethod.SetIsInputMethodEnabled(tb, false);
                    InputMethod.Current.ImeState = InputMethodState.Off;
                }
                var result = TestFutureText(previewText, tb);
                var isNumber = GetIsNumber(tb);
                var isAmount = GetIsAmount(tb);
                var decimalSpace = GetDecimalPlace(tb);
                //isAmoust和isNumber互斥,且优先级高于isNumber
                if (isAmount)
                    isNumber = false;
                if (isNumber || isAmount)
                {
                    //不能输入空格
                    if (Regex.IsMatch(result, @"s+"))
                    {
                        e.Handled = true;
                        return;
                    }
                    //全0的时候 ,多个连接的0替换成只有一个
                    if (Regex.IsMatch(result, @"^-?00+$"))
                    {
                        tb.Text = Regex.Replace(result, @"0+", m => "0");
                        tb.CaretIndex = tb.Text.Length;
                        e.Handled = true;
                        return;
                    }
    
                }
                //纯数字模式
                if (isNumber)
                {
                    //如果不是纯数字,处理掉输入信号
                    if (!Regex.IsMatch(result, @"^d+$"))
                    {
                        e.Handled = true;
                        return;
                    }
                    //如果只输了0再输其他的数字,直接替换掉0
                    if (tb.Text == "0" && tb.SelectionLength == 0 && tb.CaretIndex == 1)
                    {
                        tb.Text = previewText;
                        tb.CaretIndex = 1;
                        e.Handled = true;
                        return;
                    }
                    //不能输入没有意义的0
                    if (Regex.IsMatch(result, @"^0(?=d)"))
                    {
                        e.Handled = true;
                        return;
                    }
                }
                //金额模式(正负值 小数点)
                if (isAmount)
                {
                    //只能输入数字和小数点和负号
                    if (!Regex.IsMatch(previewText, @"[d.-]"))
                    {
                        e.Handled = true;
                        return;
                    }
                    //如果光标右边是. 什么都不做,光标右移一位
                    if (Regex.IsMatch(tb.Text, @"d+.d+") && previewText == "." && tb.Text.Length != tb.CaretIndex && tb.Text[tb.CaretIndex] == '.')
                    {
                        tb.CaretIndex++;
                    }
                    //小数点如果超过限制,中断输入信号
                    if (Regex.IsMatch(result, @".d+$"))
                    {
                        var len = Regex.Match(result, @".(d+$)").Groups[1].Length;
                        if (len > decimalSpace)
                        {
                            e.Handled = true;
                            return;
                        }
                    }
                    //如果是-.的情况 改为-0.1
                    if (result == "-.")
                    {
                        tb.Text = "-0.1";
                        tb.CaretIndex = tb.Text.Length - 1;
                        tb.SelectionStart = tb.Text.Length - 1;
                        tb.SelectionLength = 1;
                        e.Handled = true;
                        return;
                    }
                    if (result == ".")
                    {
                        tb.Text = "0.1";
                        tb.CaretIndex = tb.Text.Length - 1;
                        tb.SelectionStart = tb.Text.Length - 1;
                        tb.SelectionLength = 1;
                        e.Handled = true;
                        return;
                    }
    
    
                    //如果有多个小数点不让输入
                    if (Regex.Matches(result, @".").Count > 1)
                    {
                        e.Handled = true;
                        return;
                    }
                    //如果有多个负号不让输入
                    if (Regex.Matches(result, @"-").Count > 1)
                    {
                        e.Handled = true;
                        return;
                    }
                    //如果负号不是在最前面不让输入
                    if (Regex.IsMatch(result, @"(?<!^)-"))
                    {
                        e.Handled = true;
                        return;
                    }
                    //不能输入空格
                    if (Regex.IsMatch(result, @"s+"))
                    {
                        e.Handled = true;
                        return;
                    }
                    //整数部分如果只输了0或-0,光标定位在0后面再输其他的数字,直接替换掉0
                    if (((Regex.IsMatch(result, @"^0+") && tb.CaretIndex == 1) || (Regex.IsMatch(result, @"^-0+") && tb.CaretIndex == 2)) && tb.SelectionLength == 0)
                    {
                        if (previewText != ".")
                        {
                            tb.Text = Regex.Replace(tb.Text, @"0+", m =>
                            {
                                if (m.Index == 0)
                                {
                                    return previewText;
                                }
                                return m.Value;
                            });
    
                            tb.CaretIndex = tb.Text.IndexOf(previewText) + 1;
                            e.Handled = true;
                            return;
                        }
                    }
                    //小数点前面不能输入没有意义的0
                    if (Regex.IsMatch(result, @"^-?0(?=d)"))
                    {
                        e.Handled = true;
                        return;
                    }
                    //小数点后面不能输没有意义的0,所以自动补1,1为选中状态
                    if (Regex.IsMatch(result, @".d*0$"))
                    {
                        var decimalSpaceLen = Regex.Match(result, @"[^.]+$").Value.Length;
                        if (decimalSpaceLen <= decimalSpace - 1)
                        {
                            tb.Text = result + "1";
                            tb.CaretIndex = tb.Text.Length - 1;
                            tb.SelectionStart = tb.CaretIndex;
                            tb.SelectionLength = 1;
                        }
                        e.Handled = true;
                        return;
                    }
                    //如果整数部分只输入了-号,自动补全为-1  1为选中状态
                    if (Regex.IsMatch(result, @"^-(?!d)"))
                    {
                        tb.Text = result.Replace("-", "-1");
                        tb.CaretIndex = 1;
                        tb.SelectionStart = 1;
                        tb.SelectionLength = 1;
                        e.Handled = true;
                        return;
                    }
                    //如果在末尾输入了. ,自动补全为.1 ,1为选中状态
                    if (Regex.IsMatch(result, @".$"))
                    {
                        var i = result.IndexOf('.');
                        tb.Text = result.Replace(".", ".1");
                        tb.CaretIndex = i + 1;
                        tb.SelectionStart = i + 1;
                        tb.SelectionLength = 1;
                        e.Handled = true;
                        return;
                    }
    
                    //如果输入了.,但是没有整数部分,整数部分补0
                    if (Regex.IsMatch(result, @"^."))
                    {
                        tb.Text = "0" + result;
                        tb.CaretIndex = 0;
                        tb.SelectionStart = 0;
                        tb.SelectionLength = 1;
                        e.Handled = true;
                        return;
                    }
    
    
                }
            }
    
            private static string TestFutureText(string previewText, TextBox tb, string deleteMode = null)
            {
                var cindex = tb.CaretIndex;
                var sLen = tb.SelectionLength;
                var sStartIndex = tb.SelectionStart;
                var deleteStart = cindex >= sStartIndex ? sStartIndex : cindex;
                string futureText = string.Empty;
                //按删除的
                if (!string.IsNullOrEmpty(deleteMode))
                {
                    //按删除键,且有选择字符时,直接删除选择的字符
                    if (tb.SelectionLength > 0)
                    {
                        switch (deleteMode)
                        {
                            case "DeletePreviousWord":
                            case "DeleteNextWord":
                            case "Backspace":
                            case "Delete":
                            default:
                                futureText = tb.Text.Remove(deleteStart, sLen);
                                break;
                        }
                    }
                    //按删除键,没有选择字符时
                    else
                    {
                        switch (deleteMode)
                        {
                            //ctrl+backspace 删除到 单词左边 
                            case "DeletePreviousWord":
                                if (cindex == 0)
                                    return tb.Text;
                                var c = tb.Text[cindex - 1];
                                var isWord = Regex.IsMatch(c.ToString(), @"w");
                                if (!isWord)
                                {
                                    futureText = tb.Text.Remove(cindex - 1, 1);
                                    return futureText;
                                }
                                var startindex = 0;
                                for (int i = 0; i < cindex; i++)
                                {
                                    if (Regex.IsMatch(tb.Text[i].ToString(), @"W"))
                                    {
                                        startindex = i + 1;
                                    }
                                }
                                futureText = tb.Text.Remove(startindex, cindex - startindex);
                                break;
                            //ctrl+delete 删除到 单词右边
                            case "DeleteNextWord":
                                if (cindex == tb.Text.Length)
                                    return tb.Text;
                                var c2 = tb.Text[cindex];
                                var isWord2 = Regex.IsMatch(c2.ToString(), @"w");
                                if (!isWord2)
                                {
                                    futureText = tb.Text.Remove(cindex, 1);
                                    return futureText;
                                }
                                var end = 0;
                                for (int i = cindex; i < tb.Text.Length; i++)
                                {
                                    if (Regex.IsMatch(c2.ToString(), @"w"))
                                        end = i;
                                    else
                                        break;
                                }
                                futureText = tb.Text.Remove(cindex, end - cindex);
    
                                break;
                            //删除光标左边的字符1个或0个
                            case "Backspace":
                                futureText = tb.Text.Remove(deleteStart - 1 <= 0 ? 0 : deleteStart - 1, deleteStart >= 1 ? 1 : 0);
                                break;
                            //删除光标左右的字符1个或0个
                            case "Delete":
                                futureText = tb.Text.Remove(deleteStart, tb.Text.Length - deleteStart >= 1 ? 1 : 0);
                                break;
                            default:
                                break;
                        }
                    }
                }
                //不是按删除的
                else
                {
                    futureText = tb.Text.Remove(deleteStart, sLen).Insert(deleteStart, previewText);
                }
                Console.WriteLine(futureText);
                return futureText;
            }
    
            private static void Tb_TextChanged(object sender, TextChangedEventArgs e)
            {
                var tb = sender as TextBox;
                var isNumber = GetIsNumber(tb);
                var isAmount = GetIsAmount(tb);
    
                if ((isNumber || isAmount) && string.IsNullOrWhiteSpace(tb.Text))
                {
                    tb.Text = "0";
                    tb.SelectionStart = 0;
                    tb.SelectionLength = 1;
                }
            }
    
    
            #endregion
    
    
        }
    }
    
    
  • 相关阅读:
    BroadcastReceiver 小结
    Android Manifest.xml 之 Intent-filter
    First Phone Interview
    XDK html development --- Cross Domain Request
    Github Git usage
    为节省内存,动态添加view布局和控件
    相似的概念
    让一个view 获得焦点
    ListView 关于减少耗时方法调用优化
    SearchView 分解设置属性
  • 原文地址:https://www.cnblogs.com/nocanstillbb/p/15016485.html
Copyright © 2020-2023  润新知