Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DesignMode with nested Controls

Has anyone found a useful solution to the DesignMode problem when developing controls?

The issue is that if you nest controls then DesignMode only works for the first level. The second and lower levels DesignMode will always return FALSE.

The standard hack has been to look at the name of the process that is running and if it is "DevEnv.EXE" then it must be studio thus DesignMode is really TRUE.

The problem with that is looking for the ProcessName works its way around through the registry and other strange parts with the end result that the user might not have the required rights to see the process name. In addition this strange route is very slow. So we have had to pile additional hacks to use a singleton and if an error is thrown when asking for the process name then assume that DesignMode is FALSE.

A nice clean way to determine DesignMode is in order. Acually getting Microsoft to fix it internally to the framework would be even better!

like image 956
John Dyer Avatar asked Aug 29 '08 16:08

John Dyer


2 Answers

Revisiting this question, I have now 'discovered' 5 different ways of doing this, which are as follows:

System.ComponentModel.DesignMode property  System.ComponentModel.LicenseManager.UsageMode property  private string ServiceString() {     if (GetService(typeof(System.ComponentModel.Design.IDesignerHost)) != null)          return "Present";     else         return "Not present"; }  public bool IsDesignerHosted {     get     {         Control ctrl = this;          while(ctrl != null)         {             if((ctrl.Site != null) && ctrl.Site.DesignMode)                 return true;             ctrl = ctrl.Parent;         }         return false;     } } public static bool IsInDesignMode() {     return System.Reflection.Assembly.GetExecutingAssembly()          .Location.Contains("VisualStudio")) } 

To try and get a hang on the three solutions proposed, I created a little test solution - with three projects:

  • TestApp (winforms application),
  • SubControl (dll)
  • SubSubControl (dll)

I then embedded the SubSubControl in the SubControl, then one of each in the TestApp.Form.

This screenshot shows the result when running. Screenshot of running

This screenshot shows the result with the form open in Visual Studio:

Screenshot of not running

Conclusion: It would appear that without reflection the only one that is reliable within the constructor is LicenseUsage, and the only one which is reliable outside the constructor is 'IsDesignedHosted' (by BlueRaja below)

PS: See ToolmakerSteve's comment below (which I haven't tested): "Note that IsDesignerHosted answer has been updated to include LicenseUsage..., so now the test can simply be if (IsDesignerHosted). An alternative approach is test LicenseManager in constructor and cache the result."

like image 132
Benjol Avatar answered Oct 08 '22 00:10

Benjol


From this page:

([Edit 2013] Edited to work in constructors, using the method provided by @hopla)

/// <summary> /// The DesignMode property does not correctly tell you if /// you are in design mode.  IsDesignerHosted is a corrected /// version of that property. /// (see https://connect.microsoft.com/VisualStudio/feedback/details/553305 /// and http://stackoverflow.com/a/2693338/238419 ) /// </summary> public bool IsDesignerHosted {     get     {         if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)             return true;          Control ctrl = this;         while (ctrl != null)         {             if ((ctrl.Site != null) && ctrl.Site.DesignMode)                 return true;             ctrl = ctrl.Parent;         }         return false;     } } 

I've submitted a bug-report with Microsoft; I doubt it will go anywhere, but vote it up anyways, as this is obviously a bug (whether or not it's "by design").

like image 34
BlueRaja - Danny Pflughoeft Avatar answered Oct 08 '22 00:10

BlueRaja - Danny Pflughoeft