views:

670

answers:

2

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)
A: 

http://weblogs.asp.net/pjohnson/archive/2006/02/07/437631.aspx

Jack T. Colton
That article is trying to "convert a boxed DateTime object to a Nullable<DateTime>". We're trying to bind a Nullable<DateTime> to a Nullable<DateTime>.
ICS
+1  A: 

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);

No clue why that actually works. It's probably an unintended side effect, but it works.

Bryce Wagner