sirve - tooltip visual studio c#
Reglas de tiempo de diseƱo de.NET Windows Forms (5)
Bueno, como esto ha sido resucitado de todos modos, esta es la función que uso para determinar si estoy en modo de diseño:
public static bool IsAnyInDesignMode(Control control){
while(control != null){
if(control.Site != null && control.Site.DesignMode)
return true;
control = control.Parent;
}
return false;
}
Esto maneja el caso donde el control es un niño creado por otro control. La propiedad DesignMode
solo está configurada para los controles creados por el propio diseñador.
Tengo un objeto que inicia un hilo, abre un archivo y espera la entrada de otras clases. A medida que recibe la entrada, la escribe en el disco. Básicamente, es una clase de registro de datos segura para subprocesos ...
Aquí está la parte extraña. Cuando abro un formulario en el diseñador (Visual Studio 2008) que usa el objeto, se crea el archivo. Obviamente se ejecuta bajo el proceso de diseño vhost de tiempo ...
Lo curioso es que no he podido reproducir el problema en otro proyecto. No estoy seguro de cuáles son las reglas para el código que se ejecuta en el diseñador y el código que no. Por ejemplo, crear un archivo en un constructor de Windows Forms en realidad no crea el archivo en el momento del diseño ...
¿Cuál es la explicación? Hay una referencia?
El constructor de un control o formulario no se ejecuta al editar esa clase en el diseñador (ni se llama a OnLoad). En ocasiones, he usado esto para establecer un valor en el diseñador (por ejemplo, hacer que sus controles secundarios sean visibles en el diseñador) pero anular algunos de ellos en un valor predeterminado diferente en el constructor (por ejemplo, ocultar ciertos controles secundarios que solo mostrarán en ciertas circunstancias, como un indicador en una barra de estado).
Sin embargo, el constructor se ejecuta si el control se coloca como secundario en otro control o formulario en el diseñador. OnLoad también se ejecuta. Esta es la forma en que el código de inicio de sesión se activó accidentalmente en el diseñador.
Para detectar el diseño frente al tiempo de ejecución, una respuesta a otra pregunta tiene capturas de pantalla de algunas pruebas empíricas que muestran los valores devueltos por algunos enfoques comunes. Parece que un control secundario de un control secundario (dos niveles hacia abajo) del formulario o control que se está editando en el diseñador ve su propio DesignMode == false, por lo que la comprobación de propiedad normal no protegerá el código (por ejemplo, en el método OnLoad ) para controles anidados dentro de un control agregado en el diseñador. Si estaba comprobando DesignMode como uno esperaría, podría ser el anidamiento lo que provocó que eludiera ese control. También siempre ve DesignMode == false dentro del constructor.
Además, tenga en cuenta que la comprobación LicenseManager.UsageMode solo ve DesignTime dentro del constructor; cuando se llama a OnLoad, está dentro de un RunTime LicenseContext. La solución más completa parece ser comprobar LicenseManager.UsageMode en el constructor del control o formulario (o componente) y guardar la configuración en una variable miembro o propiedad que puede verificar más adelante para evitar ejecutar código que nunca debería ejecutarse en el diseñador incluso cuando está anidado También hay otro enfoque en otra respuesta a esa otra pregunta que explica el anidamiento pero que solo funciona fuera del constructor.
Hay algunas cosas que no debes hacer con el diseñador. No tengo ninguna evidencia sólida, pero descubrí que el diseñador de Windows Forms lo odia cuando le quitas el constructor predeterminado. Simplemente siga adelante y cree nuevas sobrecargas, pero deje el constructor vacío en su lugar.
También trate de evitar hacer eventos de Form_Load
en las clases base de las que hereda.
Puede verificar UsageMode del LicenseManager para verificar si el código está en tiempo de diseño o no.
System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime
Aquí hay un ejemplo rápido:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Test
{
public class ComponentClass : Component
{
public ComponentClass()
{
MessageBox.Show("Runtime!");
}
}
}
Cuando este componente se agrega a su formulario en el diseñador, inmediatamente obtendrá un cuadro de mensaje.
Para evitar esto, puede agregar una instrucción if simple para verificar si el código no está en tiempo de diseño
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Test
{
public class ComponentClass : Component
{
public ComponentClass()
{
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
MessageBox.Show("Runtime!");
}
}
}
}
Después de agregar la instrucción if, el cuadro de mensaje ya no aparece cuando el componente se agrega al formulario a través del diseñador.
Espero que esto ayude.
-jeremy
También puede usar esto para verificar si Visual Studio Designer ejecuta el código:
public static bool DesignMode
{
get { return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); }
}
Luego en Form_Load:
if (!DesignMode)
{
// Run code that breaks in Visual Studio Designer (like trying to get a DB connection)
}
Sin embargo, esto es menos elegante que usar LicensManager.UsageMode
, pero funciona (hasta que Microsoft cambie el nombre del proceso en el que se ejecuta Visual Studio).