c# - How can I use IDataErrorInfo to validate child objects from the parent class? -
i have class, datamodel
, has bunch of objects of same class, inputitem
. inputitem
class has nullable decimal property, value
, want validate in datamodel
class (not in inputitem
class). because validation of 1 inputitem
object depends on value in another inputitem
object. i'd use idataerrorinfo
purpose, haven't been able make work (this code allows me bind values in inputitem
, doesn't perform validation).
my datamodel class:
using system.componentmodel; public class datamodel : idataerrorinfo { public inputitem item1 {get; set;} public inputitem item2 {get; set;} public inputitem item3 {get; set;} //... more inputitem objects public string error { { return string.empty;} } public string this[string propertyname] { { string result = string.empty; switch (propertyname) { case "item1": case "item1.value": if (item1.value == null) result = "item 1 required."; else if (item1.value < 0) result = "item 1 must greater 0."; break; case "item2": case "item2.value": if (item2.value == null) result = "item 2 required."; else if (item2.value < item1.value) result = "item 2 must greater item 1"; break; case "item3": case "item3.value": if (item3.value == null) result = empty.string; else if (item3.value < item1.value) result = "item 3 must greater item 1." else if (item3.value > item2.value) result = "item 3 must less item 2." } return result; } } } public class inputitem : inotifypropertychanged { //implements inotifypropertychanged, i'm leaving out shorten code public string name {get; set;} public decimal? value {get; set;} public string unit {get; set;} public string tip { get; set; } //... more properties // ... standard constructors }
ultimately, want bind of properties of textbox
objects in xaml view properties in different inputitem
objects, (with view's datacontext
set datamodel
object):
<textbox text="{binding path=item1.value, mode=twoway, updatesourcetrigger=propertychanged, validatesondataerrors=true}"/>
previously, tried setting validation rules each of inputitem objects minimum , maximum allowable values, , binding minimum , maximum values inside validation rules values in other inputitem objects, can tell description, gets complicated , tangled fast. here's code used validationrule
, bindings strategy, in case you're interested:
using system.globalization; using system.windows; using system.windows.controls; public class numbervalidationrulewithwrapper : validationrule { public override validationresult validate(object value, cultureinfo cultureinfo) { decimal result = 0; bool canconvert = decimal.tryparse(value string, out result); if (!canconvert) return new validationresult(false, "must valid number"); decimal? maxval = this.wrapper.maxvalue; if (maxval != null && !double.isnan((double)maxval)) { if (result >= maxval) return new validationresult(false, "must less " + ((decimal)maxval).tostring()); } decimal? minval = this.wrapper.minvalue; if (minval != null && !double.isnan((double)minval)) { if (result <= minval) return new validationresult(false, "must greater " + ((decimal)minval).tostring()); } return validationresult.validresult; } public decimalwrapper wrapper { get; set; } } public class decimalwrapper : dependencyobject { public static readonly dependencyproperty maxvalueproperty = dependencyproperty.register("maxvalue", typeof(double?), typeof(decimalwrapper), new frameworkpropertymetadata(double.maxvalue)); public static readonly dependencyproperty minvalueproperty = dependencyproperty.register("minvalue", typeof(double?), typeof(decimalwrapper), new frameworkpropertymetadata(double.minvalue)); public decimal? maxvalue { { return (decimal?)getvalue(maxvalueproperty); } set { setvalue(maxvalueproperty, value); } } public decimal? minvalue { { return (decimal?)getvalue(minvalueproperty); } set { setvalue(minvalueproperty, value); } } }
i've looked @ how validate child objects implementing idataerrorinfo on parent class, doesn't apply situation (that person wanted validate individual child objects on own, not through parent object).
i looked @ this post brian lagunas, doesn't apply either, since each of inputitem
objects have different rules relating other inputitem
objects (e.g. item1 can number, item2 has less item1, item3 has between item1 , item2, item4 has greater item3, etc).
when bind item1.value
, idataerrorinfo
implementation of type value
property belongs, i.e. inputitem
, matters. doesn't matter whether datamodel
implements idataerrorinfo
.
the inotifydataerrorinfo interface introcuded in .net framework 4.5 makes wpf data validation lot more flexible.
if want perform validation in datamodel
class, implement interface in inputitem
class , set actual errors returned geterrors
method , raise errorschanged
event datamodel
class. there example of how implement interface available here: https://social.technet.microsoft.com/wiki/contents/articles/19490.wpf-4-5-validating-data-in-using-the-inotifydataerrorinfo-interface.aspx.
Comments
Post a Comment