Detectando el modo de diseño desde el constructor de un Control

A continuación de esta pregunta , ¿es posible detectar si uno está en modo de diseño o tiempo de ejecución desde el constructor de un objeto?

Me doy cuenta de que esto puede no ser posible, y que tendré que cambiar lo que quiero, pero por ahora estoy interesado en esta pregunta específica.

Puede usar la enumeración LicenceUsageMode en el espacio de nombres System.ComponentModel :

 bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime); 

Estás buscando algo así:

 public static bool IsInDesignMode() { if (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1) { return true; } return false; } 

También puede hacerlo al verificar el nombre del proceso:

 if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv") return true; 

Componente … hasta donde yo sé, no tiene la propiedad DesignMode. Esta propiedad es provista por Control. Pero el problema es cuando CustomControl está ubicado en un Formulario en el diseñador, este CustomControl se está ejecutando en modo de tiempo de ejecución.

He experimentado que la propiedad DesignMode funciona correctamente solo en Formulario.

IMPORTANTE

¡Hay una diferencia al usar Windows Forms o WPF !

Tienen diferentes diseñadores y necesitan diferentes controles . Además, es complicado cuando mezclas formularios y controles WPF. (por ejemplo, controles WPF dentro de una ventana de Formularios)

Si solo tiene Windows Forms , use esto:

 Boolean isInWpfDesignerMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime); 

Si solo tiene WPF , use este control:

 Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); 

Si ha mezclado el uso de Forms y WPF, use un cheque como este:

 Boolean isInWpfDesignerMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime); Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); if (isInWpfDesignerMode || isInFormsDesignerMode) { // is in any designer mode } else { // not in designer mode } 

Para ver el modo actual, puede mostrar un MessageBox para la depuración:

 // show current mode MessageBox.Show(String.Format("DESIGNER CHECK: WPF = {0} Forms = {1}", isInWpfDesignerMode, isInFormsDesignerMode)); 

Observación:

Necesita agregar los espacios de nombres System.ComponentModel y System.Diagnostics .

Debería usar la propiedad Component.DesignMode. Hasta donde yo sé, esto no debería ser usado por un constructor.

Otro método interesante se describe en ese blog: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or -modo de usuario/

Básicamente, prueba que el conjunto de ejecución esté referenciado estáticamente desde el ensamblaje de entrada. Evita la necesidad de rastrear nombres de ensamblado (‘devenv.exe’, ‘monodevelop.exe’ …).

Sin embargo, no funciona en todos los otros escenarios, donde el ensamblaje se carga dinámicamente (VSTO es un ejemplo).

Los controles (Forms, UserControls, etc.) heredan la Component class que tiene la bool property DesignMode así:

 if(DesignMode) { //If in design mode } 

Con la cooperación del diseñador … Se puede usar en Controles, Componentes, en todos los lugares

  private bool getDesignMode() { IDesignerHost host; if (Site != null) { host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost; if (host != null) { if (host.RootComponent.Site.DesignMode) MessageBox.Show("Design Mode"); else MessageBox.Show("Runtime Mode"); return host.RootComponent.Site.DesignMode; } } MessageBox.Show("Runtime Mode"); return false; } 

MessageBox.Show( líneas se deben eliminar. Solo me aseguran de que funcione correctamente).

La solución de LicenseManager no funciona dentro de OnPaint, ni tampoco esto. DesignMode. Recurrí a la misma solución que @Jarek.

Aquí está la versión en caché:

  private static bool? isDesignMode; private static bool IsDesignMode() { if (isDesignMode == null) isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains("devenv")); return isDesignMode.Value; } 

Tenga en cuenta que esto fallará si está utilizando un IDE de un tercero o si Microsoft (o su usuario final) decide cambiar el nombre del ejecutable VS a otro que no sea ‘devenv’. La tasa de fallas será muy baja, solo asegúrate de lidiar con cualquier error resultante que pueda ocurrir en el código que falla como resultado de esto y todo irá bien.

Si desea ejecutar algunas líneas cuando se está ejecutando pero no en el diseñador de Visual Studio, debe implementar la propiedad DesignMode de la siguiente manera:

 // this code is in the Load of my UserControl if (this.DesignMode == false) { // This will only run in run time, not in the designer. this.getUserTypes(); this.getWarehouses(); this.getCompanies(); }