Solución de problemas relacionados con el desarrollo en tiempo de diseño

Cuando crea una experiencia en tiempo de diseño personalizada se pueden producir los siguientes problemas comunes con respecto a los componentes y controles de formularios Windows Forms:

  • No se puede compilar

  • No es posible la depuración en tiempo de diseño

  • Error del compilador: "No se puede encontrar el tipo o el nombre de espacio de nombres 'nombre de tipo'".

  • Error en tiempo de diseño: "Error al crear el componente 'nombre de componente'".

  • Error de depuración: "Operación no válida a través de subprocesos: Se tuvo acceso al control 'nombre de control' desde un subproceso distinto de aquel en que lo creó".

  • Error en tiempo de diseño: "No se puede abrir un diseñador para el archivo porque la clase que contiene no hereda de una clase que se pueda diseñar visualmente".

  • Los glifos permanecen después de que se elimine el componente

  • Comportamiento predeterminado del diseñador oculto por el comportamiento personalizado

  • Eventos de diseñador provocados de forma no deseada

  • Las colecciones no realizan la serialización

  • El diseñador no adquiere una referencia UndoEngine

  • El entorno de diseño no reconoce cambios en las propiedades del componente

  • Sintaxis de DesignerAttribute

  • Actualizar el entorno de diseño después de realizar cambios en el componente o diseñador

  • Advertencia de FxCop sobre un formulario Windows Forms recién generado: DoNotInitializeUnnecessarily

  • Clases parciales y el Diseñador de Windows Forms

  • Los controles personalizados heredados producen un comportamiento inesperado del Diseñador

  • Las etiquetas inteligentes en un diseñador hospedado producen excepciones

  • El icono del componente no aparece en el cuadro de herramientas

No se puede compilar

Para una parte significativa del desarrollo en tiempo de diseño, debe agregar una referencia al ensamblado en tiempo de diseño, System.Design.dll. Este ensamblado no está incluido en .NET Framework 4 Client Profile. Para agregar una referencia a System.Design.dll, debe cambiar la versión de .NET Framework de destino del proyecto a .NET Framework 4.

No es posible la depuración en tiempo de diseño

Hay dos maneras de depurar el código en tiempo de diseño:

  • Realizar llamadas MessageBox.Show en los puntos estratégicos del código.

  • Asociar otra instancia de Visual Studio para depurar el entorno de diseño de la primera instancia.

Para obtener más información, consulte Cómo: Obtener acceso a servicios en tiempo de diseño.

Error del compilador: "No se puede encontrar el tipo o el nombre de espacio de nombres 'nombre de tipo'"

Debería hacer referencia al ensamblado System.Design. Los tipos relacionados con el Diseñador están ubicados en el ensamblado System.Design. Esto incluye los tipos en los espacios de nombres System.Windows.Forms.Design y System.ComponentModel.Design.

Asimismo, debe asegurarse de importar los espacios de nombres que necesita mediante las palabras clave Imports o using. Para obtener más información, vea Cómo: Obtener acceso a las funciones en tiempo de diseño de formularios Windows Forms.

Error en tiempo de diseño: "Error al crear el componente 'nombre de componente'"

Puede recibir este error cuando está creando su componente o control en la superficie de diseño desde el Cuadro de herramientas. En la siguiente tabla se muestran las dos causas probables de este error.

Causa

Descripción

Notas

Falta el constructor predeterminado

El componente o control debe tener un constructor predeterminado, que es un constructor sin parámetros.

El entorno de diseño necesita un constructor predeterminado para poder crear una instancia de su tipo.

El componente es un tipo genérico

Su componente o control no puede ser un tipo genérico, también denominado tipo de plantilla o tipo parametrizado. El entorno de diseño no admite tipos genéricos.

Si su tipo genérico deriva de UserControl e intenta ejecutarlo en UserControl Test Container de Visual Studio, recibirá el siguiente error:

Error al crear UserControl 'name'

El mensaje de error era "No se puede crear un tipo para el que Type.ContainsGenericParameters es true".

El UserControl se quitará de la lista.

Aunque sus componentes y controles no pueden ser tipos genéricos, pueden utilizar tipos genéricos.

Error en tiempo de diseño: "El valor no puede ser nulo.Nombre del parámetro: 'nombre de componente'"

Puede recibir este error cuando está creando su componente o control en la superficie de diseño desde el Cuadro de herramientas. Probablemente, la causa es que está intentando utilizar un componente o control que se compiló para un ensamblado de 64 bits. El entorno de diseño de Visual Studio no admite componentes de 64 bits.

Error de depuración: "Operación no válida a través de subprocesos: Se tuvo acceso al control 'nombre de control' desde un subproceso distinto de aquel en que lo creó".

