关闭

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

534人阅读 评论(0) 收藏 举报
分类:

在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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7141次
    • 积分:246
    • 等级:
    • 排名:千里之外
    • 原创:18篇
    • 转载:1篇
    • 译文:0篇
    • 评论:1条
    最新评论