none
подключение компонента из кода программы

    Вопрос

  • имеется несколько компонентов с одинаковыми методами и свойствами их необходимо подключать в программе в зависимости какой из  них я выберу, как это реализовать?
    18 сентября 2012 г. 11:41

Ответы

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

    Для демонстрации, я воспользуюсь двумя компонентами, позволяющими вводить строку и сообщать о том, что пользователь ввел бяку. Для реализации задумки, создадим интерфейс, который будет реализовывать публичный контракт:

    public interface IBaseAbstractControl
    {
        string Header
        {
            set;
        }
    
        string InputString
        {
            get;
        }
    
        void ShowError();
    }

    Как видно, добавлены свойство задающее заголовок, свойство возвращающее введенный текст и метод заставляющий компонент показать сообщение об ошибке. Добавляем в проект UserControl и формируем его интерфейс:

    Добавляем ему поддержку нашего интерфейса и реализуем соответствующие методы:

    public partial class FirstControl : UserControl, IBaseAbstractControl
    {
        public FirstControl()
        {
            InitializeComponent();
        }
    
        public string Header
        {
            set { label1.Text = value; }
        }
    
        public string InputString
        {
            get { return textBox1.Text; }
        }
    
        public void ShowError()
        {
            MessageBox.Show("Вы ввели неправильные данные");
        }
    }

    Получилось достаточно просто. Добавляем второй UserControl, вот с таким дизайном (я заполнил Items у ComboBox всякими разными строками):

    Также наследуем его от интерфейса и реализуем свойства и метод:

    public partial class SecondControl : UserControl, IBaseAbstractControl
    {
        public SecondControl()
        {
            InitializeComponent();
        }
    
        public string Header
        {
            set { label1.Text = value; }
        }
    
        public string InputString
        {
            get { return comboBox1.Text; }
        }
    
        public void ShowError()
        {
            comboBox1.BackColor = Color.Red;
            (new Task(() => { Thread.Sleep(1000); this.BeginInvoke((Action)(() => comboBox1.BackColor = Color.White)); })).Start();
        }
    }

    Все, переходим к демо приложению. На главной форме, спросим у пользователя, как он хочет вводить текст, с донаборщиком или просто, в зависимости от этого будем создавать один из подготовленных контролов. Кстати, заметили, что они кроме дизайна, будут отличаться еще и способом обработки ошибок? Первый выводит месаджбокс, второй моргает фоном. Ладно, дизайн главной формы:

    Ну и пишем обработчики кнопок:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        IBaseAbstractControl _control = null;
    
        private void btCreateControl_Click(object sender, EventArgs e)
        {
            switch (comboBox1.SelectedIndex)
            {
                case 0:
                    _control = new FirstControl();
                    break;
                case 1:
                    _control = new SecondControl();
                    break;
                default:
                    MessageBox.Show("Выбирите способ ввода");
                    return;
            }
            btCreateControl.Enabled = false;
            _control.Header = "Введите текст не менее тре символов";
            panel1.Controls.Add((Control)_control);
            btCheckText.Enabled = true;
        }
    
        private void btCheckText_Click(object sender, EventArgs e)
        {
            if (_control.InputString.Length < 3)
            {
                _control.ShowError();
            }
            else
            {
                MessageBox.Show("Вы ввели текст: " + _control.InputString);
            }
        }
    }

    Как видно, про компоненты что то говориться, только в момент вызова конструктора. Вся остальная работа ведется через интерфейс. Т.е. мы вызываем конструктор компонента в зависимости от выбора пользователя, результат записываем в переменную типа наш интерфейс. Устанавливаем текст, помещаем компонент в приготовленную специально для него панель. Ну и в обработчике второй кнопки получаем текст из компонента и, при необходимости, сообщаем что его нам ввели неправильно.         
    18 сентября 2012 г. 15:30
    Отвечающий
  • Это тоже не вызывает проблем. Вот, опять же, статья в моем блоге на эту тему.
    18 сентября 2012 г. 15:45
    Отвечающий
  • Имя интерфейса, который должны реализовывать формы, которые я создаю динамически.

    Вам из второго пример надо посмотреть как у меня происходит загрузка классоф (форм) из внешних сборок, про которых я ничего не знаю кроме имени сборки и полного имени класса (формы), а из первого примера все остальное, вставив вызовк конструктора класса (формы) из второго примера в ветки case первого примера.

    • Предложено в качестве ответа Abolmasov Dmitry 19 сентября 2012 г. 6:56
    • Помечено в качестве ответа skemuze 20 сентября 2012 г. 2:40
    19 сентября 2012 г. 4:30
    Отвечающий

Все ответы

  • Добрый день.

    Вариантов много, причем зависит от того, на какой платформе вы разрабатываете (WinForms, WPF).

    Общая идея, обычно сводится к тому, что вы объявляете базовый класс (или интерфейс), от него объявляете переменную, в нее, в зависимости от выбора пользователя, помещаете экземпляр нужного компонента, ну и делаете с ним все то, что хотите.

    Единственно, не забудьте сделать методы виртуальными, если это будет класс.

    18 сентября 2012 г. 12:20
    Отвечающий
  • использую winForms, компонент и имеет визуальную часть, был бы признателен за простенький пример
    18 сентября 2012 г. 13:44
  • Ответ получился очень большой, поэтому выложил его со всеми картинками у себя в блоге . Ну и здесь его привожу...

    Для демонстрации, я воспользуюсь двумя компонентами, позволяющими вводить строку и сообщать о том, что пользователь ввел бяку. Для реализации задумки, создадим интерфейс, который будет реализовывать публичный контракт:

    public interface IBaseAbstractControl
    {
        string Header
        {
            set;
        }
    
        string InputString
        {
            get;
        }
    
        void ShowError();
    }

    Как видно, добавлены свойство задающее заголовок, свойство возвращающее введенный текст и метод заставляющий компонент показать сообщение об ошибке. Добавляем в проект UserControl и формируем его интерфейс:

    Добавляем ему поддержку нашего интерфейса и реализуем соответствующие методы:

    public partial class FirstControl : UserControl, IBaseAbstractControl
    {
        public FirstControl()
        {
            InitializeComponent();
        }
    
        public string Header
        {
            set { label1.Text = value; }
        }
    
        public string InputString
        {
            get { return textBox1.Text; }
        }
    
        public void ShowError()
        {
            MessageBox.Show("Вы ввели неправильные данные");
        }
    }

    Получилось достаточно просто. Добавляем второй UserControl, вот с таким дизайном (я заполнил Items у ComboBox всякими разными строками):

    Также наследуем его от интерфейса и реализуем свойства и метод:

    public partial class SecondControl : UserControl, IBaseAbstractControl
    {
        public SecondControl()
        {
            InitializeComponent();
        }
    
        public string Header
        {
            set { label1.Text = value; }
        }
    
        public string InputString
        {
            get { return comboBox1.Text; }
        }
    
        public void ShowError()
        {
            comboBox1.BackColor = Color.Red;
            (new Task(() => { Thread.Sleep(1000); this.BeginInvoke((Action)(() => comboBox1.BackColor = Color.White)); })).Start();
        }
    }

    Все, переходим к демо приложению. На главной форме, спросим у пользователя, как он хочет вводить текст, с донаборщиком или просто, в зависимости от этого будем создавать один из подготовленных контролов. Кстати, заметили, что они кроме дизайна, будут отличаться еще и способом обработки ошибок? Первый выводит месаджбокс, второй моргает фоном. Ладно, дизайн главной формы:

    Ну и пишем обработчики кнопок:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        IBaseAbstractControl _control = null;
    
        private void btCreateControl_Click(object sender, EventArgs e)
        {
            switch (comboBox1.SelectedIndex)
            {
                case 0:
                    _control = new FirstControl();
                    break;
                case 1:
                    _control = new SecondControl();
                    break;
                default:
                    MessageBox.Show("Выбирите способ ввода");
                    return;
            }
            btCreateControl.Enabled = false;
            _control.Header = "Введите текст не менее тре символов";
            panel1.Controls.Add((Control)_control);
            btCheckText.Enabled = true;
        }
    
        private void btCheckText_Click(object sender, EventArgs e)
        {
            if (_control.InputString.Length < 3)
            {
                _control.ShowError();
            }
            else
            {
                MessageBox.Show("Вы ввели текст: " + _control.InputString);
            }
        }
    }

    Как видно, про компоненты что то говориться, только в момент вызова конструктора. Вся остальная работа ведется через интерфейс. Т.е. мы вызываем конструктор компонента в зависимости от выбора пользователя, результат записываем в переменную типа наш интерфейс. Устанавливаем текст, помещаем компонент в приготовленную специально для него панель. Ну и в обработчике второй кнопки получаем текст из компонента и, при необходимости, сообщаем что его нам ввели неправильно.         
    18 сентября 2012 г. 15:30
    Отвечающий
  • я так понял вы подключали компоненты через референс в проекте, скорее всего я неправильно сформулировал вопрос у меня компоненты лежат в разных папках и следовательно имеют разный путь,  при выборе конкретной dll он должен подключатся в проект и уже от туда использовать его свойства и методы,  т.е если я добавлю новыю dll она должна схватыватся основной программой, как то так заранее извеняюсь за то что не могу сформулировать вопрос более точно.
    18 сентября 2012 г. 15:42
  • Это тоже не вызывает проблем. Вот, опять же, статья в моем блоге на эту тему.
    18 сентября 2012 г. 15:45
    Отвечающий
  •  что такое IFactoryForm и для чего он нужен это реализация dll или интерфейса для связя с dll 
    19 сентября 2012 г. 3:57
  • Имя интерфейса, который должны реализовывать формы, которые я создаю динамически.

    Вам из второго пример надо посмотреть как у меня происходит загрузка классоф (форм) из внешних сборок, про которых я ничего не знаю кроме имени сборки и полного имени класса (формы), а из первого примера все остальное, вставив вызовк конструктора класса (формы) из второго примера в ветки case первого примера.

    • Предложено в качестве ответа Abolmasov Dmitry 19 сентября 2012 г. 6:56
    • Помечено в качестве ответа skemuze 20 сентября 2012 г. 2:40
    19 сентября 2012 г. 4:30
    Отвечающий
  • Привет. Пожалуйста, не забудьте отметить ответы решающие проблему, когда вопрос будет закрыт. Спасибо.


    Для связи [mail]

    19 сентября 2012 г. 6:56