Шаг 276.
Язык программирования C#. Начала.
Приложения с графическим интерфейсом. Использование списков

    На этом шаге мы рассмотрим пример использования списков.

    В следующей программе мы познакомимся с таким графическим компонентом, как раскрывающийся список. Раскрывающийся список реализуется через объект класса ComboBox. Но прежде чем приступить к рассмотрению программного кода, остановимся на том, как программа работает. Так будет легче понять программный код.

    При запуске программы появляется диалоговое окно, представленное на рисунке 1.


Рис.1. Диалоговое окно с изображением волка

    Половину окна занимает изображение. В правой части окна есть раскрывающийся список и кнопка ОК. В раскрывающемся списке выбирается название животного, а в области изображения появляется соответствующая картинка. При отображении окна в списке выбран элемент Волк, и соответственно в окне отображается картинка с волком. Какие еще элементы есть в раскрывающемся списке, показано на рисунке 2.


Рис.2. В раскрывающемся списке можно выбрать элемент (название животного)

    При выборе нового элемента изменения (смена картинки) наступают автоматически. На рисунке 3 показано окно с изображением лисы.


Рис.3. Диалоговое окно с изображением лисы

    Окно с изображением медведя представлено на рисунке 4.


Рис.4. Диалоговое окно с изображением медведя

    Наконец, окно с изображением енота показано на рисунке 5.


Рис.5. Диалоговое окно с изображением енота

    Если щелкнуть по кнопке ОК, то окно закроется и программа завершит выполнение. Такая вот простая программа. Ее код представлен ниже.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;
using System.Drawing;

namespace pr276_1
{
    // Класс окна является производным от класса Form: 
    class MyForm: Form {
        // Закрытое поле является текстовьм массивом 
        // с названиями животных:
        private string[] animals = {"Волк", "Лиса", "Медведь", "Енот"};
        // Закрытое поле является текстовым массивом 
        // с названиями файлов с изображениями:
        private string[] files = {"wolf.jpg", "fox.jpg", "bear.jpg", "raccoon.jpg"};
        // Закрытое поле содержит путь к каталогу с файлами: 
        private string path = "";
        // Закрытое поле - значение индекса для выбранного 
        // элемента из массива: 
        private int index = 0;
        // Закрытое поле - ссылка на объект метки: 
        private Label pict;
        // Закрытое поле - ссылка на объект 
        // раскрывающегося списка: 
        private ComboBox list;
        // Конструктор: 
        public MyForm(): base() {
            // Заголовок окна: 
            this.Text = "B мире животных";
            // Размеры окна: 
            this.Size = new Size(300, 155);
            // Окно фиксированных размеров: 
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            // Окно нельзя развернуть на весь экран: 
            this.MaximizeBox = false;
            // Создание объекта метки: 
            pict = new Label();
            // Положение и размеры метки: 
            pict.SetBounds(5, 5, 154, 104);
            // Тип рамки вокруг метки: 
            pict.BorderStyle = BorderStyle.FixedSingle;
            // Изображение для метки: 
            pict.Image = Image.FromFile(path + files[index]);
            // Добавление метки в окно: 
            this.Controls.Add(pict);
            // Создание объекта для списка: 
            list = new ComboBox();
            // Содержимое списка: 
            list.Items.AddRange(animals);
            // Тип списка:
            list.DropDownStyle = ComboBoxStyle.DropDownList;
            // Индекс выбранного в списке элемента: 
            list.SelectedIndex = index;
            // Положение списка:
            list.Left = pict.Right + 5;
            list.Top = pict.Top;
            // Размеры списка: 
            list.Size = new Size(110, 50);
            // Шрифт для списка:
            list.Font = new Font ("Courier New", 12, FontStyle.Bold);
            // Регистрация метода обработчиком для события,
            // связанного с выбором нового элемента в списке: 
            list.SelectedIndexChanged += OnItemChanged;
            // Добавление списка в окно: 
            this.Controls.Add(list);
            // Создание объекта кнопки:
            Button btn = new Button();
            // Название кнопки: 
            btn.Text = "OK";
            // Положение кнопки:
            btn.Left = list.Left;
            btn.Top = list.Bottom + 10;
            // Размеры кнопки:
            btn.Width = list.Width;
            btn.Height = 30;
            // Шрифт для кнопки: 
            btn.Font = list.Font;
            // Регистрация метода обработчиком события,
            // связанного со щелчком по кнопке: 
            btn.Click += OnButtonClick;
            // Добавление кнопки в окно: 
            this.Controls.Add(btn);
        }
        // Метод для обработки события, связанного с выбором 
        // в списке нового элемента:
        private void OnItemChanged(object obj, EventArgs ea){ 
            // Индекс выбранного в списке элемента: 
            int index = list.SelectedIndex;
            // Новое изображение для метки: 
            pict.Image = Image.FromFile(path + files[index]);
        }
        // Метод для обработки события, связанного со щелчком 
        // по кнопке:
        private void OnButtonClick(object obj, EventArgs ea){ 
            // Завершение выполнения приложения: 
            Application.Exit();
        }
    }

