码迷,mamicode.com
首页 > 数据库 > 详细

WPF 验证没有通过无法保存数据(非常好)+ 虚似数据库

时间:2014-11-01 00:53:54      阅读:474      评论:0      收藏:0      [点我收藏+]

标签:des   http   io   os   ar   for   sp   strong   数据   

Validation control with a single validation rule is easy, but what if we need to validate a control using different validation rules. This article tells how to achieve multiple validation on single control in an easy and systematic way.

Introduction

Implementing multiple validation rules on a single control is bit difficult but not impossible. Every form has one or more controls which required to be validation on different set of logic. Since this is a very basic dependency of code that every developer has to do, this tip is dedicated only to this.

It would be an easy task if we have set of multiple validation like required, numeric, minimum character length, folder exists, numeric range rule and we just apply one or more than one rule just by putting comma or | between the rules in our XAML file. To elaborate more, the issue lets see a situation.

Assume one textbox control value needs to be validated with the below conditions:

  1. It has to be a required field.
  2. It has to be a numeric field.
  3. It should be between ranges of 1 to 100.

Or:

  1. It has to be a required Field
  2. Input value should have minimum 3 characters.

Or:

  1. It has to be a required field.
  2. Input value should be a valid directory.

Now one way is to create a class and club all rules into one and then use that one rule, but isn‘t it is a time consuming job and difficult to manage at the later stage of project? Imagine how many combination of rules we will have to make and if there is any logic change, we need to go back and manage each rule with the new changes.

Background

Continue to my validation segment, previously I wrote a tip where I highlighted how to implement maximum length validation on controls, now I moved to other validation but with addition of how to implement multiple validation on the same control.

Using the Code

Would it be nice to have our XAML allow assigning these rules with some kind of separator and then XAML parser would handle this list of rules on the control.

Well yes, this is possible and I will show you in the below steps how we can achieve this.

Single Validation

 <TextBox x:Name="titleBox" MaxLength="100" Grid.Column="1" Margin="0,11,0,0" HorizontalAlignment="Stretch">
            <Binding
                Path="Book.Title"
                    ValidatesOnDataErrors="True"
                     UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <rules:RequiredRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox>

Multiple Validation

<TextBox Text="{binding:RuleBinding Path=Book.Pages, 
        ValidationList=RequiredRule|NumericRule|RangeRule,  MinValueRange=0, MaxValueRange=999,        UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True , Mode=TwoWay}"
        Grid.Column="1" Grid.Row="6" HorizontalAlignment="Stretch"/> 

First, we will introduce our two generic classes which would allow us to bind these multiple rules and then these rules would be set at run time.

  [MarkupExtensionReturnType(typeof(object))]
  public abstract class BindingDecoratorBase : MarkupExtension
  {
    /// <summary>
    /// The decorated binding class.
    /// 
    private Binding binding = new Binding();
 
  public override object ProvideValue(IServiceProvider provider)
    {
      //create a binding and associate it with the target
      return binding.ProvideValue(provider);
    }
 
protected virtual bool TryGetTargetItems(IServiceProvider provider, out DependencyObject target, out DependencyProperty dp)
    {
    }
}

Now our second class would be RuleBinding Class which will be inherited from our 1st class BindingDecoratorBase class. This class has an override of ProvideValue() method. In this method, we call the below RegisterRule() method:

public override object ProvideValue(IServiceProvider provider)
        {
 
            //In case multiple rules are bound then it would come like "Required|Numeric
            var validationRules = ValidationList.Split(new string[] { "|", }, StringSplitOptions.RemoveEmptyEntries);
 
            foreach (var rule in validationRules)
            {
                RegisterRule(rule);
            }
 

            //delegate binding creation etc. to the base class
            object val = base.ProvideValue(provider);
            return val;
        } .... 
 
private void RegisterRule(string ruleName)
        {
            ValidationRule rule;
            switch (ruleName)
            {
                case "RequiredRule":
                    {
                        rule = new RequiredRule();
                        Binding.ValidationRules.Add(rule);
                        break;
                    }
                case "RangeRule":
                    {
                        rule = new MinNumericRule() 
            { MinValue = MinValueRange, MaxValue = MaxValueRange};
                        Binding.ValidationRules.Add(rule);
                        break;
                    }
                case "NumericRule":
                    {
                        rule = new NumericRule();
                        Binding.ValidationRules.Add(rule);
                        break;
                    }
                case "NumericNotEmpty":
                    {
                        rule = new NumericNotEmptyRule();
                        Binding.ValidationRules.Add(rule);
                        break;
                    }
                case "FolderExistRule":
                    {
                        rule = new FolderExistRule();
                        Binding.ValidationRules.Add(rule);
                        break;
                    }
                case "MinLengthRule":
                    {
                        rule = new MinLengthRule();
                        Binding.ValidationRules.Add(rule);
                        break;
                    }
            }
        }

That‘s it, very simple implementation but very helpful and effective, when you would run this project you would find that tooltips are changing based on error for the same control.

bubuko.com,布布扣

Points of Interest

Working on WPF is fun and doing things in a simple way in WPF is like cherry on the cake. It is always important that we write code in a simple way so that it can be managed by other people in your absence.

Validation plays a very important role and eliminates possibilities of all those silly errors which are enough to annoy an end user. Every minute spent to create basic structure of validation is worth it and this leads a project to an exception free successful project and saves lots of productivity.

Hope you enjoyed reading this tip.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

WPF 验证没有通过无法保存数据(非常好)+ 虚似数据库

标签:des   http   io   os   ar   for   sp   strong   数据   

原文地址:http://www.cnblogs.com/qq247039968/p/4066272.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!