Вот как вы можете это сделать:
using System;
using System.Windows.Forms;
using System.ComponentModel;
//Interface
public interface IControl : IComponent
{
void DoSomething();
}
//Factory
public class ControlFactory
{
public static IControl Create(string name)
{
switch (name)
{
case "UserControlA":
var userControlA = new UserControlA();
return userControlA;
case "UserControlB":
var userControlB = new UserControlB();
return userControlB;
}
return null;
}
}
//BaseUserControl
public partial class BaseUserControl : UserControl, IControl
{
public BaseUserControl()
{
InitializeComponent();
}
public virtual void DoSomething()
{
}
}
public partial class UserControlA : BaseUserControl, IControl
{
public UserControlA()
{
InitializeComponent();
}
public override void DoSomething()
{
//Do something here
}
}
public partial class UserControlB : BaseUserControl, IControl
{
public UserControlB()
{
InitializeComponent();
}
public override void DoSomething()
{
//Do something here
}
}
Вы можете сохранить BaseUserControl
, если у вас есть какие-либо общие функции для UserControlA
и UserControlB
; в противном случае устраните его и сделайте так, чтобы последние два были получены непосредственно из UserControl
.
Вы должны определить всех членов, к которым вам может понадобиться доступ из ваших производных классов в интерфейсе IControl
. Сюда входят все члены, которые вы унаследуете от UserControl
. Однако вам не нужно повторно реализовывать их в ваших конкретных классах.
//Interface
public interface IControl : IComponent
{
void DoSomething();
// To be inherited from UserControl.
Size Size { get; set; }
bool Focus();
event EventHandler FontChanged;
}
Если вам нужно добавить эти элементы управления в приложение Windows Forms - обычно в качестве аргумента вызова метода Control.ControlCollection.Add
- вам необходимо получить экземпляр Control
, соответствующий вашему элементу управления. В текущей реализации это может быть достигнуто просто посредством приведения; однако это необходимо изолировать от потребителей вашего интерфейса на случай, если вы решите изменить базовую реализацию в будущем. Таким образом, я бы использовал:
//Interface
public interface IControl : IComponent
{
void DoSomething();
Control AsWindowsForms();
}
//BaseUserControl
public partial class BaseUserControl : UserControl, IControl
{
public BaseUserControl()
{
InitializeComponent();
}
public virtual void DoSomething()
{
}
public Control AsWindowsForms()
{
return this as Control;
}
}
В вашем коде клиента:
var controlA = ControlFactory.Create("UserControlA").AsWindowsForms();
var controlB = ControlFactory.Create("UserControlB").AsWindowsForms();
panel1.Controls.Add(controlA);
panel1.Controls.Add(controlB);