На этом шаге мы рассмотрим пример использования таких компонентов.
В следующем примере мы прибегнем к помощи переключателей для того, чтобы показывать в диалоговом окне изображения животных. На рисунке 1 показано, как выглядит окно при запуске программы на выполнение.
Рис.1. Окно с группой переключателей и изображением волка
Теперь в правой части окна вместо списка размещена группа переключателей. Установлен (выбран) может быть один и только один из них. В соответствии с тем, какой переключатель установлен, в области метки отображается картинка с изображением животного. На рисунке 2 показано окно с изображением медведя (в соответствии с выбранным переключателем).
Рис.2. Окно с группой переключателей и изображением медведя
Переключатель реализуется как объект класса RadioButton. Особенность переключателей в том, что они объединяются в группы и в группе может быть установлен только один переключатель. Поэтому мало собственно создать переключатели. Их еще нужно сгруппировать. Для этого создается объект для группы переключателей. Такой объект создается на основе класса GroupBox. Все переключатели, добавленные в объект группы, образуют группу переключателей.
В программе, кроме переключателей, появляется еще один новый для нас компонент. Это панель. Панель реализуется через объект класса Panel. Вообще панель - это прямоугольная область, главное назначение которой состоит в том, чтобы быть контейнером для размещения графических компонентов. В рассматриваемой далее программе создается панель, на эту панель помещается метка с изображением, группа переключателей и кнопка, а затем панель добавляется в окно. Как это выглядит на практике, показано в примере ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Windows.Forms; namespace pr278_1 { // Класс для кнопки: class MyButton: Button { // Конструктор: public MyButton(string name): base() { // Название кнопки: this.Text = name; // Обработчик события, связанного со щелчком // по кнопке: this.Click += (x, y) => { Application.Exit(); }; } } // Класс окна: 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 RadioButton[] radio; // Конструктор: public MyForm(): base() { // Ширина окна: this.Width = 310; // Высота окна: this.Height = 200; // Режим явного определения начального // положения окна: this.StartPosition = FormStartPosition.Manual; // Координаты окна: this.Location = new Point(400, 300); // Заголовок окна: this.Text = "B мире животных"; // Окно фиксированных размеров: this.FormBorderStyle = FormBorderStyle.FixedSingle; // Окно нельзя развернуть на весь экран: this.MaximizeBox = false; // Объект панели: Panel pnl = new Panel(); // Ширина панели: pnl.Width = this.ClientSize.Width - 10; // Высота панели: pnl.Height = this.ClientSize.Height - 10; // Горизонтальная координата панели: pnl.Left = 5; // Вертикальная координата панели: pnl.Top = 5; // Рамка вокруг панели: pnl.BorderStyle = BorderStyle.FixedSingle; // Объект метки: pict = new Label(); // Положение и размеры метки: pict.SetBounds(5, 5, 154, 104); // Рамка вокруг метки: pict.BorderStyle = BorderStyle.FixedSingle; // Начальное изображение для метки: pict.Image = Image.FromFile(path + files[index]); // Добавление метки на панель: pnl.Controls.Add(pict); // Создание массива ссылок на объекты переключателей: radio = new RadioButton[animals.Length]; // Объект для группы переключателей: GroupBox gb = new GroupBox(); // Координаты группы переключателей: gb.Left = pict.Right + 5; gb.Top = pict.Top; // Размеры группы переключателей: gb.Width = 115; gb.Height = pict.Height; // Заголовок для группы переключателей: gb.Text = "Ваш выбор"; // Шрифт для группы переключателей: gb.Font = new Font("Courier New", 12, FontStyle.Bold); // Высота области для переключателя: int h = 17; // Создание объектов для переключателей и добавление // переключателей в группу: for(int k = 0; k < radio.Length; k++) { // Объект переключателя: radio[k] = new RadioButton(); // Подпись для переключателя: radio[k].Text = animals[k]; // Состояние переключателя (установлен или нет): radio[k].Checked = (k == index); // Положение и размеры переключателя: radio[k].SetBounds(10, 20 + k * (h + 4), 100, h); // Обработчик для события, связанного с изменением // состояния переключателя: radio[k].CheckedChanged += OnRadioClick; // Добавление переключателя в группу: gb.Controls.Add(radio[k]); } // Добавление группы переключателей на панель: pnl.Controls.Add(gb); // Объект кнопки: MyButton btn = new MyButton("OK"); // Высота кнопки: btn.Height = 30; // Ширина кнопки: btn.Width = pnl.Width / 3; // Горизонтальная координата кнопки: btn.Left = pnl.Width / 3; // Вертикальная координата кнопки: btn.Top = pict.Bottom + 5; // Шрифт для кнопки: btn.Font = gb.Font; // Добавление кнопки на панель: pnl.Controls.Add(btn); // Добавление панели в окно: this.Controls.Add(pnl); } // Метод для обработки событий, связанных с изменением // состояния переключателя: private void OnRadioClick(object obj, EventArgs ea) { // Перебор переключателей: for( int k = 0; k < radio.Length; k++) { // Проверка состояния переключателя: if (radio[k].Checked) { // Новое изображение для пиктограммы: pict.Image = Image.FromFile(path + files[k]); // Завершение выполнения метода: return; } } } } // Главный класс: class Program { [STAThread] // Главный метод: static void Main() { // Отображение окна: Application.Run(new MyForm()); } } }
Какие особенности этой программы? Их несколько. Начнем с того, что в программе для кнопки описывается специальный класс MyButton. Класс создается наследованием класса Button. Конструктору класса передается текстовое значение, определяющее название кнопки. Также для кнопки регистрируется обработчик события (анонимный метод на основе лямбда-выражения), связанного со щелчком по кнопке. Обработка состоит в том, что завершается выполнение программы. Таким образом, кнопки, реализованные в виде объектов класса MyButton, сразу функциональные - щелчок по такой кнопке приводит к завершению выполнения программы.
В классе окна MyForm (подкласс класса Form) много знакомых "мотивов". Но есть и новые команды и инструкции. Так, в классе имеется поле radio, которое является ссылкой на массив объектных переменных класса RadioButton. В конструкторе класса MyForm командой
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(400, 300);
Объект панели pnl создается командой
Panel pnl = new Panel(); .
pnl.Width = this.ClientSize.Width - 10; .
pnl.Height = this.ClientSize.Height - 10;
Координаты панели определяются командами
pnl.Left = 5;
pnl.Top = 5;
pnl.BorderStyle = BorderStyle.FixedSingle; .
Объект метки pict создается на основе класса Label. Метка добавляется на панель командой
pnl.Controls.Add(pict); .
Массив со ссылками на объекты переключателей создаем командой
radio = new RadioButton[animals.Length]; .
GroupBox gb = new GroupBox();
gb.Left = pict.Right + 5;
gb.Top = pict.Top; .
Размеры группы переключателей определяются командами
gb.Width = 115;
gb.Height = pict.Height;
gb.Text = "Ваш выбор"; .
gb.Font = new Font("Courier New", 12, FontStyle.Bold);
radio[k] = new RadioButton();
radio[k].Text = animals[k];
radio[k].Checked = (k == index); .
radio[k].SetBounds(10, 20 + k * (h + 4), 100, h);
radio[k].CheckedChanged += OnRadioClick; .
gb.Controls.Add(radio[k]);
После завершения оператора цикла группа переключателей добавляется на панель командой
pnl.Controls.Add(gb); .
Объект кнопки btn создается на основе класса MyButton. При создании объекта название кнопки передается аргументом конструктору класса MyButton. Обработчик для этой кнопки уже определен, а параметры и координаты кнопки определяем явно. Ширина кнопки равна трети от ширины панели (команда
btn.Width = pnl.Width / 3;
btn.Height = 30; .
btn.Left = pnl.Width / 3;
btn.Top = pict.Bottom + 5;
btn.Font = gb.Font;
pnl.Controls.Add(btn);
this.Controls.Add(pnl); .
Закрытый метод OnRadioClick() предназначен для обработки событий, связанных с изменением состояния переключателей. В теле метода выполняется конструкция цикла, в которой перебираются все переключатели из массива radio. Для каждого переключателя выполняется проверка состояния (значение свойства Checked объекта переключателя - true для установленного переключателя и false для неустановленного переключателя). Если переключатель установлен, то командой
pict.Image = Image.FromFile(path + files[k]);
В главном методе программы традиционно создается и отображается окно с изображением, переключателями и кнопкой (см. рисунок 1).
На следующем шаге мы рассмотрим опцию и поле ввода.