У меня есть большое количество пользовательских элементов управления, которые очень похожи. У них много общего в поведении. Я использовал базовый класс с общими вещами, а затем специализировал класс по мере необходимости.
class BaseControl : UserControl
{
// common
}
class RedControl : BaseControl
{
// specialized
}
class BlueControl : BaseControl
{
// specialized
}
и т.д ...
Это работает довольно хорошо, пока мне не нужно начать вставлять или изменять макет дочерних элементов управления, содержащихся в BaseControl. Например, RedControl необходимо добавить кнопку на определенную панель базового элемента управления. В другом случае мне нужно изменить размер или расположение других базовых дочерних элементов управления.
Когда я попробовал следующий код, я не увидел ни одной кнопки во время выполнения...
public partial class RedControl : BaseControl
{
public RedControl()
{
InitializeComponent();
addButtonToBase(); // no button shows up
this.PerformLayout();
}
void addButtonToBase()
{
Button button = new Button();
button.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
button.Location = new System.Drawing.Point(3, 3);
button.Size = new System.Drawing.Size(23, 23);
button.Text = "My Button";
baseSplitContainer.Panel1.Controls.Add(button); // protected child control in base
}
// ...
}
Я могу сделать кнопку отображаемой как дочернюю для baseSplitContainer, если я сделаю addButtonToBase() виртуальной и вручную добавлю ее в сгенерированный код в InitalizeComponent() BaseControl. Макет BaseControl все еще продолжался, и вам разрешено вызывать виртуальные функции в конструкторах в С#.Net....
Так что даже если это работает, это не очень хорошее решение. Во-первых, когда я редактирую BaseControl в конструкторе VS, вызов addBaseControl() в IntializeComponent удаляется. Во-вторых, вызов виртуальных функций в конструкторах кажется опасным.
Я думаю, мне нужно, чтобы макет базового элемента управления повторялся в производном элементе управления... Я пробовал это, но либо сделал это неправильно, либо он не будет работать...
Кстати, да, я знаю, что WPF хорош в этом. Не могу использовать его из-за ограничений в других системах.