.net - Mimicking Validation Behaviour without Validation -
we have several data objects in our application wind bound grids. have them implementing idataerrorinfo interface, adding error messages properties, see rowheader change style , datagridcells gain red border. , good.
we have additional requirement rather merely having errors, have errors , warnings. warnings identical errors except should produce yellow border instead of red one.
we created new interface, idatawarninginfo, based on idataerrorinfo. works fine. can access @ runtime, have rowvalidatiionrules that able access it, , set yellow row header instead of red one, appropriate tooltip, etc. i'm missing ability set given cell's border yellow, on basis databound property property has warning message.
i retrieve warning message passing name of databound property interface; suspect under hood, validation code doing that. i'm missing how in xaml. specifically, think need apply style cell, style contains datatrigger somehow passes object name of databound property, , if result different null, applies few setters cell.
does know how achieve this?
i have class attached property dependencyproperty validate. uses dependencypropertydescriptor attach event dependencyproperty's change event.
then when changes, looks through bindings, runs validation rules , sets validation errors property without commiting binding.
public static class validatingcontrolbehavior { /// <summary> /// defines validatingproperty dependency property. /// </summary> public static readonly dependencyproperty validatingpropertyproperty = dependencyproperty.registerattached("validatingproperty", typeof(dependencyproperty), typeof(validatingcontrolbehavior), new propertymetadata(validatingcontrolbehavior.validatingpropertyproperty_propertychanged)); /// <summary> /// attaches event. /// </summary> /// <param name="control">the control.</param> /// <param name="dependencyproperty">the dependency property.</param> private static void attachevent(control control, dependencyproperty dependencyproperty) { dependencypropertydescriptor.fromproperty(dependencyproperty, typeof(control)).addvaluechanged(control, validatingcontrolbehavior.control_propertychanged); control.forcevalidation(dependencyproperty); } /// <summary> /// handles propertychanged event of control control. /// </summary> /// <param name="sender">the source of event.</param> /// <param name="e">the <see cref="system.eventargs"/> instance containing event data.</param> private static void control_propertychanged(object sender, eventargs e) { control control = (control)sender; control.forcevalidation(validatingcontrolbehavior.getvalidatingproperty(control)); } /// <summary> /// forces validation. /// </summary> /// <param name="dependencyobject">the dependency object.</param> /// <param name="dependencyproperty">the dependency property.</param> private static void forcevalidation(this dependencyobject dependencyobject, dependencyproperty dependencyproperty) { bindingexpressionbase expression = bindingoperations.getbindingexpressionbase(dependencyobject, dependencyproperty); collection<validationrule> validationrules; if (expression != null) { multibinding multibinding; binding binding = expression.parentbindingbase binding; if (binding != null) { validationrules = binding.validationrules; } else if ((multibinding = expression.parentbindingbase multibinding) != null) { validationrules = multibinding.validationrules; } else { return; } (int = 0; < validationrules.count; i++) { validationrule rule = validationrules[i]; validationresult result = rule.validate(dependencyobject.getvalue(dependencyproperty), cultureinfo.currentculture); if (!result.isvalid) { validation.markinvalid(expression, new validationerror(rule, expression.parentbindingbase, result.errorcontent, null)); return; } } validation.clearinvalid(expression); } } /// <summary> /// detaches event. /// </summary> /// <param name="control">the control.</param> /// <param name="dependencyproperty">the dependency property.</param> private static void detachevent(control control, dependencyproperty dependencyproperty) { dependencypropertydescriptor.fromproperty(dependencyproperty, typeof(control)).removevaluechanged(control, validatingcontrolbehavior.control_propertychanged); } /// <summary> /// handles propertychanged event of validatingpropertyproperty control. /// </summary> /// <param name="d">the source of event.</param> /// <param name="e">the <see cref="system.windows.dependencypropertychangedeventargs"/> instance containing event data.</param> private static void validatingpropertyproperty_propertychanged(dependencyobject d, dependencypropertychangedeventargs e) { control control = d control; if (control != null) { if (e.oldvalue != null) { validatingcontrolbehavior.detachevent(control, (dependencyproperty)e.oldvalue); } if (e.newvalue != null) { validatingcontrolbehavior.attachevent(control, (dependencyproperty)e.newvalue); } } } /// <summary> /// gets validating property. /// </summary> /// <param name="control">the control.</param> /// <returns> /// dependency property. /// </returns> public static dependencyproperty getvalidatingproperty(control control) { return (dependencyproperty)control.getvalue(validatingcontrolbehavior.validatingpropertyproperty); } /// <summary> /// sets validating property. /// </summary> /// <param name="control">the control.</param> /// <param name="validatingproperty">the validating property.</param> public static void setvalidatingproperty(control control, dependencyproperty validatingproperty) { control.setvalue(validatingcontrolbehavior.validatingpropertyproperty, validatingproperty); } }
Comments
Post a Comment