It's amazing how your work suddenly vanishes into the air after spending the weekend coloring, resizing and moving around your well polished controls.
Q: Can you prevent that from ever happening?
A: Can't promise, however, here are a couple of tips to follow that helped me many times in overcoming this drama.
If you are a regular user of the V1.x VS.NET design-time environment (in C# at least, I don't do much by way of VB, so I can't comment) then you will no doubt be well aware of the effects of the amazing self-destructive design-time environment. If you are one of the lucky few who hasn't, I'll explain the symptoms.
You have been happily working in the designer, laying out controls, binding in bits of logic, switching between the code view and the designer view, building, debugging. Then, all of a sudden, half your controls disappear, and/or some move to the top left, and/or all your embedded resources (images in particular) vanish without trace... Control-Z doesn't seem to work quite right... The black gloom of despair fogs the monitor, and you're forced to go and get a really strong cup of coffee. Before you start again.
In the office, we call it "the woe", and it has happened to us...a lot.. Working out why it happens is rather tricky. Finding a reliable repro is nearly impossible; but we have found some of the contributing factors, reliable ways to avoid the problem - and how to mitigate it when it does occur.
The first thing to understand is that the problem is a defect in the round-tripping of the code that the designer generates in the
InitializeComponent() method. Basically, when things go awry, it sometimes panics and just leaves some of it out. It doesn't affect the members inserted at the top of the file (the fields that hold the references to the child controls stay put), only the initialization code. That's why, when the problem occurs, you can't just add controls with the same names as the ones that vanished. They conflict with these disembodied fields. This leads me to tip number 1, for people who have already suffered the woe. (See Tip 5 for how to mitigate the woe as it occurs).
One of the most common reasons of the woe is deleting a resource while some control in your application it is still referring to that resource. If it does happen, you will see the above picture in which we are still referring somewhere in the code to a bitmap resource with the name "download_linux"
Dealing with such kind of woes is easy, all you have to do is to go to the form designer class..
Find the missing resource named in the error message as displayed in the first snapshot of this article.
Now replace the missing resource reference with a valid one. I would always comment the old reference and set the container control to
this.pictureBox1.Image = null;
Clean & Clear
Another form of the woe is what I would call "clean and clear" in which the designer is restarting your work as if you've just created a new form.
Dealing with this kind of woe can be quite tricky, however, the first thing you should try is to simply restart the IDE without panicking and saving before restarting.
If it's still Clean & Clear, try the following:
- Close the Clean & Cleared designer tab
- Close the IDE
- Go to the solution's folder and move the Clean & Cleared designer class "usually suffixed by (.Designer.cs)" to another folder
- Open the IDE again and delete the moved class node from the solution explorer Window
- From Project go to 'Add Existing Item' and browse for the previously moved designer class and you are done
Still Can't deal with it
A couple of tips to follow to overcome/cut down the woe occurrence number are listed below…
If you have a saved, corrupted file and are trying to recover from the woe, clean up the orphaned fields so that you can reuse the names
But ideally we would avoid the woe completely! What we want is a procedure for working with WinForms projects in the IDE that won't break. How might we go about this?
Well, the problem usually occurs because you don't have a clean, working build of the solution including all the dependencies of your designable control. Now - most of the time, this isn't an issue. After all, you can use the designer right out of the box, without having built the solution at all. But if you have a control from another assembly (or even this assembly!) on your design surface, and it is not built 100% successfully and copied somewhere, it can be referenced by the design time environment (the project directories will do), then you invite the possibility of the woe. Therefore, you should follow tip 2.
Always do a complete solution build before attempting to open any designers
Unfortunately, by default, the VS.NET IDE will reopen the views you had open when you last closed the solution; which is not that great if the solution is not cleanly built when you open it again. Therefore, you should also apply tip 3.
Always close all of the designer windows before closing the solution
OK, so now we do a build. If it doesn't build cleanly, refer to Tip 2, and then use the code editors only to clean up until it builds successfully.
When it does build cleanly, we can open a designer, do our layout, add code etc. All should be well. When we are ready to try a build and test, apply Tip 4.
Close all designer Windows before doing a build
I can't say this often enough. Never, never build the solution without closing all designers. In fact, it is probably a good idea to write a macro to do this for you, and replace the build/run/debug shortcuts, buttons and menus with calls to this instead. Or be very disciplined. You will get away with it 9 times out of 10, and the tenth time...kaboom.
OK, we've closed the designer Windows and kicked off the build. If the build fails - refer to Tip 2. Don't forget - you have to clean everything up so that it builds using only the code editors. Don't accidentally open a designer... When it builds clean, you can rinse and repeat.
If you follow those guidelines, you'll avoid 99% of all the cases of the woe. But there are a couple more categories of misfortune that can befall us...
The first occurs when we reference controls from an external assembly that is pre-built (i.e. we reference the assembly itself, rather than a project in the solution). You open up the designer, and either the controls have vanished from the surface, or you get a design-time exception (the block of misery-inducing text that indicates the designer has had a panic with your control). Firstly, apply Tip 5. Tip 5 is very useful!
In Case of Woe, Don't Panic. Don't press save. Don't press undo. Just close the designer Window (and any applicable code Windows) and say "no - I don't want to save the changes".
If you do this, then the messed-up code won't be saved. It will revert to the version prior to the designer being opened. Tip 5 is also useful if you accidentally break any of the guidelines in Tips 2-4.
So - what causes this particular issue? It seems to be something to do with the design time environment failing to find references that it had no issue with a moment ago. The files haven't moved, no-one has recompiled them. The designer has just taken against them. You can close the IDE and reload it, and it still doesn't work. So, apply Tip 6.
Remove the references to the assemblies that contain the controls that vanished, and add them back again
You can then reopen the designer and all should be well...
Finally, there's the nastiest of the problems. You can build a control that has an implementation bug that causes an exception at design time. Everything will build fine, but when you reopen the designer you'll see the exception text. As usual, the designer can recover from this 9 times out of ten, but the tenth time induces the Woe.
Recovery is simple - you should first apply Tip 5 and then fix the problem using the code editor only. Fixing it can be tricky. If inspection doesn't work, a handy tip is to open a second IDE, and attach to the original instance of VS.NET. You can then set some breakpoints in your control and watch what happens as you open the designer.
Some of these tips are a bit tedious, and require some discipline, but if you follow the guidelines, you should avoid the woe almost completely, and easily be able to recover if it does occur.
Some of the contents of this article belongs to some bloger. I couldn't even find his name on the offline page I'm keeping, neither the URL of that page, so please if you're the guy, post your name here because I personally owe you a lot for sharing your experience dealing with "the woe".
Also thanks to our friend Martin for suggesting me to post this article.