2008-11-11 7 views
10

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 seguro de subprocesos ....NET Windows Forms, reglas de tiempo de diseño

Aquí está la parte extraña. Cuando abro un formulario en el diseñador (Visual   Studio   2008) que utiliza el objeto que se crea el archivo. Obviamente se ejecuta bajo el proceso de diseño vhost ...

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 no crea realmente el archivo en tiempo de diseño ...

¿Cuál es la explicación? Hay una referencia?

Respuesta

11

Puede verificar el 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í está 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 al formulario en el diseñador, que inmediatamente recibirá un cuadro de mensaje.

Para evitar esto se puede añadir un simple if para comprobar 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 la adición de la sentencia if, el cuadro de mensaje ya no aparece cuando se añade el componente a la forma a través del diseñador.

Espero que esto ayude.

-Jeremy

0

Hay algunas cosas que no debe 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 intente evitar los eventos en las clases base que hereda.

2

También puede utilizar esto para comprobar si el diseñador de Visual Studio se 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 el LicensManager.UsageMode, pero funciona (hasta que Microsoft cambie el nombre del proceso en el que se ejecuta Visual Studio).

+0

hombre, su método de "menos elegante" es el único que funciona. El LicensManager.UsageMode no funciona, p. cuando el diseñador invoca un método de "obtención de propiedad" de un control de usuario. – Soonts

11

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 diseño frente a tiempo de ejecución, an answer a another question tiene capturas de pantalla de algunas pruebas empericales 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 LicenseManager.UsageMode check only 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 another answer a esa otra pregunta que explica el anidamiento pero solo funciona fuera del constructor.

+0

Creo que esto puede ayudarme. ¡Gracias! ++ – John

+0

Corrección: me ayudó. :) – John

+0

¡Genial! Alegra oírlo. –

2

Bueno, ya que esto ha sido resucitado de todos modos, aquí está la función que utilizo 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; 
} 

Esta Trata el caso en el que 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.

Cuestiones relacionadas