我已经在我的模型上实现了INotifyDataErrorInfo。但我似乎不能在需要的时候使用它。例如。它不应该在启动时或在我键入时验证错误。仅当单击按钮(保存)时。
我目前在我的XAML中有这个:
<TextBox Text="{Binding Car.Model, ValidatesOnNotifyDataErrors=False, UpdateSourceTrigger=Explicit}"/>
在SaveCommand下的我的ViewModel中:
Car.Validate();
if (Car.HasErrors)
{
return;
}
//else save
我的模型看起来像这样:
Public class Car:ValidateModelBase
{
private string _model;
[Required (ErrorMessage ="This field is required")]
public string Model
{
get { return _model; }
set { _model= value; RaisePropertyChanged(); }
}
}
然后是我的ValidateModelBase实现:
public class ValidateModelBase: INotifyDataErrorInfo, INotifyPropertyChanged
{
private ConcurrentDictionary<string, List<string>> _errors =
new ConcurrentDictionary<string, List<string>>();
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName]string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
ValidateAsync();
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public void OnErrorsChanged(string propertyName)
{
var handler = ErrorsChanged;
if (handler != null)
handler(this, new DataErrorsChangedEventArgs(propertyName));
}
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
return null;
}
List<string> errorsForName;
_errors.TryGetValue(propertyName, out errorsForName);
return errorsForName;
}
public bool HasErrors
{
get { return _errors.Any(kv => kv.Value != null && kv.Value.Count > 0); }
}
public Task ValidateAsync()
{
return Task.Run(() => Validate());
}
private object _lock = new object();
public void Validate()
{
lock (_lock)
{
var validationContext = new ValidationContext(this, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(this, validationContext, validationResults, true);
foreach (var kv in _errors.ToList())
{
if (validationResults.All(r => r.MemberNames.All(m => m != kv.Key)))
{
List<string> outLi;
_errors.TryRemove(kv.Key, out outLi);
OnErrorsChanged(kv.Key);
}
}
var q = from r in validationResults
from m in r.MemberNames
group r by m into g
select g;
foreach (var prop in q)
{
var messages = prop.Select(r => r.ErrorMessage).ToList();
if (_errors.ContainsKey(prop.Key))
{
List<string> outLi;
_errors.TryRemove(prop.Key, out outLi);
}
_errors.TryAdd(prop.Key, messages);
OnErrorsChanged(prop.Key);
}
}
}
}
问题是它的工作正常,但当窗口打开时,文本框已经是红色的。我想让它在启动时忽略验证,只在我单击保存时验证。单击保存时,它将验证并查看是否有任何错误。当出现错误时,将设置验证(现在应标记为红色),并且窗口保持打开状态。我如何才能做到这一点。
发布于 2018-01-29 22:43:38
如果您的模型应该只在保存时验证,我会让您的模型实现IEditableObject
,并确保在进行更改之前调用BeginEdit
,并在提交这些更改(即保存)之前调用EndEdit
。
让基类跟踪它是否处于“编辑模式”,如果处于“编辑模式”,则禁止任何验证。当调用EndEdit
时,再次允许验证并触发ErrorsChanged
。如何处理CancelEdit
由您决定。
一些控件,如数据网格,具有对IEditableObject
的内置支持,并在开始编辑行时调用BeginEdit
,在提交行时调用EndEdit
。这是一个非常有用的界面。
https://stackoverflow.com/questions/48499407
复制相似问题