六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 285|回复: 0

WPF 验证

[复制链接]

升级  33.33%

30

主题

30

主题

30

主题

秀才

Rank: 2

积分
100
 楼主| 发表于 2013-1-3 15:35:27 | 显示全部楼层 |阅读模式
<div id="cnblogs_post_body">目录:

1、ValidationRule 验证
2、Exception 验证
3、IDataErrorInfo 验证
4、Custom Control 验证

1、ValidationRule 验证

ValidationRule:是通过ValidationRule中的的Validate方法来验证我们绑定的属性。所以我们的用法是继承ValidationRule,重写他的Validate方法。示例
public class RequiredRule : ValidationRule    {        public override ValidationResult Validate(object value, CultureInfo cultureInfo)        {            if (value == null)                return new ValidationResult(false, "不能为空值!");            if (string.IsNullOrEmpty(value.ToString()))                return new ValidationResult(false, "不能为空字符串!");            return new ValidationResult(true, null);        }    }而XAML中需要把错误信息显示出来。
<Window.Resources>        <ControlTemplate x:Key="ErrorTemplate">            <Border BorderBrush="Red" BorderThickness="1">                <AdornedElementPlaceholder/>            </Border>        </ControlTemplate>        <Style TargetType="TextBox">            <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}">            </Setter>            <Style.Triggers>                <Trigger Property="Validation.HasError" Value="True">                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>                </Trigger>            </Style.Triggers>        </Style>    </Window.Resources>    <StackPanel>        <TextBlock Text="姓名"/>        <TextBox>            <TextBox.Text>                <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">                    <Binding.ValidationRules>                        <ValidationRules:RequiredRule/>                    </Binding.ValidationRules>                </Binding>            </TextBox.Text>        </TextBox>        <TextBlock Text="年龄"/>        <TextBox >            <TextBox.Text>                <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">                    <Binding.ValidationRules>                        <ValidationRules:GreaterThanRule Number="10"/>                    </Binding.ValidationRules>                </Binding>            </TextBox.Text>        </TextBox>    </StackPanel>这样显示的错误信息就会以 ToolTip和红色边框的形式显示出来。但这边如果又在TextBox里面设置ToolTip那么就会优先选择TextBox里的,也就是Style中的ToolTip遇到错误信息是不会显示出来的,而是显示TextBox中的ToolTip。所以我们可以改善一下显示的模版来解决这个问题。
<ControlTemplate x:Key="ErrorTemplate">            <DockPanel LastChildFill="true">                <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"                            ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">                    <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">                    </TextBlock>                </Border>                <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >                    <Border BorderBrush="red" BorderThickness="1" />                </AdornedElementPlaceholder>            </DockPanel>        </ControlTemplate>2、Exception 验证

Exception :我们xaml中绑定的对象是属性。所以Exception验证,就是通过属性的改变来判断是否正常。如:
public int Age        {            get { return _age; }            set            {                if (value > 200)                {                    throw new Exception("年龄不能大于200");                }                _age = value;            }        }同样跑出的异常在Xaml中也要显示下。XAML同上。这种方式就会破坏POCO的设计原则。
3、IDataErrorInfo 验证

IDataErrorInfo:这个验证是通过我们的实体对象继承IDataErrorInfo来实现的。这里声明的this索引器来访问类的成员。
public class BaseDataErrorInfo : IDataErrorInfo    {        private string _error;        public string this[string columnName]        {            get { return GetErrorFor(columnName); }        }        public string Error        {            get { return _error; }            set { _error = value; }        }        public virtual string GetErrorFor(string columnName)        {            return string.Empty;        }    }public class Person : BaseDataErrorInfo    {        public string Name { get; set; }        public override string GetErrorFor(string columnName)        {            if (columnName == "Name")                if (string.IsNullOrEmpty(Name))                    return "Name 不能为空";            return base.GetErrorFor(columnName);        }    }XAML同上。
4、Custom Control 验证

这里我即不想污染实体类,又想实现一个通用的Validate。我想通过我xaml绑定的属性和它所属的控件。来显示ToolTip。
  public abstract class Validator : FrameworkElement    {        static Validator()        {            DefaultStyleKeyProperty.OverrideMetadata(typeof(Validator), new FrameworkPropertyMetadata(typeof(Validator)));        }        public virtual string ErrorMessage { get { return string.Empty; } }        public abstract bool InitialValidation();        public FrameworkElement ElementName        {            get { return (FrameworkElement)GetValue(ElementNameProperty); }            set { SetValue(ElementNameProperty, value); }        }        // Using a DependencyProperty as the backing store for ElementName.  This enables animation, styling, binding, etc...        public static readonly DependencyProperty ElementNameProperty =            DependencyProperty.Register("ElementName", typeof(FrameworkElement), typeof(Validator), new PropertyMetadata(null));        public object Source        {            get { return (object)GetValue(SourceProperty); }            set { SetValue(SourceProperty, value); }        }        // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...        public static readonly DependencyProperty SourceProperty =            DependencyProperty.Register("Source", typeof(object), typeof(Validator), new UIPropertyMetadata(new PropertyChangedCallback(ValidPropertyPropertyChanged)));        private static void ValidPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)        {            var validator = d as Validator;            if (validator != null)                validator.SetSourceFromProperty();            if (string.IsNullOrEmpty(e.NewValue.ToString()))            {                if (validator != null)                {                    validator.IsValid = validator.InitialValidation();                    if (validator.ElementName.DataContext != null)                        validator.ShowToolTip();                    validator.IsValid = false;                }            }        }        private void ShowToolTip()        {            if (IsValid)            {                timer = new DispatcherTimer();                timer.Interval = TimeSpan.FromSeconds(1.5);                _toolTip = new ToolTip();                _toolTip.StaysOpen = true;                _toolTip.PlacementTarget = ElementName;                _toolTip.Placement = PlacementMode.Right;                _toolTip.Content = ErrorMessage;                _toolTip.IsOpen = true;                timer.Tick += (sender, args) =>                                  {                                      _toolTip.IsOpen = false;                                      timer.Stop();                                  };                timer.Start();            }        }        private void SetSourceFromProperty()        {            var expression = this.GetBindingExpression(SourceProperty);            if (expression != null && this.ElementName == null)                this.SetValue(Validator.ElementNameProperty, expression.DataItem as FrameworkElement);        }        private ToolTip _toolTip;        private DispatcherTimer timer;        public bool IsValid { get; set; }    }这是一个简单的Validate基类。提供思想。功能不完善。
然后继承这个Validator
public class RequiredValidator : Validator    {        public override string ErrorMessage { get { return "不能为空值"; } }        public override bool InitialValidation()        {            if (Source == null)                return false;            return string.IsNullOrEmpty(Source.ToString());        }    }这里ErrorMessage是显示错误信息。
InitialValidation方法是我们要验证的规则。

代码
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表