silverlight Validation MVVM下用户提交数据验证捕获

转自http://www.cnblogs.com/HalfwayMonk/archive/2011/01/08/1930495.html

@jv9的数据验证系列文章:Silverlight实例教程Validation验证系列中已经详细介绍了silverlight下的各种数据验证的方法。我也看着这些文章学习过来的。

现在在实践MVVM,需要在MVVM下实现提交数据验证,一步一步来。

参考系列文章的第四篇,定义一个验证的基类实现:INotifyPropertyChanged和IDataErrorInfo。

public abstract class DataErrorInfoBase : INotifyPropertyChanged, IDataErrorInfo
{
#region INotifyPropertyChanged 成员

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged( string propertyName)
{
if ( this .PropertyChanged != null )
{
this .PropertyChanged( this , new PropertyChangedEventArgs(propertyName));
}
}
#endregion

#region IDataErrorInfo 成员

private string _dataError = string .Empty;
private Dictionary < string , string > _dataErrors = new Dictionary < string , string > ();

public string Error
{
get { return _dataError; }
}

public string this [ string columnName]
{
get
{
if (_dataErrors.ContainsKey(columnName))
return _dataErrors[columnName];
else
return null ;
}
}

#endregion
}

封装2个添加删除错误的方法:

public void AddError( string name, string error)
{
_dataErrors[name]
= error;
this .NotifyPropertyChanged(name);
}

public void RemoveError( string name)
{
if (_dataErrors.ContainsKey(name))
{
_dataErrors.Remove(name);
this .NotifyPropertyChanged(name);
}
}

定义一个简单的model类:person

public class Person : INotifyPropertyChanged
{
string _name;

public string Name
{
get { return _name; }
set
{
_name
= value;
this .NotifyPropertyChanged( " Name " );
}
}

int _age;

public int Age
{
get { return _age; }
set
{
_age
= value;
this .NotifyPropertyChanged( " Age " );
}
}

#region INotifyPropertyChanged 成员

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged( string propertyName)
{
if ( this .PropertyChanged != null )
{
this .PropertyChanged( this , new PropertyChangedEventArgs(propertyName));
}
}
#endregion

}

然后就是一个ViewModel类继承自DataErrorInfoBase的PersonViewModel,其中包括一个数据源persons,一个调用AddPerson方法的AddPersonCommand,最终的目的是执行AddPersonCommand的时候往persons里添加一个新的Person。

public class PersonViewModel : DataErrorInfoBase
{
public ObservableCollection < Person > Persons { get ; private set ; }

public PersonViewModel()
{
AddPersonCommand
= new Command( this .AddPerson);
Persons
= new ObservableCollection < Person > ();
Persons.Add(
new Person() { Name = " 张三 " , Age = 25 });
Persons.Add(
new Person() { Name = " 李四 " , Age = 35 });
Persons.Add(
new Person() { Name = " 王五 " , Age = 45 });
Persons.Add(
new Person() { Name = " 赵六 " , Age = 55 });
}

#region Validate

string _name;
int _age;

public string Name
{
get { return _name; }
set
{
_name
= value;
this .NotifyPropertyChanged( " Name " );
}
}

public int Age
{
get { return _age; }
set
{
_age
= value;
this .NotifyPropertyChanged( " Age " );
}
}

public ICommand AddPersonCommand { get ; private set ; }

private void AddPerson()
{
}
}

实现AddPerson方法:在添加Person之前先进行数据验证,如果验证通过则添加。ValidateData方法里分别执行了Name和Age的验证,如果有错误就调用基类的AddError方法添加错误并返回false,反之则调用RemoveError方法移除错误,返回true。  

private void AddPerson()
{
if ( this .ValidateData())
Persons.Add(
new Person() { Name = Name, Age = Age });
}

private bool ValidateData()
{
return ValidateName() & ValidateAge();
}

private bool ValidateName()
{
if ( string .IsNullOrEmpty(Name))
{
this .AddError( " Name " , " 名字不能为空 " );
return false ;
}
else
{
this .RemoveError( " Name " );
return true ;
}
}

private bool ValidateAge()
{
if (Age <= 0 )
{
this .AddError( " Age " , " 年龄需大于0 " );
return false ;
}
else
{
this .RemoveError( " Age " );
return true ;
}
}

下面是XAML代码的实现。一个实现数据源的DataGrid  

  < sdk:DataGrid Margin ="5" ItemsSource =" {Binding Persons} " />

添加Person页面:绑定的字段需定义ValidatesOnDataErrors=True,并把添加按钮的Command绑定到AddPersonCommand  

  < TextBlock Margin ="5" Text ="姓名" />
< TextBox Grid.Column ="1" Margin ="5" Text =" {Binding Name,Mode=TwoWay,ValidatesOnDataErrors=True} " />

< TextBlock Grid.Row ="1" Margin ="5" Text ="年龄" />
< TextBox Grid.Column ="1" Grid.Row ="1" Margin ="5" Text =" {Binding Age,Mode=TwoWay,ValidatesOnDataErrors=True} " />

< Button Grid.Row ="2" Grid.Column ="1" Content ="添加" Command =" {Binding AddPersonCommand} " />

页面和验证效果如下:

 

基本的验证已经实现了。只是对于每个属性都要写一个或多个验证方法实在是有点麻烦,让我们来改进下。

添加一套新的验证组合:

string _newName;
int _newAge;

