(1) Para controlar que el componente solo se puede agregar a un formulario, use un constructor FooComponent
al que se le pasa un formulario y no defina el constructor predeterminado. Se llama así:
FooComponent component = new FooComponent(this);
donde el componente se crea desde el propio formulario. Al no definir el constructor predeterminado, esto:
FooComponent component = new FooComponent();
no se compilará.
(2) exponer una propiedad FooComponent
en el propio formulario, y en el constructor de la FooComponent
, ajuste de FooComponent
a this
la forma aprobada.
(3) Lo mismo, en el constructor de la FooComponent
, registrarse con el acto de clausura de la forma que ha pasado
poner todo junto y se obtiene:
public class MyForm : Form {
public FooComponent OwnedComponent { get; set; }
}
public class FooComponent {
public FooComponent (MyForm OwnerForm) {
OwnerForm.OwnedComponent = this;
OwnerForm.FormClosing += MyCallback;
}
private void MyCallback(object sender, FormClosingEventArgs e) {
...
}
}
EDIT
Lamentablemente, si necesita th El constructor predeterminado, y si tiene que ser un Componente verdadero drop-on-the-form, no hay manera de exigir que un componente solo se cree en un Formulario, o que el Formulario solo tenga una instancia del componente (no desde dentro del componente, de todos modos).
El problema es doble:
(1) Dejar caer un componente no añadir el componente a la forma, se añade a la colección de la forma components
. Entonces, incluso si pudiera obtener un control para el padre/propietario, nunca será un formulario.
(2) Como señaló Neil, colocar un componente en un formulario llama al constructor predeterminado, que no pasa parámetros, y, por supuesto, ninguna de las propiedades del componente (como sitio o contenedor) se rellena.
Posiblemente útil: Un componente puede ser diseñado para ser notificado cuando se crea en un par de maneras:
(1) Mediante la implementación de un constructor que toma un parámetro IContainer
. Cuando el componente se descarta en un formulario, el código generado llamará a este constructor, en su lugar. Sin embargo, solo hará esto en tiempo de ejecución, no en tiempo de diseño. Pero el contenedor será un identificador de la colección components
del formulario.
public FooComponent(IContainer container) {...}
(2) Implementando ISupportInitialize
. Cuando el componente se descarta en un formulario, el código generado también llamará al BeginInit()
y al EndInit()
. En EndInit()
, puede acceder a propiedades como Site
y Container
. Nuevamente, solo obtendrá esto en tiempo de ejecución, no en tiempo designado, y lanzar una excepción aquí no impedirá que se cree el componente.
Artículos antiguos, pero excelentes sobre componentes y controles de MSDN Magazine de Michael Weinhardt y Chris Sells.
April 2003 Building Windows Forms Controls and Components with Rich Design-Time Features
May 2003 Building Windows Forms Controls and Components with Rich Design-Time Features, Part 2
Estos son ahora los archivos de ayuda .chm. Deberá desbloquear en la página de propiedades del archivo para permitir la lectura de los contenidos después de la descarga.
Creo que puede ver el CodeDomSerializer (http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx). Puede ser tu mejor apuesta. – PHeiberg
@PHeiberg: gracias –