void btnyes_Click(object sender, EventArgs e){
MessageBox. Show("Мы и не сомневались, что Вы так думаете!");
}
Выделяем кнопку "Нет". Открываем окно Properties. Переключаемся в окно событий и дважды щелкаем в поле MouseMove.

Рисунок 3.6 - Событие MouseMove для кнопки btnno
В обработчике этого события связываем движение мыши с координатами кнопки и устанавливаем координаты кнопки, куда она будет возвращаться, если во время своего движения выйдет за указанную область:
private void Btnno_MouseMove(object sender, MouseEventArgs e) {
Btnno. Top -= e. Y;
Btnno. Left += e. X;
if (Btnno. Top < -10 || Btnno. Top > 100)
Btnno. Top = 60;
if (Btnno. Left < -80 || Btnno. Left > 250)
Btnno. Left = 120;
}
С событиями мыши связано большинство инструментов во многих программах, а для некоторых, например, графических, — это основа всего взаимодействия с пользователем. Другие события мыши — такие как MouseDown, MouseEnter, MouseUp — могут быть использованы для получения необычной реакции на действия пользователя в этом приложении.
Форматирование элементов управления
Пункт главного меню Format содержит опции выравнивания, изменения размера и блокировки элементов управления:

Рисунок 3.7 - Пункт главного меню Format
При выделении нескольких элементов управления около одного из них появляются темные точки маркера. Свойства выбранных элементов будут изменяться относительно этого, главного элемента управления. Для последовательного выделения нескольких элементов удерживаем клавишу Shift, главным элементом будет последний выделенный элемент.
При создании дизайна формы всегда следует использовать возможности студии для расположения элементов.
Таблица 3.5 - Значение пунктов меню формат
Пункт меню Format | Описание |
Align | Выравнивание выбранных элементов управления |
Make Same Size | Установка равного размера |
Horizontal Spacing | Пробел между элементами по горизонтали |
Vertical Spacing | Пробел между элементами по вертикали |
Center in Form | Расположение элементов управления относительно формы |
Order | Вертикальный порядок элементов управления |
Lock Controls | Блокировка элементов |
Создание меню
Все пользователи Windows-приложений хорошо знакомы с меню, которые представляют собой простой механизм выбора команд.
Добавим в приложение SocOpros простое меню. Для того чтобы выйти из программы, пользователь должен выбрать пункт меню File / Exit.
1. Откройте панель инструментов Toolbox и перетащите управляющий элемент MenuStrip на форму приложения.
2. Для создания выпадающего меню File с пунктом Exit, введите File и Exit, как на рис. 3.8.
3. В окне Properties измените названия этих пунктов меню на MenuFile и MenuExit.
4. Дважды щелкните на Exit, чтобы добавить код в обработчик события File / Exit.
5. Добавьте в обработчик код, закрывающий приложение.
private void MenuExit_Click(object sender, EventArgs e) {
Application.Exit();
}
6. Скомпонуйте и выполните приложение.

Рисунок 3.8 - Использование управляющего элемента MenuStrip
для добавления в форму меню
Выбор пункта меню сочетанием клавиш
В свойстве ShortcutKeys в окне Properties для пункта меню выбрать из появившегося окна нужное сочетание клавиш, для отображения этого сочетания рядом с названием пункта меню. Данный элемент будет активизироваться при нажатии соответствующей этой букве клавиши.