    // Главный класс: 
    class Program
    {
        [STAThread]
        // Главный метод: 
        static void Main()
        {
            // Отображение окна:
            Application.Run(new MyForm());
        }
    }
}
Архив проекта можно взять здесь.

    Мы описываем класс MyForm, который является производным от класса Form. В классе есть закрытое поле animals, являющееся текстовым массивом с названиями животных. Элементы этого массива, как мы увидим далее, определяют содержимое раскрывающегося списка. Еще одно закрытое поле files является текстовым массивом с названиями файлов с изображениями животных. Между элементами массивов animals и files должно быть строгое взаимно-однозначное соответствие: название животного в массиве animals должно иметь такой же индекс, как название файла с изображением этого животного в массиве files.

    Закрытое текстовое поле path содержит текст, определяющий путь к каталогу с файлами изображений (значение "", потому что файлы с изображениями находятся рядом с исполняемым файлом в папке bin/Debug).


В данном случае названия файлов wolf.jpg, fox.jpg, bear.jpg и raccoon.jpg. Именно эти названия указаны в массиве files.

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

    Кроме этих полей, в классе MyForm есть еще несколько закрытых полей, используемых в качестве ссылок на объекты графических компонентов. Точнее, их два: поле pict класса Label (ссылка на объект метки) и поле list класса ComboBox (ссылка на объект раскрывающегося списка).

    В конструкторе класса MyForm() выполняются рутинные операции по настройке внешнего вида окна и его компонентов. Большинство из них уже должны быть знакомы читателю. Поэтому остановимся на наиболее важных и принципиально новых командах. Так, положение и размеры объекта метки задаются с помощью метода SetBounds(). Аргументы метода - это координаты метки и ее размеры (ширина и высота). Вокруг метки отображается рамка, тип которой определяется командой

  pict.BorderStyle = BorderStyle.FixedSingle;      .

    Хотя метка обычно называется текстовой, в данном случае она содержит изображение. Изображение, связанное с меткой, определяется командой

  pict.Image = Image.FromFile(path + files[index]);     , 
которой свойству Image объекта метки присваивается ссылка на объект, который создается вызовом статического метода FromFile() из класса Image. Аргументом методу передается текст с полным путем к файлу с изображением (в данном случае такой текст получается объединением содержимого переменной path и элемента files[index]).


Размеры метки заданы на 4 пикселя больше размеров изображений, отображаемых в области метки.

    Объект списка создается командой

  list = new ComboBox();           . 
Чтобы заполнить список содержимым массива animals, используем команду
  list.Items.AddRange(animals);     . 
