Создайте дизайнерскую коллекцию UserControl для использования во время выполнения - PullRequest
1 голос
/ 15 сентября 2010

У меня есть панель, которую я хочу заполнить некоторыми пользовательскими элементами управления во время выполнения. Эти элементы управления являются сложными и могут быть взаимозависимыми, поэтому я хотел бы их:

  • для редактирования редактором Visual Studio;
  • находиться в том же контексте (= определено в том же классе);

Оба требования являются обязательными.

Учитывая, что UserControl сам по себе является индексированной коллекцией элементов управления, я начал проектировать свои элементы управления в одном и том же классе, не заботясь о их реальном расположении (это будет указано во время выполнения). Я уже использовал тот же идентичный подход с ленточными контейнерами DevComponents (с большим удовлетворением), поэтому я сначала подумал, что то же самое возможно со стандартными элементами UserControl (ов).

В конце концов я понял, что элемент управления может находиться только в одном экземпляре Control.ControlCollection одновременно, поэтому я не мог использовать свойство Controls и добавлять элементы управления на другую панель, не удаляя их из исходного «фиктивного» элемента UserControl.

У меня вопрос: есть ли чистый и поддерживаемый способ создания этой коллекции UserControl, ориентированной на дизайнера? Я бы назвал этот подход шаблоном, потому что он действительно добавляет ясности и эффективности кода.

Спасибо, Francesco

P.S .: в качестве обходного пути я создал класс DummyControlContainer, который наследует UserControl и сохраняет заполненную карту словаря при событии ControlAdded (код следует). Хотите знать, если есть что-то чище.

public partial class DummyControlContainer : UserControl
{
    private Dictionary<string, Control> _ControlMap;

    public DummyControlContainer()
    {
        InitializeComponent();

        _ControlMap = new Dictionary<string, Control>();
        this.ControlAdded += new ControlEventHandler(DummyControlCollection_ControlAdded);
    }

    void DummyControlCollection_ControlAdded(object sender, ControlEventArgs args)
    {
        _ControlMap.Add(args.Control.Name, args.Control);
    }

    public Control this[string name]
    {
        get { return _ControlMap[name]; }
    }
}

1 Ответ

0 голосов
/ 17 ноября 2010

После тестирования и использования его в реальном проекте, я все больше и больше убежден, что мое решение было чистым и безопасным, если вам нужен такой шаблон.Этот контейнер предназначен для заполнения элементами управления, такими как панели или аналогичные.Чтобы предотвратить некоторые плохие поведения с привязываемыми источниками данных, я предоставлял каждому новому элементу управления, добавляемому в этот контейнер, свой собственный BindingContext.Наслаждайтесь.

public partial class DummyControlContainer : UserControl
{
    private Dictionary<string, Control> _ControlMap;

    public DummyControlContainer()
    {
        InitializeComponent();

        _ControlMap = new Dictionary<string, Control>();
        this.ControlAdded +=
            new ControlEventHandler(DummyControlCollection_ControlAdded);
    }

    void DummyControlCollection_ControlAdded(object sender,
        ControlEventArgs args)
    {
        // If the added Control doesn't provide its own BindingContext,
        // set a new one
        if (args.Control.BindingContext == this.BindingContext)
            args.Control.BindingContext = new BindingContext();
        _ControlMap.Add(args.Control.Name, args.Control);
    }

    public Control this[string name]
    {
        get { return _ControlMap[name]; }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...