DataAnnotations方法定义WPF输入异常祥解

在MVVM中,我们一般将前台xaml需绑定的变量统一写在ViewModel中,而对于数据的验证,也会在viewModel中进行处理:

这里详解DataAnnotations方法:

首先ViewModel需要引用System.ComponentModel.DataAnnotations,接下来我们需要为viewModel建立viewModelBase类,方便所有viewModel统一处理验证,

base类中可写的东西有很多,这边列出2个我们需要的方法:

    public class ViewModelBase : IDataErrorInfo
    {
        public string this[string columnName]
        {
            get
            {
                var validationResults = new List<ValidationResult>();
                if (Validator.TryValidateProperty(GetType().GetProperty(columnName).GetValue(this, null),
                                                  new ValidationContext(this, null, null) { MemberName = columnName },
                                                  validationResults))
                {
                    return null;
                }
                return validationResults.First().ErrorMessage;
            }
        }

        protected bool IsValid()
        {
            return Validator.TryValidateObject(
                this, new ValidationContext(this, null, null), new List<ValidationResult>(), true);
        }
    }
这样以后,我们就能在viewModel中进行相关验证了“:

    public class SampleViewModel : ViewModelBase
    {
        public int ID { get; set; }

        [Display(Name = "Condition Name")]
        [Required(ErrorMessageResourceName = ValidationErrorMessagesResourceNames.Required,
            ErrorMessageResourceType = typeof(ValidationErrorMessages))]
        [StringLength(30, ErrorMessageResourceName = ValidationErrorMessagesResourceNames.StringMaximumLength,
            ErrorMessageResourceType = typeof(ValidationErrorMessages))]
        public string Name { get; set; }
    }

提示的message可以自定义resource,而DataAnnotations
 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
        AllowMultiple = false)]
    public class StringValidate : ValidationAttribute
    {
         private static readonly Regex InvalidRegex 
             = new Regex(@"[^a-zA-Z0-9 -/:-@\[-\`\{-\~]");

        public StringValidate()
            : base(() => "Error string")
        {
        }

         public override bool IsValid(object value)
         {
             var s = Convert.ToString(value);

             if (string.IsNullOrEmpty(s)) return true;

             return !InvalidRegex.IsMatch(s);
         }
    }

最后我们的viewModel就能变成:

 public class SampleViewModel : ViewModelBase
    {
        public int ID { get; set; }

        [Display(Name = "Condition Name")]
        [Required(ErrorMessageResourceName = ValidationErrorMessagesResourceNames.Required,
            ErrorMessageResourceType = typeof(ValidationErrorMessages))]
        [StringLength(30, ErrorMessageResourceName = ValidationErrorMessagesResourceNames.StringMaximumLength,
            ErrorMessageResourceType = typeof(ValidationErrorMessages))]
        [StringValidate]
        public string Name { get; set; }
    }

即Name只限输入英语,数字,符号,别的全角字符一律不行。


最后,在xmal中定义以下style:

    <Style x:Key="TextBoxStyleBase" TargetType="TextBox">
        <Style.Triggers>
            <!-- Validation エラー時にエラー内容を ToolTip 表示する -->
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="ToolTip"
                        Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Mode=Self}}" />
            </Trigger>
        </Style.Triggers>
    </Style>

这里提示是用tooltip提示,当然还可以用adornedElementPlaceHolder这种旁边的修饰框

  <Style x:Key="ValidateTextBoxStyle" TargetType="TextBox">
                        <Style.Triggers>
                        <Trigger Property="Validation.HasError" Value="true">
                            <Setter Property="Validation.ErrorTemplate">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <DockPanel LastChildFill="True">
                                            <TextBlock DockPanel.Dock="Left" Background="Red" Foreground="White" FontSize="11" Height="17"
                                                       Width="Auto"
                                                       VerticalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" FontFamily="Arial" 
                                                 Text="{Binding ElementName=ErrorBox, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                            </TextBlock>
                                            <AdornedElementPlaceholder Name="ErrorBox" />
                                        </DockPanel>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                    </Style>

最后在binding的时候设置ValidatesOnDataErrors=true就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值