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

Collapse | Copy Code
 <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

Collapse | Copy Code
<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.

Collapse | Copy Code
  [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:

Collapse | Copy Code
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.

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 验证没有通过无法保存数据(非常好)+ 虚似数据库的更多相关文章

  1. WPF MVVM(Caliburn.Micro) 数据验证

    书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model端验证,Model通过继承IDataErrorInfo接口来 ...

  2. WPF中退出时显示是否保存数据提示

    一.通过窗体中的按钮实现退出时数据保存提示 Xaml: <Grid> <TextBlock HorizontalAlignment="Left" Margin=& ...

  3. WPF XML序列化保存数据 支持Datagrid 显示/编辑/添加/删除数据

    XML序列化保存数据 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...

  4. 理解和使用WPF 验证机制

    博客 学院 下载 更多 写博客 发布Chat 登录注册 理解和使用WPF 验证机制 原创 2013年06月20日 11:15:37 7404 首先建立一个demo用以学习和实验WPF Data Val ...

  5. Docker最全教程——数据库容器化之持久保存数据(十一)

    上一节我们讲述了SQL Server容器化实践(注意,SQL Server现在也支持跨平台),本节将讲述如何持久保存数据,并且接下来将逐步讲解其他数据库(MySql.Redis.Mongodb等等)的 ...

  6. hibernate4无法保存数据

    hibernate4无法保存数据 author: hiu 以后都发文章我都备注一下作者了,hiu就是我了 红色字体更新日期:2014-07-08 初次使用hibernate4,使用getCurrent ...

  7. WPF获得PNG图片外观Path数据

    原文:WPF获得PNG图片外观Path数据        WPF开发界面的时候,用的最多的就是自定义控件模板,开发人员需要根据UI的设计,做出符合要求的自定义控件.但是在一些特殊情况下,UI的设计可能 ...

  8. 02-EF Core笔记之保存数据

    EF Core通过ChangeTracker跟踪需要写入数据库的更改,当需要保存数据时,调用DbContext的SaveChanges方法完成保存. 基本的添加.更新.删除操作示例如下: using ...

  9. EasyUI使用JSON保存数据

    目前来说,使用JSON保存数据比较方便,前台可以不用Test.aspx 页面,可以直接用Html页面,使用.aspx页面的弊端就不在这里熬述. 具体步骤如下: 1.新建一个Html页面,命名为Test ...

随机推荐

  1. UICollectionView中Cell左对齐 居中 右对齐 等间距------你想要的,这里都有

    支持靠左,居中,靠右,等间距对齐. 靠左等间距.png 居中等间距.png 靠右等间距.png #import <UIKit/UIKit.h> typedef NS_ENUM(NSInte ...

  2. 基于NIOS-II的示波器:PART2 界面动态显示功能

    本文所有的硬件基础以及工程参考来自魏坤示波仪,重新实现驱动并重构工程. version 0.2 界面动态显示功能 界面显示功能原理 显示波形有如下两个方案: 每一帧直接重绘显示界面,再显示下一帧图形 ...

  3. Seesion工作原理

    session的工作原理一.术语session 在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含义是相 ...

  4. 【beta】阶段 第七次 Scrum Meeting

    每日任务 1.本次会议为第七次 Meeting会议: 2.本次会议在下午14:45,课间休息时间在陆大楼召开,召开本次会议为10分钟. 一.今日站立式会议照片 二.每个人的工作 (有work item ...

  5. 201521123083《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...

  6. 201521123093 java 第八周总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 1.泛型简介:同一个代码可以被不同的对象重用 2.使用泛型的好处:允许 ...

  7. 201521044091 《java程序设计》第八周学习总结

    本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容.1.2 选做:收集你认为有用的代码片段 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1)1.1 实验 ...

  8. Java 第五周总结

    1. 本周学习总结 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 不能. ...

  9. 201521123006 《Java程序设计》第4周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 本周除了继承,我们还重点学习了多态. (1)多态性在于有相同的形态,却是不同的行为或者说是不 ...

  10. Python学习笔记008_类_对象_继承_组合_类相关的BIF

    # 对象 = 属性 + 方法>>> # Python中的类名约定以大写字母开始>>> # tt = Turtle() 这就是创建类实例的方法,其它语言用new ,它 ...