[Required(ErrorMessage
= " 姓名必填 " )]
[Display(Name
= " 姓名 " )]
public string NewName
{
get { return _newName; }
set
{
_newName
= value;
this .NotifyPropertyChanged( " NewName " );
}
}

[Range(
1 , 100 , ErrorMessage = " 年龄需在1-100之间 " )]
[Display(Name
= " 年龄 " )]
public int NewAge
{
get { return _newAge; }
set
{
_newAge
= value;
this .NotifyPropertyChanged( " NewAge " );
}
}

public ICommand NewAddPersonCommand { get ; private set ; }

private void NewAddPerson()
{
if ( this .NewValidateData())
Persons.Add(
new Person() { Name = NewName, Age = NewAge });
}

我们在每个需要验证属性上添加了验证系列第三篇中的 DataAnnotation验证机制,但是我们不在set属性实现Validator.ValidateProperty方法,稍后再做。看看现在NewValidateData方法是怎么实现的。

public bool NewValidateData()
{
this .ClearError();
var results
= new List < ValidationResult > ();
if ( ! Validator.TryValidateObject( this , new ValidationContext( this , null , null ), results, true ))
{
foreach (var result in results)
{
this .AddError(result.MemberNames.First(), result.ErrorMessage);
}
return false ;
}
return true ;
}

public void ClearError()
{
var keys
= new string [_dataErrors.Count];
_dataErrors.Keys.CopyTo(keys,
0 );
foreach (var key in keys)
{
this .RemoveError(key);
}
}

在NewValidateData方法方法中先调用ClearError 方法清空原有的错误信息。然后再调用Validator.TryValidateObject 方法验证viewModel中所有需要验证的属性,捕获错误,再把错误信息添加到IDataErrorInfo接口中通知实现。看看新的xaml

  < sdk:Label Margin ="5" Target =" {Binding ElementName=name} " />
< TextBox x:Name ="name" Grid.Column ="1" Margin ="5" Text =" {Binding NewName,Mode=TwoWay,ValidatesOnDataErrors=True,NotifyOnValidationError=True} " />

< sdk:Label Grid.Row ="1" Margin ="5" Target =" {Binding ElementName=age} " />
< TextBox x:Name ="age" Grid.Column ="1" Grid.Row ="1" Margin ="5" Text =" {Binding NewAge,Mode=TwoWay,ValidatesOnDataErrors=True,NotifyOnValidationError=True} " />

< Button Grid.Row ="2" Grid.Column ="1" Content ="新的添加" Command =" {Binding NewAddPersonCommand} " />

这里使用label代替了textblock,label可以显示DisplayAttribute定义的信息。如果绑定属性定义了RequiredAttribute,那么Label会默认显示粗体。在实现了NotifyOnValidationError=True之后,如果验证错误,那么Label会显示红色。看看效果。

当然,可以把NewValidateData方法和ClearError方法移到基类封装,这样以后调用起来就更方便了。

个人觉得数据验证的关键还在于灵活组合应用,不要一个验证方法一条道走到黑。

如有问题,还请大家指正。

代码:SLValidation.rar

 
posted on 2012-04-10 16:59 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/archive/2012/04/10/2440870.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本火锅店点餐系统采用Java语言和Vue技术,框架采用SSM,搭配Mysql数据库,运行在Idea里,采用小程序模式。本火锅店点餐系统提供管理员、用户两种角色的服务。总的功能包括菜品的查询、菜品的购买、餐桌预定和订单管理。本系统可以帮助管理员更新菜品信息和管理订单信息,帮助用户实现在线的点餐方式,并可以实现餐桌预定。本系统采用成熟技术开发可以完成点餐管理的相关工作。 本系统的功能围绕用户、管理员两种权限设计。根据不同权限的不同需求设计出更符合用户要求的功能。本系统中管理员主要负责审核管理用户,发布分享新的菜品,审核用户的订餐信息和餐桌预定信息等,用户可以对需要的菜品进行购买、预定餐桌等。用户可以管理个人资料、查询菜品、在线点餐和预定餐桌、管理订单等,用户的个人资料是由管理员添加用户资料时产生,用户的订单内容由用户在购买菜品时产生,用户预定信息由用户在预定餐桌操作时产生。 本系统的功能设计为管理员、用户两部分。管理员为菜品管理、菜品分类管理、用户管理、订单管理等,用户的功能为查询菜品,在线点餐、预定餐桌、管理个人信息等。 管理员负责用户信息的删除和管理,用户的姓名和手机号都可以由管理员在此功能里看到。管理员可以对菜品的信息进行管理、审核。本功能可以实现菜品的定时更新和审核管理。本功能包括查询餐桌,也可以发布新的餐桌信息。管理员可以查询已预定的餐桌,并进行审核。管理员可以管理公告和系统的轮播图,可以安排活动。管理员可以对个人的资料进行修改和管理,管理员还可以在本功能里修改密码。管理员可以查询用户的订单,并完成菜品的安排。 当用户登录进系统后可以修改自己的资料,可以使自己信息的保持正确性。还可以修改密码。用户可以浏览所有的菜品,可以查看详细的菜品内容,也可以进行菜品的点餐。在本功能里用户可以进行点餐。用户可以浏览没有预定出去的餐桌,选择合适的餐桌可以进行预定。用户可以管理购物车里的菜品。用户可以管理自己的订单,在订单管理界面里也可以进行查询操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值