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

 

时间: 2024-09-21 06:59:47

silverlight Validation MVVM下用户提交数据验证捕获的相关文章

Silverlight实例教程 - Validation用户提交数据验证捕获

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

请教 s2sh下 批量提交数据的话action和service该怎么写

问题描述 今天的面试被问道 当前台页面需要批量提交数据的话 action里面应该怎么写 service层该做什么工作来处理批量数据....小弟求指教 问题补充:hu437 写道 解决方案 恩 知道了就好解决方案二:要看你想批量数据得类型跟表里面的关系了关系都是独立的话 不好办 如果不是独立的 就搞个数组把这些数据全部存在数组当中然后他说在service层处理的话 看怎么处理了反正第一步就先遍历出来然后在调用DAO里面写好的处理方法就OK了可是做了项目要看情况希望能够帮助你解决方案三:这个批量是个

ajax无刷新保存用户提交数据

们继续我们的修改用户资料,修改用户资料,首先第一个需要我们做的就是,先显示出所有的用户信息. 最新的网站结构,下面用箭头标注的就是今天新增加了几个文件. ShowStudent.htm增加如下代码. <link href="Style/BaseStyle.css教程" rel="stylesheet" type="text/css" /> <script src="Js/BaseJs.js" type=&qu

Silverlight实例教程 - Validation数据验证基础属性和事件

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

Silverlight实例教程 - Validation数据验证开篇

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation 数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation 服务器端异步数据验证 Silverlight

Silverlight实例教程 - Validation客户端同步数据验证

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

Silverlight实例教程 - Validation服务器端异步数据验证

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

Silverlight实例教程 Datagrid,Dataform数据验证和ValidationSummary

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例