Si utiliza el multithreading en las aplicaciones de Windows Forms, se debe asegurar de realizar llamadas a los controles de una manera segura para los subprocesos. Esta excepción es provocada por el depurador y no aparece en tiempo de ejecución, aunque se recomienda solucionar este problema cuando se presenta. Para obtener más información, vea Cómo: Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms.

Error en tiempo de diseño: "No se puede abrir un diseñador para el archivo porque la clase que contiene no hereda de una clase que se pueda diseñar visualmente"

El archivo con el componente o control puede contener varias definiciones de clases, pero la primera clase del archivo debe ser una que pueda diseñar. La primera clase del archivo debe implementar la interfaz IComponent, o derivar de la clase Component o una clase de la que derive Component.

Los glifos permanecen después de que se elimine el componente

Si su diseñador personalizado crea objetos Adorner, debe eliminarlos de la superficie de diseño cuando el diseñador salga del ámbito. Llame a BehaviorServiceAdornerCollection.Remove en el método Dispose de su diseñador para borrar objetos Glyph y Adorner relacionados, así como objetos Behavior. Para obtener más información, vea Cómo: Extender la apariencia y el comportamiento de los controles en modo de diseño.

Comportamiento predeterminado del diseñador oculto por el comportamiento personalizado

El diseñador de controles predeterminado crea un glifo que cubre el control completo en la superficie de diseño. Esto se denomina glifo del cuerpo. Si su diseñador de controles personalizado crea un glifo con los mismos límites que el glifo del cuerpo, ocultará la implementación subyacente de Behavior asociada al glifo del cuerpo. Así se evita que aparezcan características predeterminadas tales como etiquetas inteligentes y glifos de cambio de tamaño.

No puede pasar mensajes entre objetos Behavior, por lo que no podrá controlar un mensaje del mouse y reenviarlo a ningún objeto Behavior subyacente. Cuando implementa un glifo que cubre el control completo, asume toda la responsabilidad sobre el aspecto y el comportamiento de su experiencia de diseño personalizada.

Eventos de diseñador provocados de forma no deseada

Si su diseñador personalizado asocia controladores de eventos a eventos de diseñador tales como ComponentRemoved ActiveDesignerChanged y SelectionChanged, debe desasociar los controladores de eventos en el método Dispose de su diseñador.

Si no lo hace, puede producirse un comportamiento imprevisto en tiempo de diseño. En la siguiente lista se muestran algunos de los síntomas posibles:

  • Cuadro de mensaje de error: "Error al procesar este comando".

  • Cuadro de mensaje de error: "Referencia a objeto no establecida como instancia de un objeto".

  • Controladores de eventos a los que se ha llamado indebidamente cuando hay componentes eliminados o diseñadores cerrados.

Las colecciones no realizan la serialización

Si desea serializar su propiedad de colección de control o componente personalizado, aplique el atributo DesignerSerializationVisibilityAttribute y establézcalo como Content. Para obtener más información, vea Cómo: Serializar colecciones de tipos estándar con DesignerSerializationVisibilityAttribute.

El diseñador no adquiere una referencia UndoEngine

Si intenta adquirir una referencia al servicio UndoEngine mientras se está cargando un formulario, el método GetService devuelve null.

No se crea ni habilita el servicio UndoEngine hasta que el formulario ha finalizado su fase de carga. Después de que se cargue el formulario, las llamadas subsiguientes a GetService devolverán una referencia UndoEngine.

En general, raramente debería requerir una referencia al servicio UndoEngine directamente. Los casos en los que se necesita suelen ser por una acción del usuario y después de que se cargue el diseñador.

El entorno de diseño no reconoce cambios en las propiedades del componente

El entorno de diseño no reconoce cambios en el componente o el control si se establecen directamente las propiedades. Para que se provoquen eventos como ComponentChanged, debe establecer el valor de las propiedades del componente con el método PropertyDescriptor.SetValue. Así se notifica al entorno de diseño el cambio de propiedad, lo que permite que se actualicen correctamente la superficie de diseño y los controles PropertyGrid. Para obtener más información, vea Cómo: Extender la apariencia y el comportamiento de los controles en modo de diseño.

Sintaxis de DesignerAttribute

Asocia el diseñador personalizado al control que diseña mediante la aplicación de DesignerAttribute al control.

Debe especificar los parámetros DesignerAttribute precisamente; de lo contrario el entorno de diseño no cargará a su diseñador personalizado.

Actualizar el entorno de diseño después de realizar cambios en el componente o diseñador

Cuando realiza cambios en los aspectos en tiempo de diseño de un componente, debe volver a generar el proyecto del componente. Además, si hay otro proyecto de formularios Windows Forms abierto al mismo tiempo y que utiliza este componente, probablemente habrá que actualizar el proyecto para ver los cambios. Normalmente, deberá cerrar y volver a abrir la ventana de diseño que contiene el componente.