Рисунок 3.9 – Выбор сочетания клавиш для выбора пункта меню
Добавление изображения рядом с пунктом меню
Выбрать свойство Set Image из контекстного меню, нажав правую клавишу мыши на соответствующем пункте меню.
Дополнительные возможности меню
В классе MenuStrip определены свойства, при помощи которых можно, к примеру, устанавливать флажок напротив пункта меню, прятать пункты меню, делать некоторые пункты меню недоступными и т. п. Вот перечень свойств, обеспечивающих подобные возможности.
Таблица 3.6 - Свойства Menultem, обеспечивающие дополнительные возможности меню
Свойство | Назначение |
Checked | Позволяет получить или установить значение, определяющее, будет ли установлен флажок рядом с текстом пункта меню |
Defaultltem | Позволяет получить или установить значение, определяющее, какой пункт меню выбран по умолчанию |
Enabled | Получает или устанавливает значение, определяющее, будет ли доступен тот или иной пункт меню |
Index | Позволяет получить или установить значение, определяющее позицию пункта меню |
Shortcut | Позволяет получить или установить клавиатурную комбинацию, используемую для активизации элемента меню в приложении |
ShowShortcut | Позволяет получить или установить значение, определяющее, будет ли такая клавиатурная комбинация быстрого доступа выведена рядом с названием пункта меню |
Text | Позволяет получить или установить название пункта меню |
Закрытие формы
Давайте сделаем так, что каждый раз, когда пользователь попытается закрыть приложение, приложение будет его спрашивать, действительно ли он хочет выйти. Существует несколько способов закрыть окно:
· щелкнуть на кнопке "X" (Закрыть) в правом верхнем углу окна;
· закрыть окно из системного меню в левом верхнем углу окна,
· закрыть окно с помощью комбинации клавиш Alt+F4,
· выйти из приложения с помощью меню File. Exit
Когда закрывается форма можно остановить процедуру завершения. Просто напечатайте код MessageBox, приведенный ниже:
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
if (MessageBox. Show("Do you want to close", "SocOpros",
MessageBoxButtons. YesNo, MessageBoxIcon. Question) == System. Windows. Forms. DialogResult. Yes)
{
Application. Exit();
}
}
Для того чтобы получить нужное нам поведение приложения, обработчик меню File. Exit должен не выходить из приложения, а закрыть главное окно, вызвав метод Сlose.
private void MenuExit_Click(object sender, EventArgs e) {
Close();
}
Запустите программу, и попытайтесь закрыть окно приложения разными способами.
Диалоговые окна
Диалоговое окно — это набор управляющих элементов, с помощью которых упрощается процесс ввода данных. В предыдущем примере было описано, как создать простое диалоговое окно, которое позволяло бы пользователю на вопрос дать ответ "Да" или "Нет". Для создания таких диалоговых окон используется класс MessageBox (Окно сообщения). Более сложные диалоговые окна создаются на основе форм.
Проиллюстрируем создание диалоговых окон на примере графического пользовательского интерфейса для бюро путешествий.
Создание модального диалога
Программа 5:
1. Скомпонуйте и запустите стартовую систему приложения AdminForm. На форме расположены кнопки Add и Exit и 4 элемента Label для отображения информации. По щелчку на кнопке Add отображается пустая форма AddHotelDialog. cs. Это обычная форма. Ее размер можно изменять, у нее есть системное меню, кнопки свертывания Minimize и развертывания Maximize.

Рисунок 3.10 - Окно приложения AdminForm
2. Откройте файл AddHotelDialog. cs в режиме Design (Конструктор). В окне Properties установите значение свойства FormBorderStyle равным FixedDialog.
3. Установите значение свойств ControlBox, MinimizeBox и MaximizeBox равным False. Сейчас можно скомпоновать и запустить приложение. Теперь размер диалогового окна будет фиксированным, у него не будет системного меню, а в правом верхнем углу окна не будет кнопки "X", с помощью которой можно закрыть окно.
4. Добавьте на форму текстовые поля TextBox и Label, содержащие информацию о гостинице. Кроме того, необходимо добавить кнопки ОК и Cancel.
5. Установите значения и имена элементов в соответствии с табл. 3.7.

