c# - Custom WinForms data binding with converter not working on nullable type (double?) -


in winforms application implemented custom data binding support value converters, similar wpf.

the sample has new binding class derives binding , allows attach custom converter:

public class custombinding : binding {     private readonly ivalueconverter _converter;     private readonly object _converterparameter;     private readonly cultureinfo _converterculture;      public custombinding(string propertyname, object datasource, string datamember, ivalueconverter valueconverter, cultureinfo culture, object converterparameter = null)         : base(propertyname, datasource, datamember)     {         if (valueconverter != null)             this._converter = valueconverter;          this.datasourceupdatemode = datasourceupdatemode.onpropertychanged;         this.formattingenabled = false;          this._converterculture = culture;         this._converterparameter = converterparameter;     }      public custombinding(string propertyname, object datasource, string datamember, ivalueconverter valueconverter, object converterparameter = null)         : base(propertyname, datasource, datamember)     {         if (valueconverter != null)             this._converter = valueconverter;          this._converterculture = thread.currentthread.currentuiculture;         this._converterparameter = converterparameter;     }      protected override void onformat(converteventargs cevent)     {         if (this._converter != null)         {             var converterdvalue = this._converter.convert(cevent.value, cevent.desiredtype, _converterparameter, _converterculture);             cevent.value = converterdvalue;         }         else base.onformat(cevent);     }      protected override void onparse(converteventargs cevent)     {         if (this._converter != null)         {             var converterdvalue = this._converter.convertback(cevent.value, cevent.desiredtype, _converterparameter, _converterculture);             cevent.value = converterdvalue;         }         else base.onparse(cevent);     } } 

there interface ivalueconverter similar interface of wpf:

public interface ivalueconverter {     object convert(object value, type targettype, object parameter, cultureinfo culture);     object convertback(object value, type targettype, object parameter, cultureinfo culture); } 

with i'm able attach own converter (two-way) binding. far i've built timespanstringvalueconverter allows me bind timespan field textbox invertbooleanvalueconverter bind opposite of boolean field boolean property of control. work expected!

now want bind property of type double? textbox text field. wrote converter:

public class nullabledoublestringvalueconverter : ivalueconverter {     public object convert(object value, type targettype, object parameter, system.globalization.cultureinfo culture)     {         return value != null ? ((double)value).tostring(culture) : string.empty;     }      public object convertback(object value, type targettype, object parameter, system.globalization.cultureinfo culture)     {         string text = regex.replace((string)value, @"[^0-9" + culture.numberformat.numberdecimalseparator + @"]", "");         if (text == string.empty)         {             return null;         }         double convertedvalue;         if (double.tryparse(text, numberstyles.any, culture, out convertedvalue))         {             return (double?)convertedvalue;         }         return null;     } } 

and bind textbox way:

this.textbox1.databindings.add(new custombinding("text", obj, "myproperty", new nullabledoublestringvalueconverter())); // obj data context object 

when set break point in convertback method of value converter can see how string converted nullable double value after leaving textbox, successfully. however, instead of other cases, not update data context object. , if set break point in convert method of value converter can see retrieve initial value of myproperty null when updating text of textbox after leaving it. so, textbox gets empty after typing numeric value in it.

my question is: why? , how can make work nullable types (double?)? if change type of myproperty in data context object double accept changed value. unfortunately need nullable support. when leaving textbox empty want store null showing empty text box, when value null.

download of problem case solution

in fact, bug not in code, in 1 have downloaded (custombinding). modify constructors become

public custombinding(string propertyname, object datasource, string datamember, ivalueconverter valueconverter, object converterparameter = null)     : this(propertyname, datasource, datamember, valueconverter, thread.currentthread.currentuiculture, converterparameter) { }  public custombinding(string propertyname, object datasource, string datamember, ivalueconverter valueconverter, cultureinfo culture, object converterparameter = null)     : base(propertyname, datasource, datamember, true) {     this._converter = valueconverter;     this._converterculture = culture;     this._converterparameter = converterparameter; } 

and problem solved. essential part binding.formatingenabled must true in order work (note last argument base call, can set later too). note removed

this.datasourceupdatemode = datasourceupdatemode.onpropertychanged; 

line. default value onvalidation applicable control. onpropertychanged applicable immediate update controls check boxes, radio buttons , non editable combo boxes. in case, better leave responsibility of setting property user of class.

a side note unrelated question: you'd better off not stripping invalid characters , let exception thrown inside convertback method, otherwise weird input values if user types instance "1-3"

public object convertback(object value, type targettype, object parameter, system.globalization.cultureinfo culture) {     var text = value != null ? ((string)value).trim() : null;     return !string.isnullorempty(text) ? (object)double.parse(text, numberstyles.any, culture) : null; } 

Comments

Popular posts from this blog

java - Date formats difference between yyyy-MM-dd'T'HH:mm:ss and yyyy-MM-dd'T'HH:mm:ssXXX -

c# - Get rid of xmlns attribute when adding node to existing xml -