例如:
代码 MSDN 参考数据注释
在您的模型类中添加引用:
using System.ComponentModel.DataAnnotations
那么,只需要为您的属性添加以下内容即可。
[Required(ErrorMessage = "Email address is required")]
[EmailAddress(ErrorMessage = "Email Address is Invalid")]
public string Email
{
get { return GetValue(() => Email); }
set { SetValue(() => Email, value); }
}
完整示例已更新:
你的类应该使用一个基类PropertyChangedNotification
创建PropertyChangedNotification
类如下所示(在链接页面上可以找到它)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
namespace EmployeeApp.Notification
{
public abstract class PropertyChangedNotification : INotifyPropertyChanged, IDataErrorInfo
{
#region Fields
private readonly Dictionary<string, object> _values = new Dictionary<string, object>();
#endregion
#region Protected
protected void SetValue<T>(Expression<Func<T>> propertySelector, T value)
{
string propertyName = GetPropertyName(propertySelector);
SetValue<T>(propertyName, value);
}
protected void SetValue<T>(string propertyName, T value)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
_values[propertyName] = value;
NotifyPropertyChanged(propertyName);
}
protected T GetValue<T>(Expression<Func<T>> propertySelector)
{
string propertyName = GetPropertyName(propertySelector);
return GetValue<T>(propertyName);
}
protected T GetValue<T>(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
object value;
if (!_values.TryGetValue(propertyName, out value))
{
value = default(T);
_values.Add(propertyName, value);
}
return (T)value;
}
protected virtual string OnValidate(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
string error = string.Empty;
var value = GetValue(propertyName);
var results = new List<System.ComponentModel.DataAnnotations.ValidationResult>(1);
var result = Validator.TryValidateProperty(
value,
new ValidationContext(this, null, null)
{
MemberName = propertyName
},
results);
if (!result)
{
var validationResult = results.First();
error = validationResult.ErrorMessage;
}
return error;
}
#endregion
#region Change Notification
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
protected void NotifyPropertyChanged<T>(Expression<Func<T>> propertySelector)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
string propertyName = GetPropertyName(propertySelector);
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion // INotifyPropertyChanged Members
#region Data Validation
string IDataErrorInfo.Error
{
get
{
throw new NotSupportedException("IDataErrorInfo.Error is not supported, use IDataErrorInfo.this[propertyName] instead.");
}
}
string IDataErrorInfo.this[string propertyName]
{
get
{
return OnValidate(propertyName);
}
}
#endregion
#region Privates
private string GetPropertyName(LambdaExpression expression)
{
var memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
{
throw new InvalidOperationException();
}
return memberExpression.Member.Name;
}
private object GetValue(string propertyName)
{
object value;
if (!_values.TryGetValue(propertyName, out value))
{
var propertyDescriptor = TypeDescriptor.GetProperties(GetType()).Find(propertyName, false);
if (propertyDescriptor == null)
{
throw new ArgumentException("Invalid property name", propertyName);
}
value = propertyDescriptor.GetValue(this);
_values.Add(propertyName, value);
}
return value;
}
#endregion
#region Debugging
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // Debugging Aides
}
}
在您的视图中,您可以添加以下内容:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Name="txtEmail"
Text="{Binding Email, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True, NotifyOnValidationError=True}" Width="100">
</TextBox>
<TextBlock Grid.Column="1" Grid.Row="0"
Text="{Binding (Validation.Errors)[0].ErrorContent, ElementName=txtEmail}"
Foreground="Red" Margin="5,0,0,0"/>
</Grid>
关于按钮点击时的验证,只需实现命令并在那里发出通知即可。
点击时进行验证的更改。
视图。
<TextBox Grid.Column="0"
Name="txtTestValue" Text="{Binding MyTextValue, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" Width="100">
</TextBox>
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding (Validation.Errors)[0].ErrorContent, ElementName=txtTestValue}" Foreground="Red" Margin="5,0,0,0"/>
<Button Content="Validate" Command="{Binding ValidationCommand}">
</Button>
模型
ValidationCommand = new RelayCommand(ExecuteMyCommand,() => true);
....
public RelayCommand ValidationCommand
{
get;
private set;
}
private void ExecuteMyCommand()
{
OnValidate("MyTextValue");
}