Тема: «Компоненты для организации работы программ с вариантами»
План
1. Ввод и отображение чисел
2. Компоненты выбора со списков
3. Переключатели
4. Флажки
5. Компонент Imagelist
6. Закладки
Ввод целых чисел в обычное текстовое поле ничем не защищен, и пользователь вместо цифр может ввести произвольные символы, что может приводить к ошибкамv выполнения программы. Для решения данной проблемы можно использовать два подхода:
- программно фильтровать вводимые символы, разрешая ввод только чисел;
- использовать другие компоненты для ввода чисел.
Существует компонент NumericUpDown
, позволяющих вводить, отображать и редактировать
только числа. Визуально он представляет из себя тестовое поле, в правой
части которого отображаются кнопки счетчика. Пользователь может либо ввести
число с клавиатуры, либо воспользоваться кнопками для счетчика. По умолчанию
знгачение счетчик изменяется от 0 до 100 с шагом 1. Но эти настройки можно
изменить.
Компонент имеет следующие основные свойства:
Свойство |
Описание |
|
Name |
Имя компонента |
|
DecimalPlaces |
Задает число знаков после запятой. Данное свойство нужно обязательно задавать, если шаг изменения счетчика Increment задается дробным |
|
Increment |
Шаг изменения счетчика. Можно задать как целое, так и дробное значение. |
|
InterceptArrowKey |
Включает возможность изменения значения счетчика с помощью стрелок управления курсором "вверх" и "вниз" |
|
Maximum |
Максимально допустимое значение изменения счетчика |
|
Mininmum |
Минимально допустимое значение изменения счетчика |
|
ThousendsSeparator |
Включает разделение разрядов в больших числах (единицы, сотни, тысячи т .п.) |
|
UpDownAlign |
Задает размещение стрелок счетчика внутри компонента (слева или справа) |
|
Value |
Текущее значение компонента |
Содержимое счетчика определяется с помощью свойства Value. При этом данное свойство хранится в числовом формате и преобразования из текста в число выполнять не нужно.
2. Компоненты выбора из списка
Если пользователю нужно ввести некоторое текстовое значение, и это значение является частью некоторого набора (дни недели, месяцы года, должности, улицы и т.п.), то лучше использовать выбор значения из списка. Такой подход защитит программу от ошибок ввода, а скорость работы пользователя с программой увеличится.
Компоненты ListBox и ComboBox отображают списки значений и позволяют пользователю выбрать в нем нужный элемент.
Компонент имеет следующие основные свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента |
|
ColumnWidth |
Ширина колонок, если список состоит из нескольких колонок |
|
Items |
Перечень значений списка |
|
MultiColumn |
Отображает значения списка в несколько колонок. Количество колонок автоматически подгоняется под ширину самого компонента |
|
SelectionMode |
Задает тип выбора элементов списке (One - только один, MultiSimple - несколько без нажатия на специальные клавиши, MultiExtended - несколько, удерживая Ctrl или Shift) |
|
Sorted |
Включает сортировку значений в списке. Обратите внимание, что все значения воспринимаются как текст. Поэтому 11 меньше, чем 2 (сортировка по первому символу 1<2) |
|
Text |
Текущее значение в списке. |
Компонент имеет свойства, доступные только при написании кода:
- SelectedIndex - номер выбранного строки в списке (нумерация с 0). Если ни одна строка не выбрана, свойство равняется -1;
- SelectedIndices - массив номеров выбранных строк в списке (если выбрано несколько строк);
- SelectedItem - выбранный элемент в списке. Имеет универсальный тип object. Перед использование м требуется конвертировать данное свойство в нужный формат;
- SelectedItems - массив выбранных элемент в списке. Каждый выбранный элемент имеет универсальный тип object. перед использование м требуется конвертировать данное свойство в нужный формат;
- Items.Count - общее число элементов в списке;
- SelectedIndices.Count или SelectedItems.Count - общее число выбранных элементов в списке;
С помощью свойства SelectedIndex можно узнать индекс выбранной строки в списке. По умолчанию SelectedIndex = -1. Это означает, что ни один элемент в списке не выбран. Если вы хотите задать этому свойству какое-то другое значение, то есть установить выбор по умолчанию, который будет показан в момент начала работы приложения, то сделать это можно, например, в обработчике события формы Load, введя в него оператор вида:
listBox1.SelectedIndex=0;
Чтение одиночных выбранных значений из списка
Все значения списка хранятся в массиве Items. Чтобы получить значение нужного элемента, то можно использовать запись вида:
listBox1.Items[i], - где i - номер нужного элемента (нумерация с 0)
Если же нужно получить значение выбранного элемента, то вместо номер элемента задается с помощью свойства SelectedIndex:
listBox1.Items[listBox1.SelectedIndex]
Замечание. Обратите внимание, что любой элемент списка имеет универсальный тип object. Если вы хотите использовать значение элемента списка в коде, то его нужно предварительно конвертировать в требуемый формат. Например:
listBox1.Items[listBox1.SelectedIndex].ToString() //конвертируем в текст
Convert.ToDouble(listBox1.Items[listBox1.SelectedIndex]) //конвертируем в вещественный тип
Convert.ToInt32(listBox1.Items[listBox1.SelectedIndex]) //конвертируем в целый тип
Чтение нескольких выбранных значений из списка
Если список позволяет пользователю выбор нескольких значений, то их обработка может выполняться с помощью цикла. При этом можно использовать как цикл for, так и цикл for each.
Пример. Пусть в списке отображаются некоторые числовые значения. Пользователь выбрал несколько значений. Напишем цикл for, который выводит каждое из выбранных значений в сообщении.
for (int i = 0; i < listBox1.SelectedItems.Count; i++)
MessageBox.Show(listBox1.SelectedItems[i].ToString());
Запишем этот же пример с помощью цикла for each.
foreach(object a in listBox1.SelectedItems)
MessageBox.Show(a.ToString());
Пример. Найдем сумму значений, выбранных в списке.
//сумму обнуляем
double sum=0;
//в цикле находим суммы выбранных элементов (конвертируем в число)
for (int i = 0; i < listBox1.SelectedItems.Count; i++)
sum+=Convert.ToDouble(listBox1.SelectedItems[i]);
//после цикла выводим результат
MessageBox.Show("Сумма = "+sum.ToString());
Запишем этот же пример с помощью цикла for each.
//сумму обнуляем
double sum=0;
//в цикле находим суммы выбранных элементов (конвертируем в число)
foreach(object a in listBox1.SelectedItems)
sum+=Convert.ToDouble(a);
//после цикла выводим результат
MessageBox.Show("Сумма = "+sum.ToString());
Методы списка
Для работы со списком используют следующие методы:
listBox1.Clear(); //очищает список;
listBox1.ClearSelected(); //снимает выделение со всех элементов;
listBox1.Items.Add("текст"); //добавляет в список новую строку;
listBox1.Items.RemoveAt(i); //удаляет элемент с номером i
listBox1.Items.RemoveAt(listBox1.ItemIndex); //удаляет выбранный элемент
listBox1.Focus(); //передает фокус списку
Основными событиями компонента ListBox является событие SelectedIndexChanged - выбор значения в списке. Наступит, даже если кликнуть на уже выбранном значении.
Для работы со списками рассмотрим пример.
Пусть имеется форма вида:

Для того, чтобы в левом списке по умолчанию была выбрана первая строка, необходимо в событии формы Load написать код:
private void Form1_Load(object sender, EventArgs e)
{
listBox1.SelectedIndex = 0;
}
Кнопка «+» добавляет в левый список содержимое текстового поля и для демонстрации ставит курсор на последний (добавленный) элемент. При этом нужно проверить, чтобы текстовое поле не было пустым. Для кнопки напишем код:
private void button1_Click(object sender, EventArgs e)
{
//если поле не пустое
if (textBox1.Text != "")
{
//добавляем содержимое поля в список
listBox1.Items.Add(textBox1.Text);
//ставим указатель в списке на последнее значение,
//чтобы увидеть добавленный элемент
listBox1.SelectedIndex = listBox1.Items.Count - 1;
//очищаем поле
textBox1.Text = "";
}
//если поле пустое, сообщение об ошибке
else
MessageBox.Show("Нет данных для добавления", "Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
//ставим курсор в поле для нового добавления
textBox1.Focus();
}
Кнопка "-" удаляет из левого списка выбранную строку. При этом нужно выдать запрос на выполнение операции и проверить, есть ли выбранная строка для удаления . Для кнопки напишем код:
private void button2_Click(object sender, EventArgs e)
{
//если элемент в списке выбран (SelectedIndex не равно -1)
if (listBox1.SelectedIndex!=-1)
{
//выдаем запрос на удаление элемента
if (MessageBox.Show("Удалить выбранный элемент?", "Подтвердите",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
//если пользователь подтвердил удаление
listBox1.Items.RemoveAt(listBox1.SelectedIndex);
}
//если элемент в списке не выбран
else
//выдаем сообщение об ошибке
MessageBox.Show("Не выбран элемент для удаления", "Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
Кнопка «>» переносит строку из левого списка в правый. При этом нужно проверить, есть ли в левом списке выбранная строка для перемещения. Для кнопки напишем код:
private void button4_Click(object sender, EventArgs e)
{
//если элемент в списке выбран (SelectedIndex не равно -1)
if (listBox1.SelectedIndex != -1)
{
//из первого списка добавляем элемент во второй список
listBox2.Items.Add(listBox1.Items[listBox1.SelectedIndex]);
//в первом списке удаляем добавленное значение
listBox1.Items.RemoveAt(listBox1.SelectedIndex);
}
//если элемент в списке не выбран
else
//выдаем сообщение об ошибке
MessageBox.Show("Не выбран элемент для переноса", "Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
Кнопка «<» идентична кнопке «>», но имена списков нужно поменять.
Кнопка «>>|» переносит все элементы из левого списка в правый. Для кнопки напишем код:
private void button3_Click(object sender, EventArgs e)
{
//пока количество элементов в первом списке больше 0
while (listBox1.Items.Count>0)
{
//становимся на первый элемент в списке
listBox1.SelectedIndex = 0;
//добавляем его во второй список
listBox2.Items.Add(listBox1.Items[listBox1.SelectedIndex]);
//удаляем его из первого списка
listBox1.Items.RemoveAt(listBox1.SelectedIndex);
}
}
Кнопка «<<» идентична кнопке «>>», но имена списков нужно поменять.
Компонент выпадающего списка ComboBox
Рассмотрим теперь компонент выпадающего списка ComboBox. Данный компонент представляет собой комбинацию компонента ListBox и текстового поля TextBox. То есть в нем можно как выбрать значение из готового перечня, так и ввести с клавиатуры. Этот компонент в основном имеет те же свойства и методы, что и ListBox, занимает на форме намного меньше места. Однако он имеет и некоторые собственные свойства:
|
Свойство |
Описание |
|
DropDownHeight |
Высота раскрывающейся области списка |
|
DropDownStyle |
Стиль списка: Simple - обычный ListBox, над которым находится текстовое поле с возможностью ввода; DropDown - обычный выпадающий список с возможностью ввода текста; DropDownList - выпадающий список без возможности ввода текста |
|
DropDownWidth |
Ширина раскрывающейся области списка |
|
MaxDropDownItems |
Максимальное число элементов, отображаемых в раскрывающейся области списка |
|
MaxLength |
Максимальная длина вводимого текста |
|
Text |
Значения выбранного или введенного элемента списка |
Список ComboBox не предполагает возможности выбора нескольких элементов. Остальные свойства, события и методы полностью идентичны компоненту ListBox.
3. Переключатели
Радиокнопки образуют группы взаимосвязанных индикаторов, из которых может быть выбран только один. Они используются для выбора пользователем одной из нескольких взаимоисключающих альтернатив, например, отдела, в котором работает сотрудник, или пола сотрудника.
Для создания радиокнопки на форме используется компонент RadioButton, имеющий свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента |
|
AutoCheck |
Включает автоматическое изменение состояния компонента при клике на нем |
|
AutoEllipsis |
Включает обработку отображения длинного текста в надписи переключателя. Если текст не помещается, то он урезается и заканчивается многоточием. При наведении на него мышью во всплывающей подсказке отображается весь текст. |
|
CheckAlign |
Расположения переключателя относительно надписи |
|
Checked |
Состояние переключателя. Checked = true (включен), Checked = false (выключен) |
|
Image |
Картинка, отображаемая возле компонента |
|
ImageAlign |
Выравнивание картинки |
|
ImageIndex |
Номер картинки из коллекции ImageList |
|
ImageList |
Имя коллекции ImageList с коллекцией картинок |
|
Text |
Текст надписи возле переключателя |
|
TextAlign |
Выравнивание текста надписи возле переключателя |
|
TextImageRelation |
Задает способ перекрытия текста надписи и картинки возле переключателя |
Радиокнопки, размещенные в пределах формы всегда работают как одна общая группа, независимо от их расположения. Если нужно создать разные группы радиокнопок, то их помещают внутри компонентов GroupBox. Компонент GroupBox представляет собой рамку, заголовок которой можно задать с помощью свойства Text. При проектировании интерфейса следите за тем, чтобы один из переключателей в каждой группе был включен (Checked = true).
Рассмотрим на примере использования переключателей. Пусть имеется форма вида:

Необходимо для кнопки написать обработчик, который на основании первых двух полей вычисляет значения в зависимости от выбранного переключателя и помещает ответ в третье поле.
private void button1_Click(object sender, EventArgs e)
{
double a, b, rez;
//в переменные записываем значения исходных текстовых полей
a = Convert.ToDouble(textBox1.Text);
b = Convert.ToDouble(textBox2.Text);
//если включен 1-й переключатель
if (radioButton1.Checked)
//считаем сумму
rez = a + b;
//иначе, если включен 2-й переключатель
else if (radioButton2.Checked)
//считаем разность
rez = a - b;
//иначе, если включен 3-й переключатель
else if (radioButton3.Checked)
//считаем произведение
rez = a * b;
//иначе, если включен 4-й переключатель
else
//если делитель не равен 0
if (b != 0)
//считаем частное
rez = a / b;
//иначе, если делитель равен 0
else
{
//выдаем сообщение "Деление на 0!"
textBox3.Text = "Деление на 0!";
//завершаем работу
return;
}
//в третьем поле отображаем результат
textBox3.Text = rez.ToString();
}
4. Флажки
Флажки CheckBox используются в приложениях в основном для того, чтобы пользователь мог включать и выключать какие-то опции, или для индикации состояния. Флажок имеет те же свойства, что и RadioButton, но данный компонент работает независмо от остальных подобных компонентов. Если в группе переключателей только один из них может быть выбран, то при работе с флажками пользователь может одновременно включать или выключать любое их количество на форме.
Рассмотрим на примере принцип работы с флажками. Добавим на нашу форму два флажка для задания типа вывода результата.

В нашем коде для кнопки добавим в конец код:
//если выбран первый флажок
if (checkBox1.Checked)
//выдаем ответ в сообщении
MessageBox.Show(rez.ToString(),"Ответ",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
//если выбран второй флажок
if (checkBox2.Checked)
{
//создаем в памяти экземпляр второй формы
Form2 form2 = new Form2();
//на форме в метке отображаем результат
form2.label1.Text=rez.ToString();
//показываем форму на экране
form3.Show();
}
Для работы приведенного кода необходимо выполнить ряд действий:
- создать новую форму Form2 и разместить на ней метку label1;
- чтобы иметь доступ к метке label1 на второй форме, необходимо для этого компонента изменить уровень доступа. Выделите компонент label1 на второй форме и задайте свойство Modifiers = Public.
При рассмотрении свойств компонентов RadioButton и CheckBox было указано, что в их свойстве ImageList можно указать имя некоторой коллекции картинок одинакового размера для размещения на компонентах. Для создания такой коллекции используется одноименный компонент ImageList.
Компонент является невидимым во время выполнения программы и служит для хранения коллекции изображений, обратиться к которым можно по их порядковому номеру (нумерация с 0). Основные свойства компонента:
|
Свойство |
Описание |
|
Name |
Имя компонента |
|
Images |
Коллекция картинок |
|
ImageSize |
Размер картинок по ширине и высоте |
|
TransparentColor |
Цвет, который на картинке будет невидимым |
Для наполнения коллекции картинками вначале задайте нужный размер с помощью свойства ImageSize, а затем в свойстве Images добавьте файлы с изображениями, если нужно, измените порядок их следования в коллекции.
Каждое загруженное в коллекцию изображение получает индекс. Именно на эти индексы впоследствии можно ссылаться в свойстве ImageIndex соответствующих компонентов.
Если на форме планируется разместить большое число компонентов (особенно это касается форм задания параметров программы), то разработчик либо вынужден будет увеличивать размер формы, либо использовать специальный компонент TabControl.
Данный компонент представляет собой набор панелей (закладок), которые позволяют экономить пространство формы. При работе с компонентов нужно различать два вида свойст:
- свойства всего компонента целиком;
- свойства отдельной панели.
Компонент в целом имеет свои свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента |
|
Alignment |
Размещение закладок на компоненте (Top - вверху, Bottom - внизу, Left - слева, Right - справа) |
|
ImageList |
Имя коллекции с рисунками, если планируется отображать их на закладках |
|
Multiline |
Включаем многострочное размещение закладок на компоненте |
|
TabPages |
Коллекция панелей (закладок). |
По умолчанию компонент имеет две панели, закладки которых размещаются внизу компонента. Чтобы изменить количество, порядок следоания закладок, а также для задания свойств нужной закладки откройте свойство TabPages компонента TabControl.
В результате в новом окне в левой части можно добавлять, удалять и изменять порядок панелей.
В правой части отображаются свойства выделенной панели. К основным свойства относятся:
|
Свойство |
Описание |
|
Name |
Имя компонента |
|
ImageIndex |
Номер картинки из коллекции ImageList |
|
text |
Текст надписи на закладке |
Вы можете размещать на каждой панели все необходимые компоненты так же, как размещаете на обычной форме. Доступ ко всем компонентам выполняется по их именам без ограничений, так как все они размещены на одной форме.
Иногда в программе нужно перейти на конкретную панель без участия пользователя. Для этого необходимо свойству SelectedIndex компонента TabControl присвоить номер нужной панели:
tabControl1.SelectedIndex=i;
где i – номер панели. Нумерация начинается с 0.
Например, чтобы перейти на третью панель нужно ввести команду:
tabControl1.SelectedIndex=2;
Указанна страница под номером 2, т.к. нумерация страниц начинается с 0.
Вопросы для самоконтроля
1. Опишите компонент для ввода целых чисел.
2. Опишите свойства компонента ListBox. Какие методы для работы со списками вы знаете? Примеры.
3. Опишите компоненты CheckBox и RadioButton. Какие основные свойства имеют данные компоненты? Как создать различные группы переключателей на одной форме?
4/ Для чего нужен ImageList и как с ним работать?
5. Как создать закладки на форме? Опишите нужный компонент, указав свойства самого компонента и свойства отдельной панели на нем. Как перейти на нужную панель в коде программы?