Advertencia de FxCop sobre un formulario Windows Forms recién generado: DoNotInitializeUnnecessarily

El Diseñador de Windows Forms genera el código siguiente para los proyectos de aplicaciones de Windows Forms en C#.

private System.ComponentModel.IContainer components = null;

FxCop puede generar la advertencia "DoNotInitializeUnnecessarily", según las reglas de FxCop vigentes. Esto es debido a que null es el valor predeterminado de Common Language Runtime (CLR) para las propiedades de referencia.

Si el diseñador no inicializase el campo components como null, el compilador de C# generaría la advertencia siguiente:

"El campo Form1.components nunca se asigna y siempre tendrá el valor predeterminado nulo".

Puede suprimir la advertencia de FxCop con SuppressMessageAttribute, pero esto puede causar problemas de mantenimiento si se cambia el nombre de clase. Por consiguiente, se recomienda pasar por alto la advertencia de FxCop.

Clases parciales y el Diseñador de Windows Forms

De forma predeterminada, el Diseñador de Windows Forms emite el código de serialización de diseñador en un archivo dedicado que es independiente del archivo principal del componente. Por ejemplo, en un proyecto de aplicaciones de Windows Forms, la definición para la clase Form1 se divide en dos archivos, tal como se muestra en la tabla siguiente.

Archivo (nombres de archivo de C#)

Función

Form1.cs

Archivo de clase principal

Form1.Designer.cs

Código emitido por diseñador

Archivo (nombres de archivo de VB)

Función

Form1.vb

Archivo de clase principal

Form1.Designer.vb

Código emitido por diseñador

En general, no necesita modificar el código emitido por el Diseñador de Windows Forms. En su lugar, edite el archivo de clase principal.

El Diseñador de Windows Forms utiliza la palabra clave partial para dividir la implementación de Form1 en dos archivos independiente. Así se evita que el código emitido por el diseñador se intercale en su código. Para obtener más información sobre la palabra clave partial, vea Clases y métodos parciales (Guía de programación de C#) y Partial (Visual Basic).

El Diseñador de Windows Forms no admite la división de la definición de un tipo diseñable en más de dos implementaciones de partial. Esta restricción supone crear un nuevo archivo de clase que contenga una tercera definición parcial del tipo, así como agregar una tercera definición de clase parcial del tipo en el archivo principal o en el archivo del diseñador. Los miembros definidos de este modo no serán visibles en el Diseñador de Windows Forms.

Los controles personalizados heredados producen un comportamiento inesperado del Diseñador

Cuando los tipos se invalidan en el diseñador, ComponentSerializationService realiza una recarga parcial para actualizar el diseñador con los tipos actualizados. Las versiones de Visual Studio que preceden a Visual Studio 2005 cargan de nuevo el diseñador completamente. El comportamiento de la recarga parcial en Visual Studio 2005 es más rápido que una recarga completa y además conserva la pila de deshacer.

Componentes y correspondiendo serializadores creados antes de que Visual Studio 2005 quizá no pueda hospedar una recarga parcial. Componentes y controles pueden causar un comportamiento inesperado porque sólo fueron creados para deserializar durante una recarga completa. Los síntomas cuando hay controles heredados incluyen desbordamientos de pila, aplicaciones que no responden o áreas en blanco en el Diseñador de Windows Forms.

Puede revertir al comportamiento de la recarga completa agregando la configuración siguiente al archivo devenv.exe.config. Si se instaló Visual Studio 2005 en la ubicación predeterminada, este archivo está en la carpeta C:\Program Files\Microsoft Visual Studio 8\Common7\IDE.

<appSettings>
   <add key="EnableOptimizedDesignerReloading" value="false" />
</appSettings>

Las etiquetas inteligentes en un diseñador hospedado producen excepciones

Si está hospedando un diseñador fuera de Visual Studio, las etiquetas inteligentes pueden generar una excepción NullReferenceException. Para resolver este problema, proporcione una referencia IUIService en el diseñador e implemente la propiedad Styles. En IDictionary expuesto por Styles, asigne un nuevo Font como elemento especificado por la clave "DialogFont", como se muestra en el fragmento de código siguiente.

Styles["DialogFont"] = new Font(...);

El icono del componente no aparece en el cuadro de herramientas

En Visual Studio, cuando se utiliza ToolboxBitmapAttribute para asociar un icono a un componente personalizado, el mapa de bits no aparece en el cuadro de herramientas para los componentes generados automáticamente. Para ver el mapa de bits, recargue el control mediante el cuadro de diálogo Elegir elementos del cuadro de herramientas. Para obtener más información, vea Iconos del cuadro de herramientas.

Vea también

Tareas

Cómo: Obtener acceso a servicios en tiempo de diseño

Conceptos

Errores en tiempo de diseño en el Diseñador de Windows Forms

Otros recursos

Ampliar compatibilidad en tiempo de diseño