User Control (text box), Null values, Formatting

I am trying to create a textbox control which will handle null values (see 1 below) and retain the ability to be formatted using Binding.Format (see 2 and 3 below). My User Control is in Number 1 below. When I use the 'Shadows Property Text' function, I loose formatting on the control. The call to format is just ignored. I tried the following:

Commented out the Public Shadows Property -- the formatting returned as well as the null problem.
Tried the following imports: Imports System.Windows.Forms.Binding and
Imports System.Windows.Forms.BindingsCollection -- No luck
Added the following attributes: <Bindable(True), ListBindable(True)> -- still no formatting.

Where am I going wrong? Thanks.

wread
CODE
1. THE USER CONTROL CLASS

Imports System.ComponentModel
Imports System.Windows.Forms.Design

<Designer(GetType(TextNoNull.TextNoNullDesigner))> _
Public Class TextNoNull
Inherits System.Windows.Forms.TextBox

Friend Class TextNoNullDesigner
Inherits System.Windows.Forms.Design.ControlDesigner

Public Overrides Sub OnSetComponentDefaults()
MyBase.OnSetComponentDefaults()
MyBase.Control.Text = ""
'MyBase.Control.Text.TextAlign = System.Windows.Forms.TextBox.
End Sub
End Class

'<Bindable(True), ListBindable(True)> _
Public Shadows Property Text() As Object
Get
Return MyBase.Text
End Get
Set(ByVal Value As Object)
Try
If IsDBNull(Value) = True Then
MyBase.Text = ""
Else
If Len(Value) = 0 Then
MyBase.Text = ""
Else
MyBase.Text = Value
End If
End If
Catch exc As Exception
MyBase.Text = "Incorrect value type " & exc.Message
End Try

End Set

End Property

2. THE CONTROL IN SITU WITH HANDLER FOR FORMATTING.

Dim b as Binding

b = Me.txtFieldName.DataBindings.Add("Text", _
Me.dsTableName, _
"TableName.FieldName")
AddHandler b.Format, AddressOf DecimalToPercentageStringTwo

3. CLASS CONTAINING THE FORMAT FUNCTION

Public Shared Sub DecimalToPercentageStringOne(ByVal sender As Object, _
ByVal cevent As ConvertEventArgs)
' This method converts only to string type.
' Test the type using the 'DesiredType'.

Dim strMessage As String

Try

strMessage = "Test for 'cevent.DesiredType' failed."
If Not cevent.DesiredType Is GetType(String) Then
Return
End If

cevent.Value = CDec(cevent.Value).ToString("P1")

Catch objEx As ArgumentNullException
' Exception is a DBnull Exception. Ignore and move on.
Catch objEx As InvalidCastException
' Exception is a DBnull Exception. Ignore and move on.
Catch objEx As Exception
strMessage = "'CDec()' failed to cast the value to PerCentage."
Call HandleException("Class.FormatParse", objEx, strMessage)
End Try

End Sub

[2985 byte] By [codefund.com] at [2008-2-7]
# 1
Boy this one was a dozzy. I had to look all over the place and finally found the answer in the IL of the Binding object.

So here is the deal. When you setup a binding object with the event handlers defined it does some basic data checks. One is to see if it is Null and another to see if it can convert from the bound property type to the type that is in the datasource.

In your case you have a decimal value coming from the database and your property type is of Object. So, here is what happens. The Binding object checks to see if it can convert the type coming from the datasource to the desired type. The desired type is the type of your property that is bound. (In your case it is Object, for a standard textbox it is String). Now if you know about the types in the framework everything inherits from Object. So, when the binding object checks to see if it can convert from Decimal to object it determines that it does not need to since it is already an object. So it never fires the event.

Now if you change your property to a String it will fire the event since there will be a valid conversion operation Decimal to String.

As far as checking for Nulls is concerned you do not need to by default in the incoming data if you have bound your form since the Binding object converts Null to a default value by default. To see an example bind your Null field to a textbox and it comes back as an empty string.

However to get the Null value to be propegated back to the database you will need to also implement the Parse handler for the binding object to return null to the database if the string is empty. As well in your Format handler you would need to check for null and if found return an empty string.

Hope that helps explain it.

codefund.com at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 2
jcauble -- Thanks a million. I think I understand what you are suggesting. I will make modifiactions to my code and get back to you on results.

I guess the main lesson here is to get more comfortable with the Intermediate Language and the IL Assembler. I'll get back to you on that subject, too.

Once again thanks.

codefund.com at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 3
<quote>
I guess the main lesson here is to get more comfortable with the Intermediate Language and the IL Assembler.
</quote>

Here's the book you'll want for learning that... <a href="http://www.amazon.com/exec/obidos/ASIN/0735614229/qid=1045235433/sr=2-1/ref=sr_2_1/104-7848185-7195907">Applied Microsoft .NET Framework Programming</a>

codefund.com at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 4
HumanCompiler -- Thanks for your study suggestion. Of course, you are referring to Jeffrey Richter's book published by Microsoft Press. There are two version: one in C# and a second on in VB (coauthored by Francesco Balena). I have it, but I am sorry to say that I have not spent the time in it that I should have. Since you posted your message on Friday, I have, and I agree with you. jcauble showed that the IL is a valuable tool.

There is another book for the not faint of heart: “Inside Microsoft .Net IL Assembler” written by Serge Lidin (Microsoft Press). According to the introduction, Mr. Lidin was the designer and developer of the IL Assembler and the ILDASM. So, it appears that this book is "from the horse's mouth". Since jcauble’s response, I have kept this book near to me also.

I was remiss in not giving credit to the person who solved the Null Value problem (not posted here). Ken Spencer had an article in his column Advanced Basics: March 2003 issue of MSDN magazine.

Finally, since many of us now have the Final Beta installed on our machines, we should start noting our version. My example is in version 1.0.

When I have finished testing the changes suggested by jcauble, I will repost the code. I will also retest it in version 1.1 Final Beta and let you know the results.

codefund.com at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 5
.NET 1.1 will support backwards compatibility, fully (or at least it's supposed to) as in you can write a .NET app in 1.0 and it is supposed to fully work in 1.1. You can also write an app in 1.1 and it will be semi-supported when running under 1.0 (only general things will still work)

And yes, I'm curious about the language specific books about the Framework. I'm guessing (but don't know because I haven't read them) that they are less IL specific and more language specific than the general book, but I might be wrong.

codefund.com at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...