Как создать компоненты WinForms на основе типа объекта

2

Предположим, что у нас есть этот интерфейс:

interface IVehicle { ... }

И некоторые классы, реализующие его:

class Car : IVehicle { ... }
class Boat : IVehicle { ... }
class Plane : IVehicle { ... }

В моем пользовательском интерфейсе у меня есть FlowLayoutPanel и доступ к некоторому виду IEnumerable<IVehicle> с несколькими различными объектами IVehicle.

Теперь я хочу создать UserControl для каждого из транспортных средств и добавить его в FlowLayoutPanel. Элементы управления будут похожи друг на друга, но поскольку есть транспортные средства разных типов, некоторые элементы управления могут выглядеть немного иначе или работать по-другому, чтобы пользователь мог легко работать со своими транспортными средствами. Как я могу лучше всего решить это без лишних помех?

Теги:
winforms
types
user-controls

4 ответа

2
Лучший ответ

Как использовать какой-нибудь метод factory:

UserControl CreateControl(IVehicle vehicle) 
{
    if (vehicle is Car)
    {
        return new CarControl();
    }
    else if (vehicle is Boat)
    {
        return new BoatControl();
    }
    ...
}
  • 0
    Я думаю, что это будет самый простой вариант, хотя я надеялся избежать длинного оператора if else if или switch . Вероятно, в конечном итоге с этим, хотя: р
2

В вашем интерфейсе 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;
    }
}
  • 0
    почему вы делаете CarControl статичным? Таким образом, несколько транспортных средств разделяют контроль?
  • 0
    @Scoregraphic: Да, если для всех автомобилей нужен только один CarControl. Но я думаю, что ОП хочет контроль для каждой машины, лодки и т. Д., Поэтому версия без статической переменной является лучшей.
Показать ещё 2 комментария
1

Я не уверен, к чему именно вы стремитесь, но вы можете использовать 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
}
  • 0
    Как бы вы реализовали элементы управления?
  • 0
    Я мог бы использовать фабричный метод, предложенный @Patrick McDonald в своем ответе. Наши ответы бесплатны.
Показать ещё 1 комментарий
0

Если вы знаете, как писать код, как выглядит сопоставление, вы можете настроить в 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);
  • 0
    Выглядит красиво, и я думал о чем-то похожем. Но разве это не сложный способ сделать то, что Патрик Макдональд сделал в своем ответе, if else if ?
  • 0
    Основное отличие состоит в том, что я чувствую, что в этом подходе четкое разделение интересов; фабричный метод не знает о сопоставлениях как таковых, он просто выполняет поиск. Это означает, что вы можете изменить способ заполнения словаря сопоставления (например, его можно загрузить на основе информации в файле конфигурации) без изменения заводского метода.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню