PC Review


Reply
Thread Tools Rate Thread

Binding to Nullable(Of T) properties

 
 
Jack Jackson
Guest
Posts: n/a
 
      24th Jan 2008
In VS2005 VB, is it possible to bind a Nullable property to a data
source (e.g. DataTable) property that is not Nullable? My goal is to
be able to convert DBNull to and from Nothing for Value data types.

I created a derived Binding object with Format and Parse handlers. In
the Format event I am unable to set the event arg's Value property to
a Nullable type. For example, stripping out the code that is not
germane to this discussion:

Protected Overrides Sub OnFormat(ByVal cevent As
System.Windows.Forms.ConvertEventArgs)
dim dt As Nullable(Of DateTime)

dt = Convert.ToDateTime(cevent.Value)
cevent.Value = dt

cevent.Value is defined as Object. The last line sets cevent.Value to
a DateTime, not to a Nullable(Of DateTime). In playing around with
this, I have been unable to get a property defined as Object set to a
Nullable - it always sets it to the value property of the Nullable
object.

Because cevent.Value is a DateTime I get an invalid cast error when
..NET tries to set the Nullable property to cevent.Value.

Is there any way to do the binding?
 
Reply With Quote
 
 
 
 
Morten Wennevik [C# MVP]
Guest
Posts: n/a
 
      24th Jan 2008
Hi Jack,

Using Format and Parse events is the way to do it. Use the
ConvertEventArgs.DesiredType property to see what kind of type cevent.Value
should be before you leave the event method. ConvertEventArgs.Value will
return an Object, but this object will be a DateTime, a nullable DateTime
null or DBNull.Value

Your code does not appear to take into account that cevent.Value may in fact
be null, in which case cevent.Value should be set to DBNull.Value.

DateTime? nullableDate = cevent.Value as DateTime?;
cevent.Value = nullableDate.Value ?? DBNull.Value;

The last line is equal to
if(nullableDate == null)
cevent.Value = DBNull.Value;
else
cevent.Value = nullableDate.Value;

--
Happy Coding!
Morten Wennevik [C# MVP]


"Jack Jackson" wrote:

> In VS2005 VB, is it possible to bind a Nullable property to a data
> source (e.g. DataTable) property that is not Nullable? My goal is to
> be able to convert DBNull to and from Nothing for Value data types.
>
> I created a derived Binding object with Format and Parse handlers. In
> the Format event I am unable to set the event arg's Value property to
> a Nullable type. For example, stripping out the code that is not
> germane to this discussion:
>
> Protected Overrides Sub OnFormat(ByVal cevent As
> System.Windows.Forms.ConvertEventArgs)
> dim dt As Nullable(Of DateTime)
>
> dt = Convert.ToDateTime(cevent.Value)
> cevent.Value = dt
>
> cevent.Value is defined as Object. The last line sets cevent.Value to
> a DateTime, not to a Nullable(Of DateTime). In playing around with
> this, I have been unable to get a property defined as Object set to a
> Nullable - it always sets it to the value property of the Nullable
> object.
>
> Because cevent.Value is a DateTime I get an invalid cast error when
> ..NET tries to set the Nullable property to cevent.Value.
>
> Is there any way to do the binding?
>

 
Reply With Quote
 
Jack Jackson
Guest
Posts: n/a
 
      24th Jan 2008
On Wed, 23 Jan 2008 23:22:01 -0800, Morten Wennevik [C# MVP]
<(E-Mail Removed)> wrote:

>Hi Jack,
>
>Using Format and Parse events is the way to do it. Use the
>ConvertEventArgs.DesiredType property to see what kind of type cevent.Value
>should be before you leave the event method. ConvertEventArgs.Value will
>return an Object, but this object will be a DateTime, a nullable DateTime
>null or DBNull.Value


In the Format event I need to return a nullable DateTime since that is
the type of the bound property, but I am unable to do that. As I said
in the original post,
Dim dt as Nullable(Of DateTime)
dt = <some DateTime value>
cevent.Value = dt
makes cevent.Value be a DateTime, not a nullable DateTime. Returning
a DateTime results in an invalid cast exception (DateTime can not be
cast to Nullable).

>Your code does not appear to take into account that cevent.Value may in fact
>be null, in which case cevent.Value should be set to DBNull.Value.


That is correct. I removed that code since it was not germane to my
problem.
 
Reply With Quote
 
Morten Wennevik [C# MVP]
Guest
Posts: n/a
 
      24th Jan 2008
Hi Jack,

I think I may be misunderstanding your problem. The Format event is for
converting datasource properties to control properties. You are saying you
need to return a nullable DateTime in the Format event, but setting
cevent.Value to a nullable DateTime makes no sense unless the Control
property supports null.

The Format event would be responsible to convert a nullable datetime to
either a DateTime or DBNull.Value, whereas the Parse event would be
responsible to convert either a DateTime or DBNull.Value to a nullable
DateTime.

If you could show is some more code it may be easier to spot the error. How
do you set up your databinding?

Try using separate references for the DateTime vs nullable DateTime instead
of reusing. dt = Convert.ToDateTime(cevent.Value) would not compile in C#
because Convert.ToDateTime returns a DateTime reference whereas dt is a
nullable DateTime. VB does some type conversion behind the scenes that not
always works perfectly.

--
Happy Coding!
Morten Wennevik [C# MVP]


"Jack Jackson" wrote:

> On Wed, 23 Jan 2008 23:22:01 -0800, Morten Wennevik [C# MVP]
> <(E-Mail Removed)> wrote:
>
> >Hi Jack,
> >
> >Using Format and Parse events is the way to do it. Use the
> >ConvertEventArgs.DesiredType property to see what kind of type cevent.Value
> >should be before you leave the event method. ConvertEventArgs.Value will
> >return an Object, but this object will be a DateTime, a nullable DateTime
> >null or DBNull.Value

>
> In the Format event I need to return a nullable DateTime since that is
> the type of the bound property, but I am unable to do that. As I said
> in the original post,
> Dim dt as Nullable(Of DateTime)
> dt = <some DateTime value>
> cevent.Value = dt
> makes cevent.Value be a DateTime, not a nullable DateTime. Returning
> a DateTime results in an invalid cast exception (DateTime can not be
> cast to Nullable).
>
> >Your code does not appear to take into account that cevent.Value may in fact
> >be null, in which case cevent.Value should be set to DBNull.Value.

>
> That is correct. I removed that code since it was not germane to my
> problem.
>

 
Reply With Quote
 
Jack Jackson
Guest
Posts: n/a
 
      24th Jan 2008
Thanks for your interest in my problem.

I have an object property that is a Nullable(Of DateTime) that I am
attempting to bind to a data source property that is a DateTime.

I have a custom Binding object to connect the two. If I don't
override OnFormat, I get an InvalidCastException when the binding
tries to cast the data source DateTime to the Nullable(Of DateTime) of
the object.

To fix this I override Binding.OnFormat. ConvertEventArgs.Value is a
DateTime, which I need to turn into a Nullable(Of DateTime) to avoid
the illegal cast exception.

My problem is that I am unable to get ConvertEventArgs.Value to be a
Nullable(Of DateTime). This code (cevent is the ConvertEventArgs
argument):
Dim dt As Nullable(Of DateTime)
dt = Convert.ToDateTime(cevent.Value)
cevent.Value = dt
results in cevent.Value being a DateTime, not a Nullable(Of DateTime).

The only way I have found to get cevent.Value to be a Nullable(Of
DateTime) is to use Activator.CreateInstance, but that creates a
Nullable with HasValue = False, and I can't find anyway to give it a
value.

On Thu, 24 Jan 2008 03:56:01 -0800, Morten Wennevik [C# MVP]
<(E-Mail Removed)> wrote:

>Hi Jack,
>
>I think I may be misunderstanding your problem. The Format event is for
>converting datasource properties to control properties. You are saying you
>need to return a nullable DateTime in the Format event, but setting
>cevent.Value to a nullable DateTime makes no sense unless the Control
>property supports null.


The control property is a Nullable(Of DateTime)

>The Format event would be responsible to convert a nullable datetime to
>either a DateTime or DBNull.Value, whereas the Parse event would be
>responsible to convert either a DateTime or DBNull.Value to a nullable
>DateTime.


I believe you have reversed Format and Parse. Format converts the
binding source property (DateTime) to the control property
(Nullable(Of DateTime)).

>If you could show is some more code it may be easier to spot the error. How
>do you set up your databinding?
>
>Try using separate references for the DateTime vs nullable DateTime instead
>of reusing. dt = Convert.ToDateTime(cevent.Value) would not compile in C#
>because Convert.ToDateTime returns a DateTime reference whereas dt is a
>nullable DateTime.


I am not reusing dt. In VB you set the value of a Nullable by
assigning an item of the Of T type to it:
Dim dt As Nullable(Of DateTime)
dt = Date.Now()
The Convert is necessary in this case because cevent.Value is defined
as Object and must be cast to DateTime. The result of this code is
that dt is a Nullable(Of DateTime) with a value of Date.Now().

I am aware that VS2005 VB has less support for Nullable than C#, and
it may be that I simply can't do this in VS2005 VB.

 
Reply With Quote
 
Morten Wennevik [C# MVP]
Guest
Posts: n/a
 
      24th Jan 2008
Hi Jack,

I'll take a closer look at it tomorrow. In the meantime try changing your
event code to something like


Dim dt as DateTime
dt = Convert.ToDateTime(cevent.Value)
cevent.Value = dt

Or

Dim dt = cevent.Value as Nullable(Of DateTime) ' may not be syntactically
right
cevent.Value = dt.Value


Your code as it was would be illegal in C# due to type difference.
Furthermore for datetime and nullable datetime the types are considered equal
even though in the end they are not.
--
Happy Coding!
Morten Wennevik [C# MVP]


"Morten Wennevik [C# MVP]" wrote:

> Hi Jack,
>
> I think I may be misunderstanding your problem. The Format event is for
> converting datasource properties to control properties. You are saying you
> need to return a nullable DateTime in the Format event, but setting
> cevent.Value to a nullable DateTime makes no sense unless the Control
> property supports null.
>
> The Format event would be responsible to convert a nullable datetime to
> either a DateTime or DBNull.Value, whereas the Parse event would be
> responsible to convert either a DateTime or DBNull.Value to a nullable
> DateTime.
>
> If you could show is some more code it may be easier to spot the error. How
> do you set up your databinding?
>
> Try using separate references for the DateTime vs nullable DateTime instead
> of reusing. dt = Convert.ToDateTime(cevent.Value) would not compile in C#
> because Convert.ToDateTime returns a DateTime reference whereas dt is a
> nullable DateTime. VB does some type conversion behind the scenes that not
> always works perfectly.
>
> --
> Happy Coding!
> Morten Wennevik [C# MVP]
>
>
> "Jack Jackson" wrote:
>
> > On Wed, 23 Jan 2008 23:22:01 -0800, Morten Wennevik [C# MVP]
> > <(E-Mail Removed)> wrote:
> >
> > >Hi Jack,
> > >
> > >Using Format and Parse events is the way to do it. Use the
> > >ConvertEventArgs.DesiredType property to see what kind of type cevent.Value
> > >should be before you leave the event method. ConvertEventArgs.Value will
> > >return an Object, but this object will be a DateTime, a nullable DateTime
> > >null or DBNull.Value

> >
> > In the Format event I need to return a nullable DateTime since that is
> > the type of the bound property, but I am unable to do that. As I said
> > in the original post,
> > Dim dt as Nullable(Of DateTime)
> > dt = <some DateTime value>
> > cevent.Value = dt
> > makes cevent.Value be a DateTime, not a nullable DateTime. Returning
> > a DateTime results in an invalid cast exception (DateTime can not be
> > cast to Nullable).
> >
> > >Your code does not appear to take into account that cevent.Value may in fact
> > >be null, in which case cevent.Value should be set to DBNull.Value.

> >
> > That is correct. I removed that code since it was not germane to my
> > problem.
> >

 
Reply With Quote
 
Jack Jackson
Guest
Posts: n/a
 
      25th Jan 2008
I found a way to avoid these problems with Nullable by setting
Binding.FormattingEnabled = True. Apparently this lets the Binding
object convert between DateTime and Nullable(Of DateTime).

I have decided it is impossible to set an Object to a Nullable. See
below.

On Thu, 24 Jan 2008 13:36:29 -0800, Morten Wennevik [C# MVP]
<(E-Mail Removed)> wrote:

>Hi Jack,
>
>I'll take a closer look at it tomorrow. In the meantime try changing your
>event code to something like
>
>
> Dim dt as DateTime
> dt = Convert.ToDateTime(cevent.Value)
> cevent.Value = dt


Since cevent.Value already is a DateTime, this will have no effect and
results in an InvalidCastException when the Binding tries to convert
cevent.Value (DateTime) to the type of the bound object (Nullable(Of
DateTime)).

>Or
>
> Dim dt = cevent.Value as Nullable(Of DateTime) ' may not be syntactically
>right
> cevent.Value = dt.Value


I think this is essentially what I first tried:
Dim dt As Nullable(Of DateTime) = Convert.ToDateTime(cevent.Value)
cevent.Value = dt
which results in cevent.Value being a DateTime, not a Nullable(Of
DateTime).

>Your code as it was would be illegal in C# due to type difference.


I don't think so. My understanding of the C# syntax is:
int? x = 10;
which is just what I am doing in VB. I assign a DateTime value to my
Nullable(Of DateTime) variable.

>Furthermore for datetime and nullable datetime the types are considered equal
>even though in the end they are not.


This can't be entirely correct given the InvalidCastException that I
get.

I am beginning to think there simply is no way to assign a Nullable
item to an item defined as Object and have the result be a Nullable.
In fact, I'm pretty sure this is true. At
<http://www.theserverside.net/news/thread.tss?thread_id=36085> I found
this:

"The outcome is that the Nullable type is now a new basic runtime
intrinsic. It is still declared as a generic value-type, yet the
runtime treats it special. One of the foremost changes is that boxing
now honors the null state. A Nullabe int now boxes to become not a
boxed Nullable int but a boxed int (or a null reference as the null
state may indicate.) Likewise, it is now possible to unbox any kind of
boxed value-type into its Nullable type equivalent."

When the Nullable is assigned to an Object, it must be boxed, and the
above says that it will be boxed as its internal type not a Nullable.

So maybe this is a 'bug' in Binding that should deal with this
situation but doesn't.
 
Reply With Quote
 
Morten Wennevik [C# MVP]
Guest
Posts: n/a
 
      25th Jan 2008
Hi Jack,

"Jack Jackson" wrote:

> I found a way to avoid these problems with Nullable by setting
> Binding.FormattingEnabled = True. Apparently this lets the Binding
> object convert between DateTime and Nullable(Of DateTime).
>


Ah, that might help. Also, sometimes calling bindingsource.ResetBindings
will help initial updates although that may not be related to this case. I'm
glad it solved your problem.

> Since cevent.Value already is a DateTime, this will have no effect and
> results in an InvalidCastException when the Binding tries to convert
> cevent.Value (DateTime) to the type of the bound object (Nullable(Of
> DateTime)).
>


Hm, I was under impression that cevent.Value was passed as nullable DateTime

> >Or
> >
> > Dim dt = cevent.Value as Nullable(Of DateTime) ' may not be syntactically
> >right
> > cevent.Value = dt.Value

>
> I think this is essentially what I first tried:
> Dim dt As Nullable(Of DateTime) = Convert.ToDateTime(cevent.Value)
> cevent.Value = dt
> which results in cevent.Value being a DateTime, not a Nullable(Of
> DateTime).
>
> >Your code as it was would be illegal in C# due to type difference.

>
> I don't think so. My understanding of the C# syntax is:
> int? x = 10;
> which is just what I am doing in VB. I assign a DateTime value to my
> Nullable(Of DateTime) variable.
>


I may have been wrong on this one and am unable to find the code that
produced the compiler error or reproduce the error. However, both in case
int? x = 10 and DateTime? y = DateTime.Today you will end up with a nullable
type.

> >Furthermore for datetime and nullable datetime the types are considered equal
> >even though in the end they are not.

>
> This can't be entirely correct given the InvalidCastException that I
> get.
>


DateTime? x = new DateTime?(DateTime.Today)
DateTime y = DateTime.Now;

x.GetType() == y.GetType()

It appears that this type equality is not entirely true and while the
compiler accepts it, the runtime might not.

> I am beginning to think there simply is no way to assign a Nullable
> item to an item defined as Object and have the result be a Nullable.
> In fact, I'm pretty sure this is true. At
> <http://www.theserverside.net/news/thread.tss?thread_id=36085> I found
> this:
>
> "The outcome is that the Nullable type is now a new basic runtime
> intrinsic. It is still declared as a generic value-type, yet the
> runtime treats it special. One of the foremost changes is that boxing
> now honors the null state. A Nullabe int now boxes to become not a
> boxed Nullable int but a boxed int (or a null reference as the null
> state may indicate.) Likewise, it is now possible to unbox any kind of
> boxed value-type into its Nullable type equivalent."
>
> When the Nullable is assigned to an Object, it must be boxed, and the
> above says that it will be boxed as its internal type not a Nullable.
>


It is boxed as its internal datatype when it isn't null, if it IS null it
will be stored as a null reference.

> So maybe this is a 'bug' in Binding that should deal with this
> situation but doesn't.
>


I really wish you provided more detail information about your setup than
vague ideas. That way we can try to reproduce the issue locally and maybe
find a solution or workaround.

---
Happy Coding!
Morten Wennevik [C# MVP]
 
Reply With Quote
 
Jack Jackson
Guest
Posts: n/a
 
      25th Jan 2008
Thanks for your help.

On Fri, 25 Jan 2008 13:55:08 -0800, Morten Wennevik [C# MVP]
<(E-Mail Removed)> wrote:

>Hi Jack,
>
>"Jack Jackson" wrote:
>
>> I found a way to avoid these problems with Nullable by setting
>> Binding.FormattingEnabled = True. Apparently this lets the Binding
>> object convert between DateTime and Nullable(Of DateTime).
>>

>
>Ah, that might help. Also, sometimes calling bindingsource.ResetBindings
>will help initial updates although that may not be related to this case. I'm
>glad it solved your problem.
>
>> Since cevent.Value already is a DateTime, this will have no effect and
>> results in an InvalidCastException when the Binding tries to convert
>> cevent.Value (DateTime) to the type of the bound object (Nullable(Of
>> DateTime)).
>>

>
>Hm, I was under impression that cevent.Value was passed as nullable DateTime
>
>> >Or
>> >
>> > Dim dt = cevent.Value as Nullable(Of DateTime) ' may not be syntactically
>> >right
>> > cevent.Value = dt.Value

>>
>> I think this is essentially what I first tried:
>> Dim dt As Nullable(Of DateTime) = Convert.ToDateTime(cevent.Value)
>> cevent.Value = dt
>> which results in cevent.Value being a DateTime, not a Nullable(Of
>> DateTime).
>>
>> >Your code as it was would be illegal in C# due to type difference.

>>
>> I don't think so. My understanding of the C# syntax is:
>> int? x = 10;
>> which is just what I am doing in VB. I assign a DateTime value to my
>> Nullable(Of DateTime) variable.
>>

>
>I may have been wrong on this one and am unable to find the code that
>produced the compiler error or reproduce the error. However, both in case
>int? x = 10 and DateTime? y = DateTime.Today you will end up with a nullable
>type.
>
>> >Furthermore for datetime and nullable datetime the types are considered equal
>> >even though in the end they are not.

>>
>> This can't be entirely correct given the InvalidCastException that I
>> get.
>>

>
>DateTime? x = new DateTime?(DateTime.Today)
>DateTime y = DateTime.Now;
>
>x.GetType() == y.GetType()
>
>It appears that this type equality is not entirely true and while the
>compiler accepts it, the runtime might not.
>
>> I am beginning to think there simply is no way to assign a Nullable
>> item to an item defined as Object and have the result be a Nullable.
>> In fact, I'm pretty sure this is true. At
>> <http://www.theserverside.net/news/thread.tss?thread_id=36085> I found
>> this:
>>
>> "The outcome is that the Nullable type is now a new basic runtime
>> intrinsic. It is still declared as a generic value-type, yet the
>> runtime treats it special. One of the foremost changes is that boxing
>> now honors the null state. A Nullabe int now boxes to become not a
>> boxed Nullable int but a boxed int (or a null reference as the null
>> state may indicate.) Likewise, it is now possible to unbox any kind of
>> boxed value-type into its Nullable type equivalent."
>>
>> When the Nullable is assigned to an Object, it must be boxed, and the
>> above says that it will be boxed as its internal type not a Nullable.
>>

>
>It is boxed as its internal datatype when it isn't null, if it IS null it
>will be stored as a null reference.
>
>> So maybe this is a 'bug' in Binding that should deal with this
>> situation but doesn't.
>>

>
>I really wish you provided more detail information about your setup than
>vague ideas. That way we can try to reproduce the issue locally and maybe
>find a solution or workaround.
>
>---
>Happy Coding!
>Morten Wennevik [C# MVP]

 
Reply With Quote
 
Mat
Guest
Posts: n/a
 
      7th Feb 2008
Hi Guys,

I had the same problem but found this reference on the internet. Works like
a charm and bypasses the need to do backflips.

http://blog.jezhumble.net/?p=3

--Binding to nullables work in WinForms.
--I had the same problem before where the nullable won’t be updated. However,
--passing extra arguments seem to fix it for some reason (haven’t checked
into the
--details yet), e.g.
--bind = new Binding(”ValueObject”, bindingSource, “FeeAmount”, true,
-- DataSourceUpdateMode.OnPropertyChanged);


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help: datetimepicker nullable required with binding support Alcibiade Microsoft C# .NET 0 21st Sep 2010 10:38 AM
Binding three state checkbox to nullable boolean klachemin@comcast.net Microsoft VB .NET 2 22nd Mar 2008 10:44 PM
binding nullable property Marka83 Microsoft Dot NET Framework Forms 1 20th Dec 2007 07:08 AM
Nullable properties for User Controls. lord.zoltar@gmail.com Microsoft VB .NET 1 19th Dec 2006 09:39 PM
Binding nullable value to combobox Bob Rundle Microsoft ADO .NET 2 25th Aug 2004 10:22 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 06:54 AM.