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数据验证(6)—— IDataErrorInfo + DataAnnotations

前面介绍过居于 IDataErrorInfo 接口的数据验证。利用 IDataErrorInfo 的好处是它可用于轻松地处理交叉耦合属性。但也具有一个很大的弊端:索引器的实现通常会导致较大的 swit...

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

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

WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性

WPF 显示验证错误的默认方式是在控件周围绘制红色边框。通常需要对此方法进行自定义,以通过其他方式来显示错误。而且,默认情况下不会显示与验证错误关联的错误消息。常见的要求是仅当存在验证错误时才在工具提...
  • hwt0101
  • hwt0101
  • 2013年02月18日 18:30
  • 9147

C# WPF 项目中无法使用Console输出时出现句柄无效的IO异常解决方法

如以下代码,重点看:ConsoleManager.Show()的位置注释即可; using System; using System.Collections.Generic; using Syst...

判断输入的自定义异常

  • 2011年05月03日 20:24
  • 470B
  • 下载

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

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

WPF通过异常来验证用户输入

在WPF中使用数据绑定,如果用户输入和绑定类型转换失败,控件就会显示出现错误的模板, 比如一个Textbox绑定到一个int 属性,如果用户输入一个string,那这个textbox就会显示错误模板...

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

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

【WPF】自定义控件:NumericBox 数字输入文本框

原文出处:http://m.blog.csdn.net/blog/yeqi3000/8920834 ///     /// 数字输入文本框     /// 创建者:Maximus     /...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DataAnnotations方法定义WPF输入异常祥解
举报原因:
原因补充:

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