Рисунок 3.11 - Диалоговое окно для изменения информации о гостинице
6. Измените размер формы так, чтобы на ней помещались все добавленные управляющие элементы.
7. Установите значение свойства DialogResult кнопки ОК равным ОК. Точно так же установите значение этого свойства кнопки Cancel равным Cancel. Сохраните изменения, сделанные в файле AddHotelDialog. cs.
8. В файле AdminForm. cs временно добавьте к обработчику cmdAdd_Click код, который отвечает за отображение окна диалога. Обратите внимание на то, что диалоговое окно отображается с помощью метода ShowDialog, а не метода Show, который используется для обычных форм.
private void cmdAdd_Click (object sender, EventArgs e) {
AddHotelDialog dialog = new AddHotelDialog();
Dialog. ShowDialog();
}
Таблица 3.7 - Значения свойств текстовых полей и кнопок диалога AddHotelDialog. cs
Имя (Name) | Текст |
txtCity | (не заполнено) |
txtHotelName | (не заполнено) |
txtlMumberRooms | (не заполнено) |
txtRate | (не заполнено) |
cmdOk | ОК |
cmdCancel | Cancel |
9. Скомпонуйте и запустите пример. Теперь диалоговое окно уже можно открыть с помощью кнопки Add, а закрыть— с помощью любой из кнопок ОК или Cancel. Можно проверить, что диалоговое окно является модальным, пощелкав мышью где-нибудь еще в приложении.
10. Закрыть приложение можно кнопкой Exit, добавив обработчик события:
private void cmdExit_Click(object sender, EventArgs e) {
if(MessageBox. Show("Do you want to close", "Warning", MessageBoxButtons. YesNo,
MessageBoxIcon. Question) == System. Windows. Forms. DialogResult. Yes) {
Application. Exit();
}
Передача информации между диалогом и родительской формой
Для этих целей в классах. NET Framework нет встроенного механизма, но все-таки существует некоторый шаблон проектирования, которому можно следовать. В классе диалога для каждого сообщения, которое может передаваться между родительской формой и диалогом, нужно определить некоторое свойство.
В нашем примере мы сделаем свойства City, HotelName, Rate (Стоимость) и NumberRooms — доступными для чтения и записи.
1. Для того чтобы реализовать указанные свойства, добавьте к классу AddHotelDialog в файле AddHotelDialog. cs приведенный ниже код.
public String City {
get { return txtCity. Text; }
set { txtCity. Text = value; }
}
public String HotelName {
get { return (txtHotelName. Text); }
set { txtHotelName. Text = value; }
}
public int Rooms {
get { return Convert. ToInt32(txtNumberRooms. Text); }
set { txtNumberRooms. Text = value. ToString(); }
}
public double Rate {
get { return Convert. ToDouble(txtRate. Text); }
set { txtRate. Text = value. ToString(); }
}
private void cmdOk_Click(object sender, EventArgs e)
{
Close();
}
2. Теперь, чтобы использовать эти свойства перед закрытием диалогового окна с помощью кнопки ОК, добавьте код в главную форму AdminForm. cs.
private void button1_Click(object sender, EventArgs e) {
AddHotelDialog dlg = new AddHotelDialog();
dlg. ShowDialog();
if (dlg. HotelName!= "") {
label1.Text = dlg. City;
label2.Text = dlg. HotelName;
label3.Text = dlg. Rooms. ToString();
label4.Text = dlg. Rate. ToString();
}
else {
MessageBox. Show("Введите данные", "Hotel Broker Administration",
MessageBoxButtons. OK, MessageBoxIcon. Exclamation);
return;
}
}
2. Скомпонуйте и испытайте программу.
Создание панели инструментов
Кнопки панели инструментов обеспечивают пользователям более легкий доступ к возможностям, которые определены в меню. В пространстве имен System. Windows. Forms предусмотрены типы, которые облегчают работу с панелями инструментов. Первый класс, который используется для создания панелей инструментов, — это класс ToolStrip.
Для добавления объекта панель инструментов:
- Перетащить объект ToolStrip с панели Toolbox. Растянуть на форме, расположив в нужной части окна. По умолчанию будет сформировано метка на панели для выбора типа объектов панели инструментов. Выберите объект Button. Появится заготовка для кнопки с изображением, чтобы добавить новое изображение на кнопку, щелкнуть по созданной кнопке правой клавишей мыши и выбрать Set Image. В появившемся окне нажать кнопку Import. В диалоговом окне выбрать путь к рисунку для загрузки в качестве изображения кнопки.
Таблица 3.8 - Свойства класса ToolStrip
Свойство | Назначение |
BorderStyle | Определяет стиль рамки вокруг панели инструментов. Используются значения из перечисления BorderStyle |
Buttons | Для работы с набором кнопок на панели инструментов |
ButtonSize | Определяет размер кнопок на панели инструментов |
ImageList | Возвращает элемент управления ImageList, в котором хранятся изображения, используемые на панели инструментов |
Для добавления обработчика события ButtonClick для кнопок объекта toolStrip1, необходимо:
- щелкнуть два раза указателем мыши по кнопке; в открывшемся окне просмотра кода ввести необходимый программный код.
Список элементов ListBox
Добавьте в проект новый класс, описывающий объект гостиница.
class Hotel {
public Hotel(String city, String name, int r, double m) {
City = city; HotelName = name;
Rooms = r; Rate = m;
}
public String City, HotelName;
public int Rooms;
public double Rate;
}
При запуске программы AdminForm в процессе инициализации метод Form1_Load осуществляет начальную загрузку списка элементов hotellist, — в него загружается список гостиниц.
public partial class Form1 : Form {
System. Collections. ArrayList list = new System. Collections. ArrayList(); // список гостиниц
public Form1() {
InitializeComponent();
}
…
private void Form1_Load(object sender, EventArgs e) {
Hotel ob1=new Hotel("Москва","Россия",200,1500);
list. Add(ob1);
Hotel ob2=new Hotel("Москва","Прага",200,3000);
list. Add(ob2);
Hotel ob3=new Hotel("Новосибирск","Объ",150,1500);
list. Add(ob3);
Hotel ob4=new Hotel("Новосибирск","Тратата",300,1200);
list. Add(ob4);
Hotel ob5=new Hotel("Москва","Измайловская",300,3500);
list. Add(ob5);
Hotel ob6=new Hotel("Тирасполь","Дружба",200,1000);
list. Add(ob6);
hotellist. Items. Clear();
if (list == null) { return; }
foreach(Hotel hotel in list) { // строка для записи в элемент ListBox hotellist
String city = hotel. City. Trim();
String name = hotel. HotelName. Trim();
String rooms = hotel. Rooms. ToString(); // гостиница
String rate = hotel. Rate. ToString();
String str = city + "," + name + "," + rooms + "," + rate;
hotellist. Items. Add(str); // Добавить элементы
}
}
}
Метод Form1_Load отображает в списке элементов hotellist список объектов, в которых хранится информация о гостиницах.
Управляющий элемент ListBox содержит свойство Items (Элементы), которое поддерживает коллекцию объектных ссылок. Сначала мы вызываем метод Items. Clear(), чтобы очистить список элементов от тех элементов, которые отображаются в нем в момент вызова метода. Потом с помощью цикла перебираем гостиницы в списке массивов и создаем строку, которая состоит из полей структуры гостиницы, разделенных запятыми. Чтобы добавить эту строку в список элементов, вызывается метод Items. Add().
Чтобы в списке элементов выбрать какой-нибудь элемент, нужно щелкнуть на нем. Выбор элемента вызовет событие SelectedIndexChanged. Доступ к выбранному элементу можно получить с помощью свойств SelectedIndex и SelectedItem. Если никакой элемент не выбран, значение SelectedItem будет равно -1. Ниже приведен код обработчика события SelectedIndexChanged.
private void hotellist_SelectedIndexChanged(object sender, EventArgs e) {
if (hotellist. SelectedIndex!= -1) {
String selected = hotellist. SelectedItem. ToString(); // выбранная строка
String[] fields;
fields = selected.Split(','); // поля = выбранное разбить;
label1.Text = fields[0]; // Город = полe [0]; и т. д.
label2.Text = fields[1];
label3.Text = fields[2];
label4.Text = fields[3];
}
else {
label1.Text = "";
}
}
Поскольку в списке элементов элементы хранятся в виде объектных ссылок, мы выполняем приведение типа выбранного элемента к типу String. Для того чтобы выделить значения полей, разделенные запятыми, используется метод String. Split, затем значения сохраняются в массиве строк fields. Из массива эти значения переносятся в элементы label на форме для отображения.
Добавление объектов, вводимых на дополнительной форме AddHotelDialog, в коллекцию и элемент hotellist осуществляется в следующем коде:
private void button1_Click(object sender, EventArgs e) {
AddHotelDialog dlg = new AddHotelDialog();
dlg. ShowDialog();
if (dlg. HotelName!= "") {
label1.Text = dlg. HotelName;
label2.Text=dlg. City;
label3.Text=dlg. Rooms. ToString();
label4.Text=dlg. Rate. ToString();
String s=dlg. City+"," +dlg. HotelName+"," +dlg. Rooms. ToString()+"," +dlg. Rate. ToString();
hotellist. Items. Add(s);
Hotel ob=new Hotel(dlg. City, dlg. HotelName, dlg. Rooms, dlg. Rate);
list. Add(ob);
}
else {
MessageBox. Show("Введите данные", "Hotel Broker Administration",
MessageBoxButtons. OK, MessageBoxIcon. Exclamation) ;
return;
}
}
Задания к лабораторной работе
1. Создать учебные приложения Программа2 – Программа 5 и разобрать принцип их работы. Поместите в отчет примеры работы программ, их код с комментариями.
2. Создать SDI-приложение с элементами ввода и отображения полей класса из задания к лабораторной работе 2. Для этого использовать различные элементы управления: текстовые поля, списки, независимые и радио - кнопки, а также панели и менеджеры компоновки.
3. Ввод новых данных осуществлять через дополнительную модальную форму.
4. При изменении данных запрашивать подтверждение через окно диалога. В случае неполных данных сообщать об ошибке.
5. Объекты сохранять в коллекции.
6. Реализовать просмотр всей коллекции объектов через список. Для редактирования выбранного объекта создать дополнительную форму модального диалога.
7. Добавить на форму меню, позволяющее работать с пунктами: добавить, просмотреть, удалить, редактировать, справка.
8. Дублировать основные операции панелью инструментов.
Вопросы к защите лабораторной работы
Что такое форма и ее назначение? Что такое элементы управления? На какие группы они делятся? Как установить элемент управления на форму и проинициализировать его? Что такое событие? Как в. Net реализуются события? Что такое обработчик события? Что такое делегат? Как задаются обработчики событий для элементов управления? Как происходит подключение к прослушиванию события? Как создать собственные события и их обработчики? Как создать верхнее меню? Как добавить несколько пунктов меню? Как установить определенному пункту меню сочетание клавиш? Как создать панель инструментов? Как добавить несколько кнопок на панель инструментов? Как разместить на кнопке изображение? Как добавить новую форму в приложение? Как организовать переход к добавленной форме? Что такое модальная и немодальная форма? Как они вызываются? Как добавить новый класс в проект? Какая компонента позволяет отображать список на форме? Какие компоненты позволяют создать набор радио-кнопок на форме? Какая компонента позволяет задавать на форме флажок?Лабораторная работа 4
Тема: Создание MDI-приложений. Сериализация объектов.
Использование стандартных диалогов для сохранения и
загрузки данных программы
Цель работы:
- Изучить особенности MDI приложений и способы их создания в Visual Studio .Net.
- Сохранение данных в файл и загрузки из файла.
- Освоить механизм сериализации и десериализации объектов.
- Освоить применение стандартных диалогов сохранения и загрузки данных в приложение.
Теоретические сведения
Операции ввода/вывода данных в. NЕТ
Данные могут рассматриваться как поток байтов, символов или объектов. Чтение и запись объектов называются соответственно преобразованием из последовательной формы в параллельную и преобразованием в последовательную форму (сериализацией). Сериализация объектов может осуществляться в двух форматах: бинарном и XML-формате.
В пространстве имен System. IO есть несколько классов для чтения и записи, позволяющих использовать различные устройства хранения, если только данные можно трактовать как байты или символы.
Пространство имен *****ntime. Serialization используется для сериализации в общей системе типов (Common Type System). Пространство имен System. Xml. Serialization используется для сериализации XML-документов.
Потоковые классы
Stream — абстрактный класс, который является базовым для чтения и записи байтов в некоторое хранилище данных. Этот класс поддерживает синхронные и асинхронные чтение и запись. Класс Stream содержит типичные и вполне ожидаемые от такого класса методы: Read , Write, Seek, Flush и Close.
Класс FileStream, который является производным от класса Stream, предоставляет операции чтения и записи последовательности байтов в файл. Конструктор FileStream создает экземпляр потока. Перегруженные методы класса Stream осуществляют чтение и запись в файл. У класса Stream есть и другие производные классы: MemoryStream, BufferedStream и NetworkStream (в . Sockets).
// Программа 1. Запись и чтение 10 байт в/из файл. Пример нужно выполнить дважды. Первый раз программа создаст файл и запишет в него числа, а во второй раз прочитает и распечатает часть файла
using System. IO;
void Main() {
byte [] data = new byte [10];
FileStream fs = new FileStream( "FileStreamTest. txt", FileMode. OpenOrCreate);
if (fs. Length == 0) {
Console. WriteLine("Writing Data...");
for (short i = 0; i < 10; i++)
data[i] = (byte)i;
fs. Write(data, 0, 10); // Запись данных
}
else {
fs. Seek(-5, SeekOrigin. End); // Ищем конец
int count = fs. Read(data, 0, 10); // Чтение данных
for (int i = 0; i < count; i++) {
Console. WriteLine(data[i]);
}
}
fs. Close();
}
Встроенные типы данных и потоки
Классы, производные от Stream, целесообразно использовать тогда, когда нужно читать или писать байты данных блоками. Если необходимо прочитать в поток или записать из потока простой тип, такой как Boolean, String или Int32, следует использовать классы BinaryReader и BinaryWriter. Нужно создать соответствующий поток (напимер, FileStream) и передать его в качестве параметра в конструктор BinaryReader или BinaryWriter. Потом можно использовать один из перегруженных методов Read или Write для чтения данных из потока или записи данных в поток.
// Программа 2. Запись и чтение 10 чисел в/из файл. Пример нужно выполнить дважды. Сначала файл создается и в него записываются данные. Во второй раз данные читаются из файла.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 |


