当前位置: 首页 > 编程语言 > C#

INotifyDataErrorInfo和BoundException分享

时间:2023-04-11 00:29:40 C#

INotifyDataErrorInfo和BoundException我正在使用INotifyDataErrorInfo接口来实现一个通用的MVVM验证机制。我通过调用OnValidate而不是OnPropertyChanged来实现接口:验证(属性名称,值);在我生成验证错误的验证方法中,将它们添加到Dictionary并在发现或清除验证错误时引发ErrorsChanged事件:新列表{errorString};RaiseErrorsChanged(属性名称);}elseif(_validationErrors.ContainsKey(propertyName)){_validationErrors.Remove(propertyName);RaiseErrorsChanged(属性名称);HasErrors属性是通过查看错误字典来实现的:publicboolHasErrors{get{return_validationErrors.Any(kv=>kv.Value!=null&&kv.Value.Count>0);}}为了防止在存在验证错误时启用保存按钮-保存命令canExecuteMethod参见HasErrors属性:privateboolIsSaveEnabled(){returnHasErrors==false;一切正常,除了我遇到绑定错误的情况——如果绑定值是(例如)不是输入整数的整数-文本框的ErrorContent将更新为错误字符串:“无法转换值'something'”,但INotifyDataErrorInfo机制未更新。虽然视图中有错误,但HasErrors仍然为false,并且启用了Save。我想找到一种方法将绑定异常传播到INotifyDataErrorInfo机制,以便我可以:禁用“保存”按钮(必须)。将验证错误消息更改为更有意义的错误字符串(很好)。我试图在不向视图添加代码的情况下找到通用的MVVM解决方案。感谢您的帮助字符串int大小写不适用于MVVM,因为视图模型由于绑定异常而无法获取任何信息。我看到两种方法来获得您需要的验证:只需在视图模型中使用字符串属性,当您必须转到模型时,只需将字符串转换为模型类型。创建行为或“特殊”控件,以便视图中的输入始终“可转换”为您的视图模型类型。顺便说一句,我使用第二种方法是因为我不得不:)但第一种方法总是有效并且对我来说似乎更容易。在Binding表达式中设置ValidatesOnExceptions="true"。这是我找到的解决方案。它使InotifyDataErrorInfo在ViewModel中正常工作(当存在任何验证错误时-HasError为true),并且它允许从viewModel添加验证错误。除此之外,它不需要更改视图、绑定或转换器。解决方案包括:添加自定义验证规则-执行实际验证并在验证更改时引发事件的验证实体:classValidationEntity:ValidationRule{publicstringKey{get;放;}publicstringBaseName="Base";publicoverrideValidationResultValidate(objectvalue,System.Globalization.CultureInfocultureInfo){varfullPropertyName=BaseName+"."+键;ValidationEntry条目;varvalidationResult=newValidationResult(true,null);if((entry=ValidationManager.Instance.FindValidation(fullPropertyName))!=null){interrorNumber;字符串错误字符串;varstrValue=(值!=null)?value.ToString():string.Empty;if(entry.Validate(strValue,outerrorNumber,outerrorString)==false){validationResult=newValidationResult(false,errorString);}}if(OnValidationChanged!=null){OnValidationChanged(Key,validationResult);}返回验证结果;}公共事件ActionOnValidationChanged;活动文本框列表并向每个文本框绑定添加验证规则:这是用户控件库中的代码:privatevoidOnLoaded(objectsender,RoutedEventArgsroutedEventArgs){_textBoxes=FindAllTextBoxs(this);varvm=DataContextasViewModelBase;if(vm!=null)vm.UpdateAllValidationsEvent+=OnUpdateAllValidationsEvent;foreach(_textBoxes中的var文本框){varbinding=BindingOperations.GetBinding(textbox,TextBox.TextProperty);if(binding!=null){varproperty=binding.Path.Path;varvalidationEntity=newValidationEntity{Key=property};binding.ValidationRules.Add(validationEntity);validationEntity.ValidationChanged+=OnValidationChanged;}}}privateListFindAllTextBoxs(DependencyObjectfe){returnFindChildren(fe);}privateListFindChildren(DependencyObjectdependencyObject)whereT:DependencyObject{varitems=newList();if(dependencyObjectisT){items.Add(dependencyObjectasT);退换货品;}varcount=VisualTreeHelper.GetChildrenCount(dependencyObject);对于(vari=0;i(child);items.AddRange(child仁);}退换货品;}当ValidationChange事件发生时——视图被调用以通知验证错误:privatevoidOnValidationChanged(stringpropertyName,ValidationResultvalidationResult){varvm=DataContextasViewModelBase;if(vm!=null){if(validationResult.IsValid){vm.ClearValidationErrorFromView(propertyName);}else{vm.AddValidationErrorFromView(propertyName,validationResult.ErrorContentasstring);ViewModel基础保留了两个列表:当从视图中添加验证错误时-将_notifyvalidationErrors更新为空值(仅意味着存在验证错误),错误字符串不会添加到_notifyvalidationErrors如果我们将它添加到那里,我们将得到在文本框ErrorContent中验证错误字符串两次。验证错误字符串也被添加到_privateValidationErrors(因为我们希望能够将其保存在视图模型中)这是ViewModel顶部的代码:privatereadonlyDictionary>_notifyvalidationErrors=newDictionary>();privatereadonlyDictionary>_privateValidationErrors=newDictionary>();publicvoidAddValidationErrorFromView(stringpropertyName,stringerrorString){_notifyvalidationErrors[propertyName]=newList();//将错误添加到私有字典_privateValidationErrors[propertyName]=newList{errorString};RaiseErrorsChanged(属性名称);}publicvoidClearValidationErrorFromView(stringpropertyName){if(_notifyvalidationErrors.ContainsKey(propertyName)){_notifyvalidationErrors.Remove(propertyName);}if(_privateValidationErrors.ContainsKey(propertyName)){_privateValidationErrors.Remove(propertyName)Rarr(propertyName)Rarr};}INotifyDataErrorInfo在视图中的实现:publicboolHasErrors{get{return_notifyvalidationErrors.Any(kv=>kv.Value!=null);}}民众事件事件处理程序错误已更改;publicvoidRaiseErrorsChanged(stringpropertyName){varhandler=ErrorsChanged;如果(处理程序!=null)处理程序(这个,新的DataErrorsChangedEventArgs(propertyName));(propertyName,outerrorsForProperty);返回errorsForProperty;用户可以选择通过调用ViewModelBaseAddValidationError和ClearValidationError方法从视图中添加验证错误publicvoidAddValidationError(stringerrorString,[CallerMemberName]stringpropertyName=null){_notifyvalidationErrors[propertyName]=newList{errorString};RaiseErrorsChanged(属性名称);}publicvoidClearValidationError([CallerMemberName]stringpropertyNameif=null)ContainsKey(propertyName)){_notifyvalidationErrors.Remove(propertyName);RaiseErrorsChanged(属性名称);视图可以通过调用GetValidationErrors和GetValidationErrorsString方法从ViewModel库中获取所有当前验证错误的列表。以上就是C#学习教程分享的全部内容:INotifyDataErrorInfo和绑定异常。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注——publicListGetValidationErrors(){varerrors=newList();foreach(varkeyin_notifyvalidationErrors.Keys){errors.AddRange(_notifyvalidationErrors[key]);如果(_privateValidationErrors.ContainsKey(key)){errors.AddRange(_privateValidationErrors[key]);}}返回错误;}publicstringGetValidationErrorsString(){varerrors=GetValidationErrors();varsb=newStringBuilder();foreach(varerrorinerrors){sb.追加(“●”);某人。附加行(错误);返回某人。字符串();}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: