Предположим, что у нас есть этот интерфейс:
interface IVehicle { ... }
И некоторые классы, реализующие его:
class Car : IVehicle { ... }
class Boat : IVehicle { ... }
class Plane : IVehicle { ... }
В моем пользовательском интерфейсе у меня есть FlowLayoutPanel
и доступ к некоторому виду IEnumerable<IVehicle>
с несколькими различными объектами IVehicle
.
Теперь я хочу создать UserControl
для каждого из транспортных средств и добавить его в FlowLayoutPanel
. Элементы управления будут похожи друг на друга, но поскольку есть транспортные средства разных типов, некоторые элементы управления могут выглядеть немного иначе или работать по-другому, чтобы пользователь мог легко работать со своими транспортными средствами. Как я могу лучше всего решить это без лишних помех?
Как использовать какой-нибудь метод factory:
UserControl CreateControl(IVehicle vehicle)
{
if (vehicle is Car)
{
return new CarControl();
}
else if (vehicle is Boat)
{
return new BoatControl();
}
...
}
В вашем интерфейсе IVehicle вы можете добавить метод для получения пользовательского элемента управления.
public interface IVehicle
{
UserControl GetVehicleControl();
}
Если вам нужен элемент управления для каждого автомобиля, вы можете использовать этот код:
public class Car : IVehicle
{
public UserControl GetVehicleControl()
{
return new CarControl();
}
}
Иначе, если вам нужен только один элемент управления для каждого типа транспортного средства:
public class Car : IVehicle
{
private static CarControl m_control;
public UserControl GetVehicleControl()
{
if(m_control == null)
m_control = new CarControl();
return m_control;
}
}
Я не уверен, к чему именно вы стремитесь, но вы можете использовать generics, когда вы расширяете пользовательские элементы управления обычным способом:
public class VehicleControl<TVehicle>: UserControl
where TVehicle:IVehicle
{
//do something specific with IVehicle
}
public class CarControl : VehicleControl<Car>
{
//add stuff specific for the Car
}
Если вы знаете, как писать код, как выглядит сопоставление, вы можете настроить в Dictionary
с сопоставлениями:
private Dictionary<Type, Type> _vehicleToControlTypeMappings = new Dictionary<Type, Type>();
Загружать сопоставления при запуске:
_vehicleToControlTypeMappings.Add(typeof(Car), typeof(CarControl));
_vehicleToControlTypeMappings.Add(typeof(Plane), typeof(PlaneControl));
... и предоставить способ получения нового элемента управления на основе транспортного средства:
private Control GetVehicleControl(IVehicle vehicle)
{
Control result = (Control)Activator.CreateInstance(
_vehicleToControlTypeMappings[(vehicle as object).GetType()]
);
// perform additional initialization of the control
return result;
}
Затем вы можете просто передать объекты типов, которые реализуют IVehicle
в метод:
IVehicle vehicle = new Car();
Control newctl = GetVehicleControl(vehicle);
if else if
?
if else if
илиswitch
. Вероятно, в конечном итоге с этим, хотя: р