Lies, Damn Lies, and Microsoft Function Names

When creating custom controls you may want your control to not do certain things when it is being used inside the Visual Studio forms designer. Perhaps in the constructor for your control you want to connect to a database, or maybe create a window, or whatever but only want that to happen at run time.

Behold, there appears to be just the function you want – DesignMode – a nice little boolean you can query in your code.

But beware ! This little doozey is incorrectly named. It should be named “TheDesignerCanAccessMyPropertiesAndIHaveAnISiteAndImInDesignMode”. You see,

  1. DesignMode isn’t set until an ISite is assigned to your control (its this ISite that actually provides the DesignMode value) and occurs in the background some time after your constructor is called.
  2. It only applies directly to the controls that the designer can modify at that time. For example, if you open a form that has a control (‘A’) on it, both will be in DesignMode. However, if control ‘A’ has any child controls, those child controls will not be in DesignMode ! The way to look at it is the designer can access properties for the form and control ‘A’ – so those will (at some point) have working DesignMode properties, however the designer doesn’t directly access control ‘B’s properties at all so control ‘B’s DesignMode will always false.

Oh cripes ! What are we going to do ?

Forms and User Controls

Well, assuming you can live with point #2 above and if you are deriving from System.Windows.UserControl or System.Windows.Form then perhaps you could override OnCreateControl and do your initialisation there instead, since their Site property will have been initialised before then and hence DesignMode will be reliable. To be honest, OnCreateControl is often a better place to perform initialisation than the constructor.

What if you can’t live with point #2 ? Well, you could rely on whoever designed Control ‘B’ to recurse up through the Parent properties until you either find one with DesignMode set to true, or until you reach the top (Parent = null) in which case you you aren’t design mode.

Components

Typically you derive from System.ComponentModel.Component when designing components you can drop on a form but in fact live on that panel at the bottom of the designer (where you often find your SystemMenu, Timers, or such like]. The clue to the answer is my alternative name for Micro$oft’s DesignMode i.e.

TheDesignerCanAccessMyPropertiesAndIHaveAnISiteAndImInDesignMode

 You can override the Site property and when it is being set to a non-null value you can query the supplied ISite‘s DesignMode and perform your initialisation based on that value.

As for getting around point #2 … well, good luck with that one !

Must Be A Better Way!?

Are there any other ways ? Well, there is System.ComponentModel.LicenseManager.UsageMode (yes, thats right, LicenseManager!) which you can query to see if it’s value is set to “runtime” but if MSDN is to believed (and why not, it is known to be a 100% reliable source of information isn’t it [snigger]) it requires at least Vista SP2. Oh, and it might only work in a constructor – it certainly doesn’t work inside events.

Must Be A Better Way Mk.II ?

Assuming for a moment you only program using VisualStudio under Windows and not some other environment (such as the excellent Mono). Well, you could get the name of the currently running process and see if it is called “devenv” [Hack alert, awooga! awooga!]. One line of code to fix it in all situations and you aren’t limited to forms, user controls and components, any class can do it:

ReallyInDesignMode

 

Which, of course, will work right up to the point where Micro$oft find out we are doing this and go and change it in the next Visual Studio service pack just to annoy us.

Must Be A Better Way Mk.III ?

Yep, there is just one more way we can tackle this problem:

Petition Micro$oft to give us a DesignMode property that tells us when we are in design mode !. Sheesh !

But don’t hold your breath …..

Leave a Reply