¿Cómo habilitar el soporte de diseño en un control personalizado?

Trataré de explicar lo que estoy buscando. No conozco el término técnico para ello, así que aquí va:

Ejemplo 1: si coloco un ListView en un Formulario y agrego algunas columnas, puedo, en Design-Time, hacer clic y arrastrar las columnas para cambiar su tamaño.

Ejemplo 2: ahora, coloco un ListView en un UserControl y lo llamo “MyCustomListView” (y quizás agregue algún método para mejorarlo de alguna manera).

Si sé colocar el “MyCustomListView” en un Formulario, no puedo hacer clic y arrastrar los encabezados de columna para cambiar su tamaño en Design-Time.

¿Hay alguna manera de hacer que eso ocurra fácilmente? Alguna forma de “pasar el evento de hacer clic y arrastrar al control subyacente y dejar que ese control haga su magia” . No estoy realmente buscando recodificar, simplemente pase el mouseclick (o lo que sea) y deje que, en este caso, ListView reaccione como lo hizo en el primer ejemplo anterior.

El diseñador de Windows Forms tiene clases de diseñador dedicadas para la mayoría de los controles. El diseñador de un ListView es System.Windows.Forms.Design.ListViewDesigner, una clase interna en el ensamblado System.Design.dll. Esta clase le da la capacidad de arrastrar los encabezados de columna.

Un UserControl utiliza la clase de diseñador System.Windows.Forms.Design.ControlDesigner. No hace nada especial, solo pone un rectángulo alrededor del control con los controles de arrastre. Puede ver hacia dónde se dirige esto: después de poner su control de usuario en un formulario, es ControlDesigner el que se utiliza para diseñar la clase, ListViewDesigner no está en la imagen. Perderá la capacidad de arrastrar los encabezados de columna. También tenga en cuenta que ControlDesigner no da acceso a los controles dentro de la UC.

Sin embargo, eso se puede arreglar al crear tu propio diseñador. Comience con Proyectos + Agregar referencia, seleccione System.Design. Deberá agregar una propiedad pública a la UC para exponer la vista de lista y aplicar el atributo [DesignerSerializationVisibility] para permitir que se guarden las propiedades modificadas. Y aplique el atributo [Designer] a la clase UC para reemplazar el diseñador predeterminado. Todo debe parecerse a esto (usando los nombres predeterminados y un ListView que muestra “empleados”):

using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.Design; // Note: add reference required: System.Design.dll namespace WindowsFormsApplication1 { [Designer(typeof(MyDesigner))] // Note: custom designer public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } // Note: property added [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ListView Employees { get { return listView1; } } } // Note: custom designer class added class MyDesigner : ControlDesigner { public override void Initialize(IComponent comp) { base.Initialize(comp); var uc = (UserControl1)comp; EnableDesignMode(uc.Employees, "Employees"); } } } 

Ahora se puede hacer clic y diseñar la vista de lista en el control de usuario de forma normal.