| Author |
Share Topic Topic Search Topic Options
|
mikewishart
Groupie
Joined: 26-Feb-2010
Location: Reno, NV
Posts: 49
|
Post Options
Quote Reply
Topic: Validate on button click? Posted: 26-Jul-2010 at 11:57am |
|
I was wondering if there's an easy way to validate an entity on a button click rather than setting up the verification engine to update as every property is changed (ala: Manager.VerifierEngine.DefaultVerifierOptions.ErrorNotificationMode = VerifierErrorNotificationMode.ThrowException).
If I have XAML like this: <TextBox Text="{Binding Employee.FirstName, Mode=Default, ValidatesOnExceptions=True}"/>
<Button Content="Validate" Command="{Binding BtnValidateClick}"/>
and in my viewmodel, I have a property and method: public static Employee Employee { get; set; }
public ICommand BtnValidateClick { get; set; } // this gets set to OnBtnValidateClick in the vm constructor public void OnBtnValidateClick(object parameter) { var result = Manager.VerifierEngine.Execute(Employee).Where(r => r.IsError || r.IsWarning); }
What can I do with the result to tell the entity to go throw errors on all the properties with failed verifiers? I'm thinking there's something simple I'm missing here.
Thanks!
|
 |
GregD
IdeaBlade
Joined: 09-May-2007
Posts: 374
|
Post Options
Quote Reply
Posted: 27-Jul-2010 at 10:53am |
|
Are you working in WPF or Silverlight?
|
 |
mikewishart
Groupie
Joined: 26-Feb-2010
Location: Reno, NV
Posts: 49
|
Post Options
Quote Reply
Posted: 27-Jul-2010 at 10:54am |
|
This is for WPF
Edited by mikewishart - 27-Jul-2010 at 11:01am
|
 |
GregD
IdeaBlade
Joined: 09-May-2007
Posts: 374
|
Post Options
Quote Reply
Posted: 27-Jul-2010 at 5:34pm |
|
The WPF UI machinery predates the INotifyDataErrorInfo interface (which is implemented by DevForce entities), so the WPF UI doesn't listen for the ErrorsChanged event that an entity raises when an error is added to its ValidationErrors collection. You'll need to wire up a handler yourself.
|
 |
mikewishart
Groupie
Joined: 26-Feb-2010
Location: Reno, NV
Posts: 49
|
Post Options
Quote Reply
Posted: 29-Jul-2010 at 7:37am |
|
Thanks Greg. I came up with two ways to do it in an injected base class.
In the interest of helping any other developers with the same question, here's one way. (It's not fun finding forum posts with "I figured it out," but no answer as to how.) This way clears the error until Verify() is called again. Bindings need to include ValidatesOnDataErrors=true.
public abstract partial class EntityBase : IDataErrorInfo { private Dictionary<string, string> _errorList; private Dictionary<string, string> ErrorList { get { return _errorList ?? (_errorList = new Dictionary<string, string>()); } } private bool _isVerifying;
/// <summary> /// Verify the specific entity, setting errors on properties not passing validation. /// </summary> /// <returns> /// True if the entity passes validation. False if there are errors. /// </returns> public bool Verify() { ErrorList.Clear();
var verifiers = verifierEngine.Execute(this) .Where(v => (v.ResultCode == VerifierResultCode.Error) || (v.ResultCode == VerifierResultCode.OkWarning)) .ToList();
_isVerifying = true; try { foreach (var verifierResult in verifiers) { var triggers = verifierResult.Verifier.TriggerLinks; foreach (var propertyName in triggers.Select(trigger => trigger.TriggerItem.MemberName)) { if (ErrorList.ContainsKey(propertyName)) ErrorList[propertyName] += Environment.NewLine + verifierResult.Message; else ErrorList.Add(propertyName, verifierResult.Message);
if (GetType().GetProperty(propertyName) != null) EntityAspect.ForcePropertyChanged(new PropertyChangedEventArgs(propertyName)); } } } finally { _isVerifying = false; }
return verifiers.Count == 0; }
/// <summary> /// Hide the error whenever the property is changed until Verify() is called again. /// </summary> protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (_isVerifying) return;
if (string.IsNullOrEmpty(e.PropertyName)) return;
if (ErrorList.ContainsKey(e.PropertyName)) ErrorList.Remove(e.PropertyName); }
public new string this[string propertyName] { get { return ErrorList.ContainsKey(propertyName) ? ErrorList[propertyName] : null; } }
public string Error { get { throw new NotImplementedException(); } } }
Edited by mikewishart - 03-Aug-2010 at 5:52am
|
 |
GregD
IdeaBlade
Joined: 09-May-2007
Posts: 374
|
Post Options
Quote Reply
Posted: 02-Aug-2010 at 11:36am |
|
Thanks very much for posting your solution, Mike!
|
 |
BringerOD
DevForce MVP
Joined: 27-Aug-2010
Location: USA
Posts: 35
|
Post Options
Quote Reply
Posted: 28-Aug-2010 at 11:05am |
Mike,
Thanks for the post. Is there a way to run the validation when the user leaves the field. Not just on the button click.
I tried it using an interceptor and it worked. I was hoping a global solution would be around. Maybe an interceptor that works on all fields and tried to verify after each set.
Bryan
|
 |
mikewishart
Groupie
Joined: 26-Feb-2010
Location: Reno, NV
Posts: 49
|
Post Options
Quote Reply
Posted: 31-Aug-2010 at 1:11pm |
|
If you set the default verifier option mode, this should happen.
Manager.VerifierEngine.DefaultVerifierOptions.ErrorNotificationMode = VerifierErrorNotificationMode.ThrowException
of course, you'll need to use ValidatesOnExceptions=true in your xaml.
|
 |
BringerOD
DevForce MVP
Joined: 27-Aug-2010
Location: USA
Posts: 35
|
Post Options
Quote Reply
Posted: 31-Aug-2010 at 1:20pm |
Mike,
Thanks that is the way to go for WPF currently.
Bryan
|
 |