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

原创 2013年12月03日 14:24:55

在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就可以了

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

【WPF】MVVM模式下的输入校验(IDataErrorInfo + DataAnnotations)

【前言】 Windows Presentation Foundation (WPF) 具有一个丰富数据绑定系统。除了作为通过 Model-View-ViewModel (MVVM) 模式从支持逻辑和...

判断输入的自定义异常

  • 2011-05-03 20:24
  • 470B
  • 下载

WPF 自定义控件的依赖属性的绑定方法

首先一些人觉得WPF中前台的代码应该在前台创建,尽量不要在后台用代码创建。另外如果前台重复代码过多,编写起来非常繁琐而且修改更是头痛。因此使用用户控件的方法把经常使用的前台模块制作成控件,当然用法和普...
  • sunlyk
  • sunlyk
  • 2014-02-18 13:52
  • 4870

WPF自定义Popup窗口随动非顶层不屏蔽输入法

做小项目的时候用到了Popup,但是原生的Popup为最顶层页面,屏蔽输入法不说,还不会自动随窗口移动更新位置。网上方案有很多,这里整理下方便各位码农们使用,废话不多说,直接上干货! class Po...

java中自定义一个异常的方法

/* 因为项目中会出现特有的问题, 而这些问题并未被java所描述并封装对象。 所以对于这些特有的问题可以按照java的对问题封装的思想。 将特有的问题。进行自定义的异常封装。   自定义...

关于打包自定义标签,并导入项目使用时,出现java.lang.NoClassDefFoundError: JspException异常,解决方法和注意事项!

坑死我了啊!!!!事先不知道,还以为哪里出了bug,百度这个异常可能出现的原因,都没解决,最后百度关键字“打包自定义标签库 出现异常”出现的第一个链接才解决的,Stack Overflow上也有关于这...

wpf 异常处理

  • 2017-04-16 10:39
  • 174KB
  • 下载

判断TextBox输入的内容是否含有字母,若含有其他内容则抛出自定义异常

 判断TextBox输入的内容是否含有数字: 法一: //只能判断是否含有字母  foreach (char c in TextBox1.Text) {         if (cha...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)