C# 使用IDataErrorInfo在验证期间启用禁用保存按钮
如何在使用C# 使用IDataErrorInfo在验证期间启用禁用保存按钮,c#,wpf,mvvm,light,C#,Wpf,Mvvm,Light,如何在使用IDataErrorInfo进行验证时禁用/启用按钮 我正在使用MVVM使用GalaSoft light框架。在我的模型类中,我实现了IDataErrorInfo来显示错误消息 public string this[string columnName] { get { Result = null; if (columnName == "FirstName") { if (String.IsNullO
IDataErrorInfo
进行验证时禁用/启用按钮
我正在使用MVVM
使用GalaSoft light框架。在我的模型类中,我实现了IDataErrorInfo
来显示错误消息
public string this[string columnName]
{
get
{
Result = null;
if (columnName == "FirstName")
{
if (String.IsNullOrEmpty(FirstName))
{
Result = "Please enter first name";
}
}
else if (columnName == "LastName")
{
if (String.IsNullOrEmpty(LastName))
{
Result = "Please enter last name";
}
}
else if (columnName == "Address")
{
if (String.IsNullOrEmpty(Address))
{
Result = "Please enter Address";
}
}
else if (columnName == "City")
{
if (String.IsNullOrEmpty(City))
{
Result = "Please enter city";
}
}
else if (columnName == "State")
{
if (State == "Select")
{
Result = "Please select state";
}
}
else if (columnName == "Zip")
{
if (String.IsNullOrEmpty(Zip))
{
Result = "Please enter zip";
}
else if (Zip.Length < 6)
{
Result = "Zip's length has to be at least 6 digits!";
}
else
{
bool zipNumber = Regex.IsMatch(Zip, @"^[0-9]*$");
if (zipNumber == false)
{
Result = "Please enter only digits in zip";
}
}
}
else if (columnName == "IsValid")
{
Result = true.ToString();
}
return Result;
}
}
public string此[string columnName]
{
得到
{
结果=空;
如果(columnName==“FirstName”)
{
if(String.IsNullOrEmpty(FirstName))
{
结果=“请输入名字”;
}
}
else if(columnName==“LastName”)
{
if(String.IsNullOrEmpty(LastName))
{
结果=“请输入姓氏”;
}
}
else if(columnName==“地址”)
{
if(String.IsNullOrEmpty(Address))
{
结果=“请输入地址”;
}
}
else if(columnName==“城市”)
{
if(String.IsNullOrEmpty(城市))
{
结果=“请输入城市”;
}
}
else if(columnName==“State”)
{
如果(状态=“选择”)
{
结果=“请选择状态”;
}
}
else if(columnName==“Zip”)
{
if(String.IsNullOrEmpty(Zip))
{
Result=“请输入zip”;
}
否则如果(拉链长度<6)
{
结果=“Zip的长度必须至少为6位!”;
}
其他的
{
boolzipnumber=Regex.IsMatch(Zip,@“^[0-9]*$”;
if(zipNumber==false)
{
结果=“请仅在zip中输入数字”;
}
}
}
else if(columnName==“IsValid”)
{
结果=true.ToString();
}
返回结果;
}
}
截图:
如何禁用/启用保存按钮。好心的建议
谢谢您可以添加一个布尔属性,然后在Validation方法的末尾保存并设置它。将IsEnabled从按钮绑定到IsValid。 像这样的事情:
public bool CanSave
{
get{ return canSave; }
set{ canSave = value; RaisePropertyChanged( "CanSave" ); }
}
private bool canSave;
public string this[string columnName]
{
//....
CanSave = Result == String.Empty;
}
//xaml
<Button IsEnabled={Binding Path=CanSave}>Save</Button>
public bool可以保存
{
获取{return canSave;}
设置{canSave=value;RaisePropertyChanged(“canSave”);}
}
私人布尔可以节省;
公共字符串此[string columnName]
{
//....
CanSave=Result==String.Empty;
}
//xaml
拯救
这样做的目的是在模型中创建以下方法:
static readonly string[] ValidatedProperties =
{
"Foo",
"Bar"
};
/// <summary>
/// Returns true if this object has no validation errors.
/// </summary>
public bool IsValid
{
get
{
foreach (string property in ValidatedProperties)
{
if (GetValidationError(property) != null) // there is an error
return false;
}
return true;
}
}
private string GetValidationError(string propertyName)
{
string error = null;
switch (propertyName)
{
case "Foo":
error = this.ValidateFoo();
break;
case "Bar":
error = this.ValidateBar();
break;
default:
error = null;
throw new Exception("Unexpected property being validated on Service");
}
return error;
}
/// <summary>
/// Checks if all parameters on the Model are valid and ready to be saved
/// </summary>
protected bool CanSave
{
get
{
return modelOfThisVM.IsValid;
}
}
最后,如果使用的是RelayCommand
,则可以将命令的谓词设置为CanSave
属性,视图将自动启用或禁用该按钮。在ViewModel中:
/// <summary>
/// Saves changes Command
/// </summary>
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
_saveCommand = new RelayCommand(param => this.SaveChanges(), param => this.CanSave);
return _saveCommand;
}
}
//
///“保存更改”命令
///
公共ICommand SaveCommand
{
得到
{
如果(_saveCommand==null)
_saveCommand=newrelaycommand(param=>this.SaveChanges(),param=>this.CanSave);
返回_saveCommand;
}
}
并且认为:
<Button Content="Save" Command="{Binding Path=SaveCommand}"/>
就这样
PS:如果你还没有读过Josh Smith的文章,它将改变你的生活。以下是我使用IDataErrorInfo接口、ValidationErrors字典和MVVM Light消息系统组合的方法。直截了当,工作起来很有魅力: 模型类
public Dictionary<string, string> ValidationErrors = new Dictionary<string, string>();
public string this[string columnName]
{
get
{
// Remove Property error from ValidationErrors prior to any validation
ValidationErrors.Remove(propertyName);
//----------------------------------------
string Result = null;
if (columnName == "FirstName")
{
if (String.IsNullOrEmpty(FirstName))
{
// Add Property error to ValidationErrors Dic
ValidationErrors[propertyName] = Result = "Please enter first name";
//----------------------------------------
}
}
else if (columnName == "LastName")
{
if (String.IsNullOrEmpty(LastName))
{
// Add Property error to ValidationErrors Dic
ValidationErrors[propertyName] = Result = "Please enter last name";
//----------------------------------------
}
}
// Send MVVM-Light message and receive it in the Code Behind or VM
Messenger.Default.Send<PersonInfoMsg>(new PersonInfoMsg());
//----------------------------------------
return Result;
}
}
public Dictionary ValidationErrors=new Dictionary();
公共字符串此[string columnName]
{
得到
{
//在进行任何验证之前,从ValidationErrors中删除属性错误
ValidationErrors.Remove(propertyName);
//----------------------------------------
字符串结果=null;
如果(columnName==“FirstName”)
{
if(String.IsNullOrEmpty(FirstName))
{
//将属性错误添加到ValidationErrors Dic
ValidationErrors[propertyName]=Result=“请输入名字”;
//----------------------------------------
}
}
else if(columnName==“LastName”)
{
if(String.IsNullOrEmpty(LastName))
{
//将属性错误添加到ValidationErrors Dic
ValidationErrors[propertyName]=结果=“请输入姓氏”;
//----------------------------------------
}
}
//发送MVVM Light消息并在代码隐藏或VM中接收
senger.Default.Send(newPersonInfo());
//----------------------------------------
返回结果;
}
}
查看隐藏代码
public partial class PersonInfoView : UserControl
{
public PersonInfoView()
{
InitializeComponent();
Messenger.Default.Register<PersonInfoMsg>(this, OnErrorMsg);
}
private void OnErrorMsg(PersonInfoMsg)
{
// In case of DataGrid validation
foreach (PersonInfoModel p in GridName.ItemsSource)
{
if (p.ValidationErrors.Count == 0)
SaveBtn.IsEnabled = true;
else
SaveBtn.IsEnabled = false;
}
}
}
公共部分类PersonInfo视图:UserControl
{
公共PersonInfo视图()
{
初始化组件();
Messenger.Default.Register(这个,onerrormg);
}
private void OnErrorMsg(PersonInfo消息)
{
//在DataGrid验证的情况下
foreach(GridName.ItemsSource中的PersonInfo模型p)
{
if(p.ValidationErrors.Count==0)
SaveBtn.IsEnabled=true;
其他的
SaveBtn.IsEnabled=false;
}
}
}
如果您使用IDataErrorInfo
这实际上比接受的答案要好得多。如果您只是像我现在这样使用验证规则属性,您可能必须使用接受的答案:)如果存在多个验证,则不工作。。。此[string columnName]是按属性调用的。因此,如果prop1无效,而prop2有效,则CanSave设置为true。@Petervankem该部分位于/..
中:每次调用函数时,结果必须基于先前的结果重新计算。。是的,这是可能的。然而,我认为这太冒险/复杂了。我选择实现@PieterMüller的解决方案。这不是将验证逻辑放在模型中的好方法,因为验证逻辑可能会在不同的场景中发生变化。为简单起见,它可以是public bool IsValid=>ValidatedProperties.All(p=>GetValid