Здесь из свойства Items объекта списка, возвращающего ссылку на коллекцию элементов списка, вызывается метод AddRange(). Аргументом методу передается ссылка на массив animals. В результате элементы массива добавляются в список.

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

  list.DropDownStyle = ComboBoxStyle.DropDownList;            , 
которой свойству DropDownStyle значением присваивается константа DropDownList из перечисления ComboBoxStyle. В результате получаем раскрывающийся список без возможности редактировать выбранное значение. Присвоив значение свойству SelectedIndex (команда
  list.SelectedIndex = index;
), определяем элемент в списке, который будет выбран по умолчанию (свойству в качестве значения присваивается индекс выбранного по умолчанию элемента).

    Положение списка в окне выбираем в соответствии с положением метки с изображением. Команда

   list.Left = pict.Right + 5;
означает, что левый край списка сдвинут на 5 пикселей по отношению к правому краю метки. По вертикали список находится на том же уровне, что и метка; команда
  list.Top = pict.Top;            .

    Размер списка определяется командой

  list.Size = new Size(110, 50);          , 
то есть присваиванием значения свойству Size. Шрифт для списка определяем командой, в которой свойству Font объекта списка list значением присваивается выражение new Font("Courier New", 12, FontStyle.Bold) (объект шрифта). Но одна команда принципиально важная. Это инструкция
  list.SelectedIndexChanged += OnItemChanged;     , 
которой в список обработчиков события SelectedIndexChanged объекта списка добавляется ссылка на метод OnItemChanged() (закрытый метод класса MyForm). Событие возникает, когда в списке выбирается новый элемент. В таком случае будет вызываться метод OnItemChanged().

    Кнопка реализуется как объект btn класса Button. Название кнопки (текст в кнопке) определяем с помощью команды

  btn.Text = "OK";     . 
Горизонтальная координата кнопки совпадает с левой координатой списка (команда
  btn.Left = list.Left;
). По вертикали кнопка размещена на 10 пикселей ниже нижней границы списка (команда
  btn.Top = list.Bottom + 10;
). Ширина кнопки такая же, как ширина списка (команда
  btn.Width = list.Width;
). Высота кнопки равна 30 пикселям (команда
  btn.Height = 30;
). Шрифт для кнопки применяется такой же, как и шрифт для списка (команда
  btn.Font = list.Font;
). Для обработки события, связанного со щелчком по кнопке, регистрируется закрытый метод OnButtonClick() класса MyForm.


Для добавления компонентов в окно используется метод Add(). Аргументом методу передается ссылка на объект компонента. Метод вызывается из свойства Controls объекта окна.

    Кроме конструктора, в классе MyForm описано еще два закрытых метода. При вызове метода OnItemChanged() (используется для обработки событий, связанных с выбором нового элемента в списке) командой

  int index = list.SelectedIndex; 
запоминается индекс выбранного в раскрывающемся списке элемента (значение этого индекса возвращается свойством SelectedIndex). После этого командой
  pict.Image = Image.FromFile(path + files[index]);
для метки определяется новое изображение. Здесь мы приняли во внимание, что названия животных в массиве animals, на основе которого формируется содержимое списка, и название файлов с изображениями животных в массиве files размещены в строгом соответствии друг другу. Поэтому если мы знаем индекс, под которым название животного входит в массив animals (а значит, и в список), то такой же индекс будет у элемента с названием файла с изображением этого животного в массиве files.

    Метод OnButtonClick() используется для обработки события, связанного со щелчком по кнопке. При вызове метода выполняется команда Application.Exit(), завершающая работу приложения.


Напомним, что события для графических компонентов относятся к типу делегата EventHandler. Этот делегат подразумевает, что соответствующий метод имеет два аргумента: первый - ссылка на объект класса object и второй - ссылка на объект класса EventArgs. Поэтому методы OnItemChanged() и OnButtonClick() описаны с двумя аргументами, хотя эти аргументы в методах не используются.

    В главном методе командой

  Application.Run(new MyForm()); 
создается объект окна, и окно отображается на экране.

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг