wpf textbox custom control type error -
i wrote custom control base on textbox has minimum , maximum inputs follows:
public class numerictextbox : textbox { static numerictextbox() { defaultstylekeyproperty.overridemetadata(typeof(numerictextbox), new frameworkpropertymetadata(typeof(numerictextbox))); } public static readonly dependencyproperty minimumproperty = dependencyproperty.register("minimum", typeof(int), typeof(numerictextbox), new propertymetadata(default(int))); public int minimum { { return (int)getvalue(minimumproperty); } set { setvalue(minimumproperty, value); } } public static readonly dependencyproperty maximumproperty = dependencyproperty.register("maximum", typeof(int), typeof(numerictextbox), new propertymetadata(100)); public int maximum { { return (int)getvalue(maximumproperty); } set { setvalue(maximumproperty, value); } } public new static readonly dependencyproperty textproperty = dependencyproperty.register("text", typeof(int), typeof(numerictextbox), new frameworkpropertymetadata( default(int), frameworkpropertymetadataoptions.bindstwowaybydefault, null, coercecurrentvalue), isvalid); public new int text { { return (int)getvalue(textproperty); } set { setvalue(textproperty, value); } } private static object coercecurrentvalue(dependencyobject d, object basevalue) { var numerictextbox = (numerictextbox)d; var intvalue = (int)basevalue; if (intvalue < numerictextbox.minimum) intvalue = numerictextbox.minimum; if (intvalue > numerictextbox.maximum) intvalue = numerictextbox.maximum; if ((int)basevalue != intvalue) numerictextbox.text = intvalue; return intvalue; } private static bool isvalid(object value) { if (value == null) return false; int intvalue; var result = int32.tryparse(value.tostring(), out intvalue); return result; } }
and in xaml call it:
<controls:numerictextbox grid.row="0" grid.column="1" margin="5" verticalalignment="center" text="{binding test, updatesourcetrigger=propertychanged}" minimum="0" maximum="100" />
it bind test property in view model (as int). works until type character , binding error:
system.windows.data error: 7 : convertback cannot convert value '1a' (type 'string'). bindingexpression:path=text; dataitem='numerictextbox' (name=''); target element 'textbox' (name=''); target property 'text' (type 'string') formatexception:'system.formatexception: input string not in correct format. @ system.number.stringtonumber(string str, numberstyles options, numberbuffer& number, numberformatinfo info, boolean parsedecimal) @ system.number.parseint32(string s, numberstyles style, numberformatinfo info) @ system.string.system.iconvertible.toint32(iformatprovider provider)
@ system.convert.changetype(object value, type conversiontype, iformatprovider provider) @ ms.internal.data.systemconvertconverter.convertback(object o, type type, object parameter, cultureinfo culture) @ system.windows.data.bindingexpression.convertbackhelper(ivalueconverter converter, object value, type sourcetype, object parameter, cultureinfo culture)'
it may because original text property in textbox string... i'm not sure. please assist on that.
you going in wrong way. not restricting input of textbox
numerical numbers. framework trying convert string
int
fit new int text
property, error says: input string not in correct format., eg. not int
. try adding constructor instead:
previewtextinput += new textcompositioneventhandler((s, e) => e.handled = !e.text.all(c => char.isnumber(c) && c != ' ')); previewkeydown += new keyeventhandler((s, e) => e.handled = e.key == key.space);
they work setting e.handled
true
if non numerical values input , has effect of ignoring input on occasions.
also, don't need implement own text
property... confusing matters. use original 1 , parse value int
wherever need to, resting assured will number. think these 2 handlers should ensure that. let me know if have problems.
another idea create attachedproperty
using these handlers , can apply textbox
control. of course, you'd need implement minimum
, maximum
properties attachedproperties
too, this:
<textbox text={binding test} attached:textboxproperties.isnumeric="true" attached:textboxproperties.minimum="0" attached:textboxproperties.maximum="100" />
you can find out more attached properties overview page on msdn.
update >>>
if don't want user able delete last character textbox
, can change 1 of handlers disallow it:
previewkeydown += previewkeydown; ... private void previewkeydown(object sender, keyeventargs e) { textbox textbox = sender textbox; e.handled = e.key == key.space || (textbox.text.length == 1 && (e.key == key.delete || e.key == key.back)); }
Comments
Post a Comment