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. ELM极限学习机

    极限学习机(Extreme Learning Machine) ELM,是由黄广斌提出来的求解神经网络算法.ELM最大的特点是对于传统的神经网络,尤其是单隐层前馈神经网络(SLFNs),ELM比传统的 ...

  2. 09 Linear Regression

    线性回归假设 错误衡量/代价函数---均方误差 最小化样本内代价函数 只有满秩方阵才有逆矩阵 线性回归算法 线性回归算法是隐式迭代的 线性回归算法泛化可能的保证 线性分类是近似求解,线性回归是解析求解 ...

  3. 误删libc.os.6共享库的解决办法

    在我们使用系统的过程中,要注意各个共享库的使用,万一不小心删掉了什么,就可能出现各种问题.如果你把libc.os.6删掉了,那可就悲剧了,因为你的大部分命令都不能够正常使用了(╥╯^╰╥) 接下来呢, ...

  4. MongoDB学习之路(三)

    数据库 一个MongoDB可以建立多个数据库. MongoDB的默认数据库为"db",该数据库存储在data目录中. MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自 ...

  5. 201521123102 《Java程序设计》第3周学习总结

    1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面作 ...

  6. HTML基础入门

    1.什么是HTML 2.HTML文件结构 3.HTML文档 4.HTML标签 1.什么是HTML 首先,HTML是一种语言,是用来描述网页的语言 HTML 指的是超文本标记语言 (Hyper Text ...

  7. Servlet 3.0 使用注解配置URl提示404错误

    我的环境是  Eclipse oxygen + Servlet 3.0 因为3.0已经开始使用注解了 之前我都是配置listenner 还有Servlet mapping  在 web.xml 中 就 ...

  8. 参加Java培训你必须知道的五点真相!

    相信大家都有过到招聘网站投简历.找工作的经历.当一份份简历发出三天后,左等右等连一个电话没有等来,心中不免有些失落,有些焦虑.这个时侯,很多培训机构就会纷纷给你打电话以各种名义让你参加各种IT技能培训 ...

  9. Piggy Back_KEY

    Piggy Back (piggyback.pas/c/cpp) [问题描述] Bessie 和她的姐姐 Elsie 在不同的田块吃草,晚上她们都返回牛棚休息.作为聪明的奶牛,她们想设计一个方案使得步 ...

  10. oracle存储过程中is和as区别

    在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别:在视图(VIEW)中只能用AS不能用IS:在游标(CURSOR)中只能用IS不能用AS.