Всем привет.
Черный плащ спешит на помощь, поэтому сегодня опять топик про вопрос на форуме MSDN. Ну, а так как у меня уже был цикл статей про позднее связывание, то давайте я его и продолжу.
Коротенько суть проблемы: Пользователь вводит некоторые данные, на основе которых принимается решение, какой компонент создать. Ну а дальше, т.к. все компоненты ведут себя одинаково, то работа с ними должна идти через схожий функционал (имена свойств и методов заранее известны).
Для демонстрации, я воспользуюсь двумя компонентами, позволяющими вводить строку и сообщать о том, что пользователь ввел бяку.
Для реализации задумки, создадим интерфейс, который будет реализовывать публичный контракт:
string Header
{
set;
}
get;
}
Как видно, добавлены свойство задающее заголовок, свойство возвращающее введенный текст и метод заставляющий компонент показать сообщение об ошибке.
Добавляем в проект UserControl и формируем его интерфейс:
Добавляем ему поддержку нашего интерфейса и реализуем соответствующие методы:
public FirstControl()
{
InitializeComponent();
}
set { label1.Text = value; }
}
get { return textBox1.Text; }
}
MessageBox.Show("Вы ввели неправильные данные");
}
}
Получилось достаточно просто. Добавляем второй UserControl, вот с таким дизайном (я заполнил Items у ComboBox всякими разными строками):
Также наследуем его от интерфейса и реализуем свойства и метод:
public SecondControl()
{
InitializeComponent();
}
set { label1.Text = value; }
}
get { return comboBox1.Text; }
}
comboBox1.BackColor = Color.Red;
(new Task(() => { Thread.Sleep(1000); this.BeginInvoke((Action)(() => comboBox1.BackColor = Color.White)); })).Start();
}
}
Все, переходим к демо приложению.
На главной форме, спросим у пользователя, как он хочет вводить текст, с донаборщиком или просто, в зависимости от этого будем создавать один из подготовленных контролов. Кстати, заметили, что они кроме дизайна, будут отличаться еще и способом обработки ошибок? Первый выводит месаджбокс, второй моргает фоном.
Ладно, дизайн главной формы:
Ну и пишем обработчики кнопок:
public Form1()
{
InitializeComponent();
}
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;
}
if (_control.InputString.Length < 3)
{
_control.ShowError();
}
else
{
MessageBox.Show("Вы ввели текст: " + _control.InputString);
}
}
}
Как видно, про компоненты что то говориться, только в момент вызова конструктора. Вся остальная работа ведется через интерфейс. Т.е. мы вызываем конструктор компонента в зависимости от выбора пользователя, результат записываем в переменную типа наш интерфейс. Устанавливаем текст, помещаем компонент в приготовленную специально для него панель. Ну и в обработчике второй кнопки получаем текст из компонента и, при необходимости, сообщаем что его нам ввели неправильно.
Ну и вот так выглядит приложение в процессе работы:
Все.
P.s. Это жесть объяснять дизайн интерфейса в WinForms, без картинки не объяснишь. Толи дело WPF, вставил XAML и все понятно.
Черный плащ спешит на помощь, поэтому сегодня опять топик про вопрос на форуме MSDN. Ну, а так как у меня уже был цикл статей про позднее связывание, то давайте я его и продолжу.
Коротенько суть проблемы: Пользователь вводит некоторые данные, на основе которых принимается решение, какой компонент создать. Ну а дальше, т.к. все компоненты ведут себя одинаково, то работа с ними должна идти через схожий функционал (имена свойств и методов заранее известны).
Для демонстрации, я воспользуюсь двумя компонентами, позволяющими вводить строку и сообщать о том, что пользователь ввел бяку.
Для реализации задумки, создадим интерфейс, который будет реализовывать публичный контракт:
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);
}
}
}
Как видно, про компоненты что то говориться, только в момент вызова конструктора. Вся остальная работа ведется через интерфейс. Т.е. мы вызываем конструктор компонента в зависимости от выбора пользователя, результат записываем в переменную типа наш интерфейс. Устанавливаем текст, помещаем компонент в приготовленную специально для него панель. Ну и в обработчике второй кнопки получаем текст из компонента и, при необходимости, сообщаем что его нам ввели неправильно.
Ну и вот так выглядит приложение в процессе работы:
Все.
P.s. Это жесть объяснять дизайн интерфейса в WinForms, без картинки не объяснишь. Толи дело WPF, вставил XAML и все понятно.
Комментариев нет:
Отправить комментарий