wpf - Silverlight: Missing DependencyObject.CoerceValue -
in silverlight there no dependencyobject.coercevalue. looking alternative, following wpf-code in silverlight.
the situation: there class range, has several dependencyproperties: minimumproperty, maximumproperty, lowervalueproperty , uppervalueproperty.
minimum may never greater maximum, maximum never smaller minimum. lowervalue , uppervalue have in between minimum , maximum, whereas lowervalue smaller uppervalue.
all dependencyproperties implemented (in wpf):
public static new readonly dependencyproperty minimumproperty = dependencyproperty.register("minimum", typeof(double), typeof(range), new frameworkpropertymetadata(0d, new propertychangedcallback(range.onminimumchanged), new coercevaluecallback(range.coerceminimum)), new validatevaluecallback(range.validateminimum)); public new double minimum { { return (double)base.getvalue(minimumproperty); } set { base.setvalue(minimumproperty, value); } }
the coercion in wpf done that:
private static object coerceminimum(dependencyobject source, object value) { range r = source range; double maximum = r.maximum; double val = (double)value; if (val > maximum) { return maximum; } return value; }
propertychangedcallback looks this:
private static void onminimumchanged(dependencyobject source, dependencypropertychangedeventargs e) { range r = source range; r.coercevalue(lowervalueproperty); r.coercevalue(uppervalueproperty); r.coercevalue(maximumproperty); }
the validatevaluecallback doesn't matter in case. other callbacks similar shown code.
in wpf runs good. example set (in xaml)
<range lowervalue="12" minimum="10" uppervalue="15" maximum="20" />
all values correct. order doesn't matter!
but in silverlight not running.
first step workaround coercevaluecallback. raise coercion in propertychangedcallback, this:
private static void onminimumchanged(dependencyobject source, dependencypropertychangedeventargs e) { range r = source range; double newval = (double)e.newvalue; double coercedval = (double)coerceminimum(source, newval); if (coercedval != newval) { r.minimum = coercecval; return; } r.coercevalue(lowervalueproperty); r.coercevalue(uppervalueproperty); r.coercevalue(maximumproperty); }
if minimum set value, coerceminimum still executed , minimum-coercion done well.
but last 3 lines not compile, because dependencyobject has no coercevalue-method. , position @ one's wits' end.
how raise coercion lowervalue, uppervalue , maximum on minimumchanged? or there way ensure, order of initialization not matter , properties set correctly (assuming condition fulfilled)?
thanks in advance!
i got solution :) sure, isnt completed yet. i've still debug possible orders, think done.
i post code lowervalue, others same:
- onuppervaluechanged raise coerceuppervaluechanged , coercelowervaluechanged.
- onminimumchanged raise coerceminimum, coerceuppervaluechanged , coercelowervaluechanged.
- onmaximumchanged raise coercemaximum, coerceuppervaluechanged , coercelowervaluechanged.
the coercion of minimum , maximum easy. if new value greater maximum (or smaller minimum) take maximum (or minimum), else take new value.
here's code:
private static void onlowervaluechanged(dependencyobject source, dependencypropertychangedeventargs e) { range r = source range; if (r._levelsfromrootcall == 0) { r._requestedlowerval = (double)e.newvalue; } r._levelsfromrootcall++; r.coercelowervalue(); r.coerceuppervalue(); r._levelsfromrootcall--; } private void coercelowervalue() { double minimum = this.minimum; double maximum = this.maximum; double lowerval = this.lowervalue; double upperval = this.uppervalue; if (lowerval != _requestedlowerval && _requestedlowerval >= minimum && _requestedlowerval <= maximum) { if (_requestedlowerval <= upperval) { base.setvalue(lowervalueproperty, _requestedlowerval); } else { base.setvalue(lowervalueproperty, upperval); } } else { if (lowerval < minimum) { base.setvalue(lowervalueproperty, minimum); } else if (lowerval > upperval || _requestedlowerval > upperval) { base.setvalue(lowervalueproperty, upperval); } else if (lowerval > maximum) { base.setvalue(lowervalueproperty, maximum); } } }
Comments
Post a Comment