(1) Чтобы контролировать, что компонент может быть добавлен только в форму, используйте конструктор FooComponent
, которому передается форма, и не определяйте конструктор по умолчанию. Это называется:
FooComponent component = new FooComponent(this);
где компонент создан из самой формы. Не определяя конструктор по умолчанию, это:
FooComponent component = new FooComponent();
не компилируется.
(2) Выставьте FooComponent
недвижимости на самой форме, так и в конструктор FooComponent
, установить переданное формы FooComponent
-х до this
.
(3) То же самое, в конструкторе FooComponent
, регистрироваться в случае закрытия для формы переданному
Положите все это вместе, и вы получите:
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
К сожалению, если вам нужно e default constructor, и если он должен быть истинным компонентом Drop-on-the-Form, нет никакого способа гарантировать, что компонент создается только в Форме или что у формы есть только один экземпляр компонента (не из внутри компонента, в любом случае).
Проблема двояка:
(1) Удаление компонента не добавляет компонент в форме, он добавляет его в components
коллекции формы. Поэтому, даже если вы можете получить дескриптор родителя/владельца, он никогда не будет формой.
(2) Как отметил Нейл, отбрасывание компонента на форму вызывает конструктор по умолчанию, который не передает никаких параметров, и, конечно же, ни один из свойств компонента (например, сайт или контейнер) не заполняется.
Возможно полезно: Компонент может быть разработан, чтобы получить уведомление, когда он будет создан в несколько способов:
(1) Осуществляя конструктор, который принимает IContainer
параметр. Когда компонент отбрасывается в форме, сгенерированный код будет вызывать этот конструктор. Тем не менее, он будет делать это только во время выполнения, а не во время разработки. Но контейнер будет ручкой для коллекции components
формы.
public FooComponent(IContainer container) {...}
(2) Внедрение ISupportInitialize
. Когда компонент отбрасывается в форме, сгенерированный код дополнительно вызывает BeginInit()
и EndInit()
. В EndInit()
вы можете получить доступ к таким областям, как Site
и Container
. Опять же, вы получите это только во время выполнения, а не в дизайне, а выброс исключения здесь не остановит создание компонента.
Старые, но отличные статьи по компонентам и элементам управления от MSDN Magazine от Майкла Вайнхардта и Криса Продает.
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
Это теперь .chm файлы справки. Вам необходимо разблокировать страницу свойств файла, чтобы разрешить чтение содержимого после загрузки.
Я думаю, вы можете посмотреть CodeDomSerializer (http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx). Это может быть вашим лучшим выбором. – PHeiberg
@PHeiberg: Спасибо –