tags:

views:

193

answers:

1

I've seen multiple posts and questions about the DesignMode property of Forms and UserControls. The idea is that you want to check if the control is in design mode (e.g. the control is shown in the Visual Studio Designer), and avoid code that can only be run in, well, run-time. The problem I've seen many have - and my failing memory exposed me to it too, recently - is that the DesignMode property does not work in the constructor, and does not work for the nested controls. However, it works extremely well in the Load event handler for your control or form!!

When you think about it, the code in the constructors of the Forms or UserControls should only deal with state that does not require the form to be loaded. Code dealing with UI objects initialization should maybe be located in the Load event handler for the control. And in that function, the DesignMode property works. The Designer will use its proper value at that time.

In principle, the InitializeComponent() method has been called but in reality, when you show the control in Design view, the Designer only parses that function, it does not run it. The Designer, however, does run the constructor of nested controls. If you absolutely need to put initialization code in the constructor, use theSystem.ComponentModel.LicenseManager class, it has a static property called UsageMode which takes values of DesignTime or RunTime. You can absolutely trust that property in the constructor of your control - but in the constructor only!

I had forgotten that little subtlety in the app I am working on at the moment. To get around the issue, I am adhering now to the pattern that all controls and forms which need extra initialization must implement a handler for the Load event. There, the DesignMode property works just fine, and I never have trouble opening my user control and forms in the Designer.

If I have a class hierarchy, I sometimes make that event handler virtual protected, and I only override it when the subclass needs extra initialization.

I am wondering, though, if there are better methods out there, or if there is something smelly about this pattern (other that having to implement a Load event handler many times?)

A: 

Because of the issues with using the DesignMode property with nested controls (and related problems), my general approach to this problem is to not even try to get my custom UserControls to function in design mode. Usually my controls are very complicated and owner-drawn, so even if the DesignMode worked with nested controls, it would take a great deal of programming effort to get them to show anything meaningful in design mode (and it would slow down development work, because the controls require a significant amount of initialization and setup time).

Usually I just add a public Setup() or LoadData() method that does all the work, and only call this method at runtime. In design mode, then, the UserControl just shows up as a square, which helps me position it and nothing more.

I'm interested in seeing if you get any other answers to this question, however, that might address your problems.

MusiGenesis
It's a real convenience to be able to look at your control in design view, especially if you want to sub-class them. If you don't, then at least a frame for the layout of the control in a form is just fine (like you are doing).If the control uses a lot of standard and you need to tinker with the positions, properties or with the event handlers of the components of the control, then a realistic-looking Design view becomes important.Besides, I think it's rewarding to know that my control can be used by someone who may not have the code for it :).
Sam Dahan
@Sam: I totally agree with everything you say, and sometimes I get drawn into trying to make my controls work in design mode. As soon as I run into serious problems, though, I usually quit, although sometimes not soon enough.
MusiGenesis