标签:nap triggers lock dep view 负数 符号 小数 表达式
正则表达式验证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>
效果:
源码:下载
标签:nap triggers lock dep view 负数 符号 小数 表达式
原文地址:https://www.cnblogs.com/congqiandehoulai/p/14537138.html