Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to a Nullable<DateTime> control property

We have a custom control that has a "Value" property of type System.Nullable (aka System.DateTime?). We have an object with a "Received" property of the same type. When we try to bind the control to the object, the following InvalidCastException is thrown:

Invalid cast from 'System.DateTime' to 'System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

Here is what we're doing:

Object property:

private System.DateTime? _dateTimeReceived;
public System.DateTime? DateTimeReceived
{
    get
    {
        return this._dateTimeReceived;
    }
    set
    {
        this._dateTimeReceived = value;
        this.OnChanged("DateTimeReceived", value); //Implements INotifyPropertyChanged and fires PropertyChanged event
    }
}

Control property:

private System.DateTime? _value;
[System.ComponentModel.Category("Behavior")]
[System.ComponentModel.Description("The current date value for this control")]
public new System.DateTime? Value
{
    get
    {
        return this._value;
    }

    set
    {
        this._value = value;
    }
}

In the application, here is where the exception is thrown:

this.dateReceived.DataBindings.Add("Value", this._object, "DateTimeReceived");

As you can see, the object's property (this._object.DateTimeReceived) is a System.DateTime? type and the control's property (this.dateReceived.Value) is a System.DateTime? type.

Why would this cause an InvalidCastException? And how can we correct this so that it binds correctly?

Update 2009-10-29 14:26 CDT:

Here is the stack trace:

at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.DateTime.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Windows.Forms.Binding.FormatObject(Object value)
at System.Windows.Forms.Binding.PushData(Boolean force)
at System.Windows.Forms.Binding.UpdateIsBinding()
at System.Windows.Forms.Binding.CheckBinding()
at System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase)
at System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding)
at System.Windows.Forms.BindingsCollection.Add(Binding binding)
at System.Windows.Forms.BindingContext.UpdateBinding(BindingContext newBindingContext, Binding binding)
at System.Windows.Forms.Binding.SetBindableComponent(IBindableComponent value)
at System.Windows.Forms.ControlBindingsCollection.AddCore(Binding dataBinding)
at System.Windows.Forms.BindingsCollection.Add(Binding binding)
at System.Windows.Forms.ControlBindingsCollection.Add(String propertyName, Object dataSource, String dataMember, Boolean formattingEnabled, DataSourceUpdateMode updateMode, Object nullValue, String formatString, IFormatProvider formatInfo)
at System.Windows.Forms.ControlBindingsCollection.Add(String propertyName, Object dataSource, String dataMember)

like image 857
Steven King Avatar asked Oct 28 '09 21:10

Steven King


1 Answers

I was trying to do the same thing, and I managed to find some working sample code which bound to a nullable. It turns out that if you set the formattingEnabled to true, it works, but if it's false, you get the invalid cast exception.

So your code that looks like this:

this.dateReceived.DataBindings.Add("Value", this._object, "DateTimeReceived");

Should instead look like this:

this.dateReceived.DataBindings.Add("Value", this._object, "DateTimeReceived", true);

Apparently the old data binding code requires that the types match exactly, but Microsoft later added the ability to automatically convert types for you. From here: http://msdn.microsoft.com/en-us/library/aa480734.aspx

In earlier versions of the .NET Framework you had to manually perform the type conversions and formatting using the Format and Parse events of the Binding object. You can now do this by enabling formatting on the Binding object, either by setting the FormattingEnabled property directly or passing true to the Add method of the ControlBindingsCollection.

like image 59
Bryce Wagner Avatar answered Oct 06 '22 12:10

Bryce Wagner