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

时间:2021-03-16 14:04:34   收藏:0   阅读:0

正则表达式验证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>

 

效果:

技术图片

 

 

技术图片

 

 

源码:下载

 

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!