WPF 验证

ValidationRule 验证
Exception 验证
IDataErrorInfo 验证
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方法是我们要验证的规则。

代码:http://download.csdn.net/my/uploads

转载:http://www.cnblogs.com/dingli/archive/2012/09/10/2679076.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值