I cross-posted this comment on another question but since this is related here it is again.
When a User Control won't load into the Visual Studio designer here is what you need to do. These instruction are for vb.net project but c# should be similar. Also, before doing this close all open windows (or at least the source and designer files of the control you are working on.)
One last thing. The FIRST thing you should do is ensure that restarting visual studio doesn't fix the problem. If not you can try the steps that follow. These instructions assume that the errant user controls are in control library project in visual studio. If not you should be able to adjust the directions a bit to get it to work but it is much easier when the control is in its own project.
Do the following:
- Make the control library your startup project.
- Open the properties for the control library project and click on the debug tab.
- Under Start Action click the Start external program option and browse to the Visual Studio executable.
NOTE: what this means is that when you run your solution it will fire up another instance of Visual Studio instead of actually running your solution. The First Instance of Visual Studion (INSTANCE_1) will "host" a second instance of visual studio (INSTANCE_2) when you run it.
- Run your solution. INSTANCE_2 will load.
- Switch back to INSTANCE_1.
- In INSTANCE_1 hit CTRL-ALT-E. This will open up the exceptions dialog box. Check On the THROWN column checkbox next to Common Language Runtime Exceptions.
NOTE: This will ensure that INSTANCE_1 will BREAK at ANY runtime error even if it is hit in a try block.
- Switch to INSTANCE_2. In Solution Explorer double-click to open the errant user control.
You should find that INSTANCE_1 OF Visual Studio should have stopped at the line of code that caused the designer to not load the control. Fix the code (which usually means testing for IsNot Nothing before references an object properties...but could mean other things.)
Also, sometimes I find that the control WILL load in INSTANCE_2 instead of breaking on an error in INSTANCE_1. In that case just stop debugging...close INSTANCE_2. Save/Restart INSTANCE_1 and your problem will often have gone away.
The lesson is this. User Control MUST be able to load/reference all objects and their members in order to load it into the designer. So for User Controls that will be placed onto other containers I will usually design events to notify the parent rather than trying to push objects into the child control.
Hope this helps for future reference on this old question.
Seth
This question was the subject of my blog on May 30th 2013. Thanks for the great question!
You're staring at an empty driveway.
Someone asks you "can your driveway hold a Honda Civic?"
Yes. Yes it can.
Someone points you at a second driveway. It is also empty. They ask "Can the current contents of my driveway fit in your driveway?"
Yes, obviously. Both driveways are empty! So clearly the contents of one can fit in the other, because there are no contents of either in the first place.
Someone asks you "Does your driveway contain a Honda Civic?"
No, it does not.
You're thinking that the is
operator answers the second question: given this value, does it fit in a variable of that type? Does a null reference fit into a variable of this type? Yes it does.
That is not the question that the is
operator answers. The question that the is
operator answers is the third question. y is X
does not ask "is y
a legal value of a variable of type X
?" It asks "Is y
a valid reference to an object of type X
?" Since a null reference is not a valid reference to any object of any type, the answer is "no". That driveway is empty; it doesn't contain a Honda Civic.
Another way to look at it is that y is X
answers the question "if I said y as X
, would I get a non-null result? If y is null, clearly the answer is no!
To look a little deeper at your question:
One expects that the null value belongs to any reference (or nullable) type
One would be implicitly assuming that a type is a set of values, and that assignment compatibility of a value y with a variable of type X is nothing more nor less than checking whether y is a member of set x.
Though that is an extremely common way of looking at types, that is not the only way of looking at types, and it is not the way that C# looks at types. Null references are members of no type in C#; assignment compatibility is not merely checking a set to see if it contains a value. Just because a null reference is assignment compatible with a variable of reference type X does not mean that null is a member of type X. The "is assignment compatible with" relation and the "is a member of type" relation obviously have a lot of overlap, but they are not identical in the CLR.
If musings about type theory interest you, check out my recent articles on the subject:
What is this thing you call a "type"? Part one
What is this thing you call a "type"? Part Two
Best Solution
There are a couple of options here. First, BrowsableAttribute only determines whether the property shows up in the property grid. To prevent the property from being serialized at all, use the DesignerSerializationVisibilityAttribute:
Second, if you want the property to be serialized, but only when the user has actually changed the value, use the DefaultValueAttribute:
This will cause the property to only be serialized if it is different from its default value. This also has other positive side-effects
There are more advanced techniques for controlling property interaction with the designer (Google "ShouldSerialize"), but these attributes should get you most of the way there.