• WPF正则表达式绑定的数字文本框,错误模板,带提示信息watermark


    正则表达式验证double类型的数字:

     public class ValidateRegexs
        {
            /// <summary>
            /// 文本验证,[匹配数字],正则表达式
            /// 涵盖:整数、小数、正负数,最大9位
            /// </summary>
            public static string TextboxNumericValidateRegex = @"^-?(?<decimalValue>0.d{1,9})?(?(decimalValue)|([1-9]{1}[0-9]{0,9}(.d+)?))$";
    
    
    
            /// <summary>
            /// 文本验证,[匹配数字],正则表达式
            /// 涵盖:正整数,最大9位
            /// </summary>
            public static string TextboxPositiveIntegerValidateRegex = @"^[1-9]{1}[0-9]{0,8}$";
        }

    关于第一个正则,解释和测试如下:

       Regex r = new Regex("^-?(?<decimalValue>0\.\d{1,9})?(?(decimalValue)|([1-9]{1}[0-9]{0,9}(\.\d+)?))$", RegexOptions.Singleline, Regex.InfiniteMatchTimeout);
                //匹配数字
                /*正则解释:
                ^    符号表示匹配必须是从第一个字符开头 
                第一部分:-?    表示负号出现0次或1次
                第二部分:(?<decimalValue>0\.\d{1,9})?  表示0.321 这种数字
                          (?<名称> 子表达式)分组构造,其中  decimalValue是名称,表示当前匹配的是小数,0\.\d{1,9}是表达式,表示0.3213这种,小数最多9位
                          最后的?表示出现0次或1次
                第三部分:(?(decimalValue)|([1-9]{1}[0-9]{0,9}(\.\d+)?))
                          (?(name)yes| no)替换构造,其中    decimalValue是名称,当不是小数的时候,匹配([1-9]{1}[0-9]{0,9}(\.\d+)?)
                          ([1-9]{1}[0-9]{0,9}(\.\d+)?),其中[1-9]{1}表示开头必须是1到9,[0-9]{0,9}中间可以是0到9,次数是0到9次,即最多9位   
    
                $       匹配必须出现在结尾 
                 */
                Debug.Assert(r.IsMatch("1")== true);//整数
                Debug.Assert(r.IsMatch("-1")== true);//整数
                Debug.Assert(r.IsMatch("10")== true);//带0整数
                Debug.Assert(r.IsMatch("-10")== true);//带0整数
                Debug.Assert(r.IsMatch("1010")== true);//多个带0
                Debug.Assert(r.IsMatch("-1010")== true);//多个带0
                Debug.Assert(r.IsMatch("1010.0321")== true);//小数
                Debug.Assert(r.IsMatch("-1010.0321")== true);//小数
                Debug.Assert(r.IsMatch("1010.123456789")== true);//多位小数
                Debug.Assert(r.IsMatch("-1010.123456789")== true);//多位小数
                Debug.Assert(r.IsMatch("0.1")== true);//0开头小数
                Debug.Assert(r.IsMatch("-0.1")== true);//0开头小数
                Debug.Assert(r.IsMatch("0.1123123")==true);
                Debug.Assert(r.IsMatch("-0.1123123")==true);
                Debug.Assert(r.IsMatch("0.143545") ==true);
                Debug.Assert(r.IsMatch("-0.143545") ==true);
                Debug.Assert(r.IsMatch("0.123456789") ==true);
                Debug.Assert(r.IsMatch("-0.123456789") ==true);
                Debug.Assert(r.IsMatch("-1.5")== true);
                Debug.Assert(r.IsMatch("123")== true);
                Debug.Assert(r.IsMatch("-999")== true);
                Debug.Assert(r.IsMatch("-0.5")== true);
    
                Debug.Assert(r.IsMatch("0.1234567890") == false); 
                Debug.Assert(r.IsMatch("-.5")==false);
                Debug.Assert(r.IsMatch("asdf")==false);
                Debug.Assert(r.IsMatch("002")==false);
                Debug.Assert(r.IsMatch("02")==false);
                Debug.Assert(r.IsMatch("02.6")==false);
                Debug.Assert(r.IsMatch("a123")== false);
                Debug.Assert(r.IsMatch("123 ")== false);
                Debug.Assert(r.IsMatch(" -23.5")== false);
    
                Debug.Assert(r.IsMatch("-01.5") == false);
                Debug.Assert(r.IsMatch("-001.5") == false);

    定义附加属性:

     public class TextBoxAttach
        {
            private static void SetTbBindingValidator(TextBox tb)
            {
                var regexString = GetValidateRegex(tb);
    
    
                var expression = tb.GetBindingExpression(TextBox.TextProperty);
                if (expression != null)
                {
                    var binding = expression.ParentBinding;
    
    
                    if (binding != null)
                    {
                        RegexValidationRule bindingRule = null;
                        foreach (var rule in binding.ValidationRules)
                        {
                            if (rule is RegexValidationRule regexRule)
                            {
                                bindingRule = regexRule;
                                break;
                            }
                        }
    
                        if (bindingRule != null)
                        {
                            bindingRule.RegexString = regexString;
                        }
                        else
                        {
                            binding.ValidationRules.Add(new RegexValidationRule { RegexString = regexString });
                        }
                    }
                }
            }
    
            /// <summary>
            /// 文本验证正则表达式
            /// </summary>
            public static readonly DependencyProperty ValidateRegexProperty =
                DependencyProperty.RegisterAttached("ValidateRegex", typeof(string), typeof(TextBoxAttach),
                    new PropertyMetadata("", OnValidateRegexChangeCallback));
    
            private static void OnValidateRegexChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (d is TextBox tb)
                {
                    if (!tb.IsInitialized)
                    {
                        tb.Initialized += delegate { SetTbBindingValidator(tb); };
                    }
                    else
                    {
                        SetTbBindingValidator(tb);
                    }
                }
            }
    
    
            public static string GetValidateRegex(DependencyObject obj)
            {
                return (string)obj.GetValue(ValidateRegexProperty);
            }
    
            public static void SetValidateRegex(DependencyObject obj, string value)
            {
                obj.SetValue(ValidateRegexProperty, value);
            }
    
    
    
    
    
            public static string GetTooltipPlaceholder(DependencyObject obj)
            {
                return (string)obj.GetValue(TooltipPlaceholderProperty);
            }
    
            public static void SetTooltipPlaceholder(DependencyObject obj, string value)
            {
                obj.SetValue(TooltipPlaceholderProperty, value);
            }
    
            /// <summary>
            /// 文本提示占位符,用于显示文本框的提示信息
            /// </summary>
            public static readonly DependencyProperty TooltipPlaceholderProperty =
                DependencyProperty.RegisterAttached("TooltipPlaceholder", typeof(string), typeof(TextBoxAttach), new PropertyMetadata(""));

    定义绑定验证规则:

     public class RegexValidationRule : ValidationRule
        {
            public override ValidationResult Validate(object value, CultureInfo cultureInfo)
            {
                var r = new Regex(RegexString);
                var isMatch = r.IsMatch(value.ToString());
                if(isMatch)
                {
                    return ValidationResult.ValidResult;
                }
    
                return new ValidationResult(false, "格式匹配出错,格式必须是数字");
            }
    
            public string RegexString { get; set; }
        }

    设置样式模板:

     <Style x:Key="TextBoxExtendBaseStyle"
                   TargetType="TextBox">
    
                <Setter Property="Padding"
                        Value="3"></Setter>
                <Setter Property="Validation.ErrorTemplate">
                    <Setter.Value>
                        <ControlTemplate>
                            <DockPanel>
                                <Border BorderBrush="Red"
                                        BorderThickness="1"
                                        DockPanel.Dock="Top">
                                    <AdornedElementPlaceholder />
                                </Border>
                                <TextBlock Foreground="Red"
                                           FontSize="12"
                                           DockPanel.Dock="Bottom"
                                           VerticalAlignment="Center"
                                           Text="{Binding [0].ErrorContent}"></TextBlock>
    
                            </DockPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate  TargetType="TextBox">
                            <Grid>
                                <Border x:Name="border"
                                        CornerRadius="3"
                                        BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}"
                                        Background="{TemplateBinding Background}"
                                        SnapsToDevicePixels="True" />
                                <TextBlock x:Name="Placeholder"
                                           Padding="1"
                                           Visibility="Collapsed"
                                           VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                           Margin="{TemplateBinding Padding}"
                                           HorizontalAlignment="Stretch"
                                           Foreground="#B0B0B0"
                                           Text="{Binding Path=(local:TextBoxAttach.TooltipPlaceholder), RelativeSource={RelativeSource TemplatedParent} }" />
                                <ScrollViewer Padding="{TemplateBinding Padding}"
                                              Margin="1"
                                              VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                              x:Name="PART_ContentHost"
                                              Focusable="false"
                                              HorizontalScrollBarVisibility="Hidden"
                                              VerticalScrollBarVisibility="Hidden" />
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled"
                                         Value="false">
                                    <Setter Property="Opacity"
                                            TargetName="border"
                                            Value="0.4" />
                                    <Setter Property="Opacity"
                                            TargetName="PART_ContentHost"
                                            Value="0.4" />
                                    <Setter Property="Opacity"
                                            TargetName="Placeholder"
                                            Value="0.4" />
                                </Trigger>
                                <Trigger Property="Text"
                                         Value="">
                                    <Setter Property="Visibility"
                                            Value="Visible"
                                            TargetName="Placeholder"></Setter>
                                </Trigger>
                                <Trigger Property="Text"
                                         Value="{x:Null}">
                                    <Setter Property="Visibility"
                                            Value="Visible"
                                            TargetName="Placeholder"></Setter>
                                </Trigger>
                                <Trigger Property="IsMouseOver"
                                         Value="true"
                                         SourceName="PART_ContentHost">
                                    <Setter Property="BorderBrush"
                                            TargetName="border"
                                            Value="{DynamicResource SecondaryBorderBrush}" />
                                </Trigger>
                                <Trigger Property="IsFocused"
                                         Value="true">
                                    <Setter Property="BorderBrush"
                                            TargetName="border"
                                            Value="{DynamicResource PrimaryBrush}" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

    控件使用时候,设置附加属性:

        <Grid>
            <TextBox HorizontalAlignment="Left"
                     VerticalContentAlignment="Center"
                     Height="60"
                     local:TextBoxAttach.ValidateRegex="{x:Static local:ValidateRegexs.TextboxNumericValidateRegex}"
                     local:TextBoxAttach.TooltipPlaceholder="请输入数字"
                     Style="{StaticResource TextBoxExtendBaseStyle}"
                     Margin="234,66,0,0"
                     TextWrapping="Wrap"
                     Text="{Binding TestString,UpdateSourceTrigger=PropertyChanged}"
                     FontSize="20"
                     VerticalAlignment="Top"
                     Width="220" />
    
        </Grid>

    效果:

    源码:下载

  • 相关阅读:
    SVN如何新建用户并分配权限
    Android性能测试工具Emmagee介绍
    Jquery 中的$(this) 和javascript中的this
    Django 的开始之路
    Python 100道题深入理解
    怎么使用jquery判断一个元素是否含有一个指定的类(class)
    windows下面安装Python和pip
    Waves:类Material Design 的圆形波浪(涟漪)点击特效插件
    Python 基础语法(三)
    Python 基础语法(四)
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/14537138.html
Copyright © 2020-2023  润新知