2013-12-02 2 views
1

Я хочу знать, можно ли динамически загружать пользовательские элементы управления?
Это код, чтобы показать, что я имею в виду:
C# Winform динамически загружает usercontrols по имени

public void Load() 
     { 

      Reset(); 

      if (_host.User == null) 
       return; 

      int _count = 0; 

      String[] _applications = _host.User.Applications; 

      if (_applications == null) 
       return; 

      foreach (String _application in _applications) 
      { 

       TabPage _page = null; 

       switch (_application) 
       { 
        case "SF01": 

         _page = new TabPage(); 
         _page.Text = "SF01"; 
         _page.Controls.Add(new SF01(_container)); 

         break; 
       } 

       if (_page != null) 
       { 

        tapplications.TabPages.Add(_page); 
        m_list.Add(_count, _page); 
        _count++; 

       } 

      } 

      tapplications.TabPages.Add(tlog); 

      if (_host.User.Admin) 
       tapplications.TabPages.Add(tadmin); 

      _container.Controls.Add(this); 

     } 

Как вы можете видеть SF01 мой UserControl.
Теперь, как я могу загрузить другие usercontrols по имени вместо жесткого ввода объекта класса?
Таким образом, я могу создать больше приложений и забыть о том, как их загрузить. (case "SF01":)

Все приложения будут находиться под папкой проекта applications, возможно, есть способ перебрать эту папку проекта?

Project

+0

Если вы пытаетесь ускорить разработку, вы должны предварительно определить формы, соответствующие вашему стилю, и создать элементы управления, которые дополняют вашу функциональность. Поскольку использование элементов управления загрузкой является шагом назад с точки зрения удобочитаемости и крутой кривой обучения. – Measuring

+0

Согласен, но это невозможно (я думаю) в этом случае. Пользователь регистрируется с помощью веб-службы, а класс приложения получает список всех приложений, которые пользователь может запустить. Все это происходит в 1 форме. Мне нужно найти способ перевести String [] _приложения в типы пользовательских элементов управления ... – grmbl

ответ

2

Да это.

Пользовательский контроль может быть создан с использованием Activator.CreateInstance, как и любого другого объекта.

string objTypeName = "myNamespace.UI.SF01"; // Full namespace name 
SF01 myNewSF01 = (Foo)Activator.CreateInstance(Type.GetType(objTypeName)); 

Затем вы можете заменить переключатель заявление с

_page = new TabPage(); 
_page.Text = "SF01"; 

var control = (Control)Activator.CreateInstance(Type.GetType("myNamespace." + _application)); 
_page.Controls.Add(control); 
+0

Отлично! Как я могу поймать несуществующие «приложения»? (неважно, обошел это.) – grmbl

+0

+ Конструктор SF01 нуждается в параметре ... :( Что я имею в виду, что SF01 нуждается в ссылке на его контейнер, чтобы он мог получить доступ к этому объекту и его родительскому (основному). – grmbl

+0

I ' ve выставил параметр constructors как свойство, но все же нужно найти способ доступа к этому свойству типов ...? – grmbl

1

Я нашел (простой) Solution с помощью отражения.

foreach (String _application in _applications) 
      { 

       TabPage _page = null; 

       Type[] _atypes = new Type[] { typeof(Panel) }; 
       Object[] _avalues = new Object[] { _container }; 
       ConstructorInfo _ctor = Type.GetType("SFM." + _application).GetConstructor(_atypes); 
       Object _control = _ctor.Invoke(_avalues); 

       if (_control != null) 
       { 
        _page = new TabPage(); 
        _page.Text = _application; 
        _page.Controls.Add((Control)_control); 
       } 

       if (_page != null) 
       { 

        tapplications.TabPages.Add(_page); 
        m_list.Add(_count, _page); 
        _count++; 

       } 

      } 

Все работает как ожидается!
Просто нужно сделать больше защиты от ошибок (Invoke fail, ...)

Смежные вопросы