Pregunta

I've made a custom Textbox which displays a (nullable) decimal value as time (2.5 = 2:30). I've added a property "decimal? DecimalValue" to which I bind my datasource. This all works fine, except when I clear the Textbox, to make the value null.

It says "Object of type System.String cannot be converted to System.Nullable`1[System.Decimal]".

What I saw is that base.OnValidating makes e.Cancel = True. So, somewhere underneath there is a check performed that causes this. I don't understand this behaviour though, because when I bind to property Text I can clear the Textbox without a problem and a null value is being saved.

Code of binding:

this.txtUrenDoorberekenen.DataBindings.Add(new System.Windows.Forms.Binding("DecimalValue", this.bsAutokraanOrderRegel, "Uren", true));

Custom property:

[Browsable(true), Bindable(true), Category("DSE"), DefaultValue(null), Description("De numerieke waarde")]
public decimal? DecimalValue
{
    get { return this.GeefNumeriek(this.Text); }
    set { this.Text = this.GeefTijd(value); }
}

this.GeefNumeriek return a decimal? (it converts the Text of Textbox to a nullable decimal). this.GeefTijd(value) converts a nullable decimal to a string format.

    private decimal? GeefNumeriek(string waarde)
    {
        decimal? result = null;
        if (!String.IsNullOrEmpty(waarde)) {
            try {
                // voeg dubbele punt toe, indien deze ontbreekt
                if (waarde.Length == 1 && waarde.IndexOf(":") < 0) { waarde = waarde + ":00"; }
                if (waarde.Length == 2 && waarde.IndexOf(":") < 0) { waarde = waarde + ":00"; }
                if (waarde.Length >= 3 && waarde.IndexOf(":") < 0) { waarde = waarde.Substring(0, waarde.Length - 2) + ":" + waarde.Substring(waarde.Length - 2); }

                // Uren gedeelte
                result = Convert.ToDecimal(waarde.Substring(0, waarde.IndexOf(":")));

                // Minuten
                int minuten = Convert.ToInt16(waarde.Substring(waarde.IndexOf(":") + 1));
                // Minuten kan niet meer dan 60 zijn
                if (minuten > 60) { throw new Exception(DSETextResource.GeefText("Validatie_Numeriek_Ongeldig")); }

                result = result + ((decimal)minuten / (decimal)60);
            }
            catch {
            }
        }
        return result;
    }
¿Fue útil?

Solución

You have to add some code to Parse event of Binding like this:

Binding bind = new Binding("Text", yourObject, "DecimalProperty");
bind.Parse += (s,e) => {
  if((string)e.Value == "") e.Value = default(decimal?);
  else e.Value = decimal.Parse((string)e.Value);
};
textBox1.DataBindings.Add(bind);

NOTE: The code above suppose the string is always parsable to decimal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top