Лекция № 3

Тема: «Компоненты для организации работы программ с вариантами»

 

План

1. Ввод и отображение чисел

2. Компоненты выбора со списков

3. Переключатели

4. Флажки

5. Компонент Imagelist

6. Закладки

 

1. Ввод и отображение чисел

Ввод целых чисел в обычное текстовое поле ничем не защищен, и пользователь вместо цифр может ввести произвольные символы, что может приводить к ошибкам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.

 

5. Компонент ImageList

 

При рассмотрении свойств компонентов RadioButton и CheckBox было указано, что в их свойстве ImageList можно указать имя некоторой коллекции картинок одинакового размера для размещения на компонентах. Для создания такой коллекции используется одноименный компонент ImageList.

Компонент является невидимым во время выполнения программы и служит для хранения коллекции изображений, обратиться к которым можно по их порядковому номеру (нумерация с 0). Основные свойства компонента:

 

Свойство

Описание

Name

Имя компонента

Images

Коллекция картинок

ImageSize

Размер картинок по ширине и высоте

TransparentColor

Цвет, который на картинке будет невидимым

 

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

Каждое загруженное в коллекцию изображение получает индекс. Именно на эти индексы впоследствии можно ссылаться в свойстве ImageIndex соответствующих компонентов.

 

6. Закладки

 

Если на форме планируется разместить большое число компонентов (особенно это касается форм задания параметров программы), то разработчик либо вынужден будет увеличивать размер формы, либо использовать специальный компонент 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. Как создать закладки на форме? Опишите нужный компонент, указав свойства самого компонента и свойства отдельной панели на нем. Как перейти на нужную панель в коде программы?