Как создать компоненты WinForms на основе типа объекта - PullRequest
2 голосов
/ 04 августа 2009

Допустим, у нас есть этот интерфейс:

interface IVehicle { ... }

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 04 августа 2009

В вашем интерфейсе 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;
    }
}
2 голосов
/ 04 августа 2009

Как насчет использования какого-то фабричного метода:

UserControl CreateControl(IVehicle vehicle) 
{
    if (vehicle is Car)
    {
        return new CarControl();
    }
    else if (vehicle is Boat)
    {
        return new BoatControl();
    }
    ...
}
1 голос
/ 04 августа 2009

Я не уверен, к чему именно вы стремитесь, но вы можете использовать дженерики, когда расширяете пользовательские элементы управления обычным способом:

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 голосов
/ 04 августа 2009

Если при написании кода вы знаете, как выглядит отображение, вы можете установить на 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...