unam una pareados incompletos hibridos estudios estudio epidemiologia entre diseƱos diferencia controles cohortes cohorte casos caso basicos anidados anidado .net user-controls

.net - una - estudios caso cohorte



DesignMode con controles anidados (11)

¿Por qué no revisas LicenseManager.UsageMode? Esta propiedad puede tener los valores LicenseUsageMode.Runtime o LicenseUsageMode.Designtime.

Si desea que el código solo se ejecute en tiempo de ejecución, use el siguiente código:

if (LicenseManager.UsageMode == LicenseUsageMode.Runtime) { bla bla bla... }

¿Alguien ha encontrado una solución útil al problema de DesignMode al desarrollar controles?

El problema es que si anillas controles, DesignMode solo funciona para el primer nivel. El segundo y más bajo niveles DesignMode siempre devolverá FALSE.

El hack estándar ha consistido en ver el nombre del proceso que se está ejecutando y, si es "DevEnv.EXE", entonces debe ser estudio, por lo que DesignMode es realmente VERDADERO.

El problema con eso es buscar el ProcessName que se abre paso a través del registro y otras partes extrañas con el resultado final de que el usuario puede no tener los derechos necesarios para ver el nombre del proceso. Además, esta extraña ruta es muy lenta. Así que hemos tenido que apilar hacks adicionales para usar un singleton y, si se produce un error al solicitar el nombre del proceso, supongamos que DesignMode es FALSE.

Una buena y limpia forma de determinar DesignMode está en orden. ¡Conseguir que Microsoft lo arregle internamente en el framework sería aún mejor!


Como ninguno de los métodos es confiable (DesignMode, LicenseManager) o eficiente (procesos, comprobaciones recursivas), estoy usando un public static bool Runtime { get; private set } public static bool Runtime { get; private set } a nivel de programa y explícitamente configurándolo dentro del método Main ().


De esta página :

( [Editar 2013] Editado para trabajar en constructores, utilizando el método proporcionado por @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://.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; } }

He enviado un informe de error con Microsoft; Dudo que vaya a ir a ninguna parte, pero vote de todos modos, ya que esto es obviamente un error (ya sea o no "por diseño" ).


DesignMode es una propiedad privada (por lo que puedo decir). La respuesta es proporcionar una propiedad pública que expone el accesorio DesignMode. Luego puede cascasde una copia de seguridad de la cadena de controles de usuario hasta que se encuentre con un control que no sea de usuario o un control que esté en modo de diseño. Algo como esto....

public bool RealDesignMode() { if (Parent is MyBaseUserControl) { return (DesignMode ? true : (MyBaseUserControl) Parent.RealDesignMode; } return DesignMode; }

Donde todos sus UserControls heredan de MyBaseUserControl. Alternativamente, podría implementar una interfaz que exponga el "RealDeisgnMode".

Tenga en cuenta que este código no es un código en vivo, solo fuera de las reflexiones del manguito. :)


Este es el método que uso dentro de formularios:

/// <summary> /// Gets a value indicating whether this instance is in design mode. /// </summary> /// <value> /// <c>true</c> if this instance is in design mode; otherwise, <c>false</c>. /// </value> protected bool IsDesignMode { get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; } }

De esta forma, el resultado será correcto, incluso si alguna de las propiedades DesignMode o LicenseManager falla.


Mi sugerencia es una optimización de la respuesta @ blueraja-danny-pflughoeft. Esta solución no calcula el resultado todas las veces, sino solo la primera vez (un objeto no puede cambiar UsageMode del diseño al tiempo de ejecución)

private bool? m_IsDesignerHosted = null; //contains information about design mode state /// <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 https://.com/a/2693338/238419 ) /// </summary> [Browsable(false)] public bool IsDesignerHosted { get { if (m_IsDesignerHosted.HasValue) return m_IsDesignerHosted.Value; else { if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) { m_IsDesignerHosted = true; return true; } Control ctrl = this; while (ctrl != null) { if ((ctrl.Site != null) && ctrl.Site.DesignMode) { m_IsDesignerHosted = true; return true; } ctrl = ctrl.Parent; } m_IsDesignerHosted = false; return false; } } }


No me había dado cuenta de que no puedes llamar a Parent.DesignMode (y también aprendí algo sobre ''protected'' en C # ...)

Aquí hay una versión reflectante: (sospecho que podría haber una ventaja en el rendimiento al hacer que designModeProperty sea un campo estático)

static bool IsDesignMode(Control control) { PropertyInfo designModeProperty = typeof(Component). GetProperty("DesignMode", BindingFlags.Instance | BindingFlags.NonPublic); while (designModeProperty != null && control != null) { if((bool)designModeProperty.GetValue(control, null)) { return true; } control = control.Parent; } return false; }


Nunca he sido atrapado por esto, pero ¿no podrías simplemente caminar por la cadena Parent desde el control para ver si DesignMode está ubicado en algún lugar por encima de ti?


Revisando esta pregunta, ahora he ''descubierto'' 5 maneras diferentes de hacer esto, que son las siguientes:

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")) }

Para tratar de entender las tres soluciones propuestas, creé una pequeña solución de prueba, con tres proyectos:

  • TestApp (aplicación winforms),
  • SubControl (dll)
  • SubSubControl (dll)

Luego incrustó SubSubControl en SubControl, luego uno de cada uno en TestApp.Form.

Esta captura de pantalla muestra el resultado cuando se ejecuta.

Esta captura de pantalla muestra el resultado con el formulario abierto en Visual Studio:

Conclusión: parece que sin reflexión, el único que es confiable dentro del constructor es LicenseUsage, y el único que es confiable fuera del constructor es ''IsDesignedHosted'' (por BlueRaja abajo)

PD: Ver el comentario de ToolmakerSteve a continuación (que no he probado): "Tenga en cuenta que la respuesta IsDesignerHosted se ha actualizado para incluir LicenseUsage ..., por lo que ahora la prueba puede ser simplemente if (IsDesignerHosted). Un enfoque alternativo es probar LicenseManager en el constructor y almacena el resultado en caché ".


Usamos este código con éxito:

public static bool IsRealDesignerMode(this Control c) { if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime) return true; else { Control ctrl = c; while (ctrl != null) { if (ctrl.Site != null && ctrl.Site.DesignMode) return true; ctrl = ctrl.Parent; } return System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"; } }


Utilizo el método LicenseManager, pero guardo en caché el valor del constructor para usarlo durante toda la vida de la instancia.

public MyUserControl() { InitializeComponent(); m_IsInDesignMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime); } private bool m_IsInDesignMode = true; public bool IsInDesignMode { get { return m_IsInDesignMode; } }

Versión VB:

Sub New() InitializeComponent() m_IsInDesignMode = (LicenseManager.UsageMode = LicenseUsageMode.Designtime) End Sub Private ReadOnly m_IsInDesignMode As Boolean = True Public ReadOnly Property IsInDesignMode As Boolean Get Return m_IsInDesignMode End Get End Property