Things I Learned Today
In VB.NET, a string with a value of Nothing is treated as equivalent to “”. Thus,
dim myString as String = Nothingif myString = "" then Debug.Print "myString is blank"
will in fact print “myString is blank”. On the surface, this seems fairly helpful because it can eliminate exceptions when comparing myString (Nothing) to an empty string. And, you can still detect if it is Nothing. So what’s the problem?
Well, in Property setters, a common pattern goes like this:
public property MyString as String Get ... End Get Set (Value as String) if _myString Value then _myString = Value RaiseEvent MyStringChanged(Me, Nothing) end if End SetEnd property
(this pattern is useful to achieve proper 2-way objectcontrol data binding)
The problem becomes that when you set a property this way, and the new value = “”, then _myString never gets set. And the string variable stays as Nothing, i.e. uninitialized. Annoying, and in my case a source of a bug. Which leads me to….
The other thing I learned today was that WinForms Data Binding eats errors. That is, when an error occurs inside of the Microsoft binding code, it is not propogated; it simply disappears. You can see that exceptions have occurred by watching the .NET Exceptions counter in Windows Performance Monitor, or the .NET tab on a process in SysInternals Process Explorer.
In my case, the symptom was that when tabbing through controls, the tab would not leave the control with the error. Clicking on the next control would also not work, although clicking elsewhere on the app worked ok.
The cause was an error in either of the bound properties, i.e. the Control.Text property, or the object property that I was binding to. If the Property Set of either of these gives an error, then the above-mentioned symptom occurs. My particular problem was that I do not expect my object properties to ever be set to Nothing, so my control could give an error when that happened (Control.Text = Nothing).