我在我的实体类中使用IDataErrorInfo来验证实体对象。我有这个工作,并使用Validation.ErrorTemplate以我想要的每个控件的视觉样式显示任何验证问题。
例如TextBox控件我使用Validation.ErrorTemplate来装饰带有红色边框的TextBox和带有描述验证错误的工具提示的感叹号图标。
现在我想稍微软化一下UI的外观。当用户打开数据输入表单时,我想将所需字段的背景颜色更改为浅蓝色。我不想将Validation.ErrorTemplate与一个刺耳的红色边框和感叹号一起使用,直到他们至少在TextBox中输入一些无法验证的数据。
我想在实体类中保留验证和必需的字段逻辑,并保持UI声明。是否有我可以使用的模式或我需要关注此功能的其他类?我正在使用Validation.HasError上的TextBox样式中的DataTrigger和MultiValueConveter来检查我是否有验证错误,并且控件的值为null或空字符串,但没有很多运气,似乎应该是一种更简单的方法。
例如,我实现IDataErrorInfo的实体类返回验证错误,例如"电子邮件地址是必需的"如果Email属性为null或为空,则另一个验证错误,例如"电子邮件地址似乎没有正确格式化#34;当Email属性设置为不验证为有效电子邮件地址的字符串时。如果Email属性设置为null或为空,我想将Background设置为LightBlue。如果Email属性中有一个字符串,但它不是有效的电子邮件地址,我想显示Validation.ErrorTemplate。
EDIT
public class MyEntity : IDataErrorInfo
{
private static readonly IList<PropertyInfo> BindableProperties;
static MyEntity()
{
BindableProperties = typeof(MyEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite).ToList();
}
public string Email { get; set; }
public Boolean IsValid()
{
return BindableProperties.All(p => this[p.Name] == null);
}
#region // IDataErrorInfo Members
public string this[string name]
{
get
{
string message = null;
switch (name)
{
...
case "Email":
if (!string.IsNullOrEmpty(Email))
{
try
{
new System.Net.Mail.MailAddress(Email);
}
catch
{
message = "Email does not appear to be a valid email address.";
break;
}
}
else
{
message = "Email is required";
}
break;
...
}
return message;
}
}
public string Error
{
get { throw new NotImplementedException(); }
}
#endregion // IDataErrorInfo Members
}
public class MyEntity : IDataErrorInfo
{
private static readonly IList<PropertyInfo> BindableProperties;
static MyEntity()
{
BindableProperties = typeof(MyEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite).ToList();
}
public string Email { get; set; }
public Boolean IsValid()
{
return BindableProperties.All(p => this[p.Name] == null);
}
#region // IDataErrorInfo Members
public string this[string name]
{
get
{
string message = null;
switch (name)
{
...
case "Email":
if (!string.IsNullOrEmpty(Email))
{
try
{
new System.Net.Mail.MailAddress(Email);
}
catch
{
message = "Email does not appear to be a valid email address.";
break;
}
}
else
{
message = "Email is required";
}
break;
...
}
return message;
}
}
public string Error
{
get { throw new NotImplementedException(); }
}
#endregion // IDataErrorInfo Members
}
控制XAML
<TextBox Name="EmailTextBox" Text="{Binding MyEntity.Email, ValidatesOnDataErrors=True}"/>
<Button x:Name="SaveButton" Command="Save" Content="Save">
<Button.CommandBindings>
<CommandBinding Command="Save" Executed="Save_Executed" CanExecute="Save_CanExecute"/>
</Button.CommandBindings>
</Button>
代码背后
<TextBox Name="EmailTextBox" Text="{Binding MyEntity.Email, ValidatesOnDataErrors=True}"/>
<Button x:Name="SaveButton" Command="Save" Content="Save">
<Button.CommandBindings>
<CommandBinding Command="Save" Executed="Save_Executed" CanExecute="Save_CanExecute"/>
</Button.CommandBindings>
</Button>
答案 0 :(得分:0)
请为您的Entity.Here Employee是一个实体。
public class Employee : INotifyPropertyChanged,IDataErrorInfo
{
private static readonly IList<PropertyInfo> BindableProperties;
static Employee()
{
BindableProperties = typeof(Employee).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite).ToList();
}
string email;
public string Email
{
get { return email; }
set {
email = value;
Validate(true,"Email");
Notify("Email");
}
}
public Boolean IsValid()
{
return BindableProperties.All(p => Validate(false,p.Name));
}
bool Validate(bool addErrors, string propName)
{
string message = string.Empty;
switch (propName)
{
case "Email":
if (!string.IsNullOrEmpty(Email))
{
try
{
new System.Net.Mail.MailAddress(Email);
}
catch
{
message = "Email does not appear to be a valid email address.";
break;
}
}
else
{
message = "Email is required";
}
break;
}
if (addErrors)
AddOrRemoveError(propName, message);
return string.IsNullOrEmpty(message);
}
void AddError(string propertyName, string error)
{
if (!errors.ContainsKey(propertyName))
errors.Add(propertyName, error);
}
void RemoveError(string propertyName)
{
if (errors.ContainsKey(propertyName))
errors.Remove(propertyName);
}
void AddOrRemoveError(string propName,string message)
{
if (!string.IsNullOrEmpty(message))
AddError(propName, message);
else
RemoveError(message);
}
private Dictionary<string, string> errors = new Dictionary<string, string>();
public event PropertyChangedEventHandler PropertyChanged;
void Notify(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public string Error
{
get { throw new NotImplementedException(); }
}
public string this[string columnName]
{
get { if(errors.ContainsKey(columnName)) return errors[columnName]; else return null;}
}
}