- •Предисловие
- •1 Среда визуального программирования visual studio.Net
- •1.1 Введение в объектно - ориентированное программирование
- •1.2 Понятие о событийном управлении Windows
- •1.3 Основные окна среды Visual Studio.Net
- •1.4 Основные структурные элементы разработки проекта c#
- •1.5 Пример первой учебной программы
- •2.1 Технология визуального проектирования форм
- •1.6 Вопросы для самопроверки
- •2 Элементы управления
- •2.2 Элементы управления панели Toolbox
- •2.3 Пример использования элементов управления
- •2.4 Вопросы для самопроверки
- •3 Графический интерфейс языка c#
- •3.1 Пространство имен System.Drawing
- •3.2 Класс Graphics
- •3.3 Пример программной реализации
- •3.4 Вопросы для самопроверки
- •4 Использование меню в приложении
- •4.1 Меню программы
- •4.2 Создание инструментальной панели приложения
- •4.3.Вопросы для самопроверки
- •5 Использование диалоговых меню
- •5.1 Обработчики событий для работы с матрицей
- •5.2 Обработчик событий для открытия файла
- •5.3 Обработчик событий для записи в файл
- •5.4 Обработчик событий для работы с текстом
- •5.5 Вопросы для самопроверки
- •6 Многооконные приложения
- •6.1 Создание «кнопочной» главной формы
- •6.2 Добавление новых форм приложения
- •6.3 Обработчики событий главной формы
- •6.4 Табличная форма представления и редактирования значений
- •6.5 Графическая форма представления прямоугольников
- •6.6 Вопросы для самопроверки
- •7. Понятие класса
- •7.1 Понятие класса
- •7.2 Состав класса
- •7.3 Методы класса
- •7.4 Структура объекта
- •7.5 Пример учебной программы
- •7.6 Доступ к полям
- •7.7 Вопросы для самопроверки
- •1 Понятие класса?
- •8 Элементы классов
- •8.1 Конструкторы
- •8.2 Деструкторы
- •8.3 Свойства
- •8.4 Параметр по ссылке this
- •8.5 События класса
- •8.6 Перегрузка операций класса
- •8.7 Вопросы для самопроверки
- •9 Принципы ооп
- •9.1 Понятие инкапсуляции
- •9.2 Понятие наследования
- •9.3 Вопросы для самопроверки
- •10 Принцип полиморфизма
- •10.1 Понятие полиморфизма
- •10.2 Пример статического наследования методов
- •10.3 Пример динамического наследования методов
- •10.4 Вопросы для самопроверки
- •11 Использование интерфейсов
- •11.1 Понятие интерфейса
- •11.2 Синтаксис интерфейса
- •11.3 Использование стандартного интерфейса iEnumerable
- •11.4 Вопросы для самопроверки
- •12 Композиция и коллекция классов
- •12.1 Понятие композиции и коллекции класса
- •12.2 Пример использования композиции и коллекции класса
- •12.3 Некоторые коллекции Framework
- •12.4 Коллекция ArrayList
- •12.5 Вопросы для самопроверки
- •13 Делегаты
- •13.1 Понятие делегата
- •13.2 Описание делегата
- •13.3 Пример использования делегата
- •13.4 Совместимость делегатов
- •13.5 Методы базовых классов делегатов
- •13.6 Вопросы для самопроверки
- •14 События
- •14.1 Понятие события
- •14.2 Некоторые часто используемые события среды Visual Studio.Net
- •14.3 Пример использования стандартных событий классов
- •14.4 Нестандартные события классов
- •14.5 Вопросы для самопроверки
- •Приложение а Ответы на вопросы для самопроверки
- •1 Понятие класса?
- •Предметный указатель
- •Список литературы
14.3 Пример использования стандартных событий классов
Рассмотрим чисто учебную программу, использующую некоторые «стандартные» события классов.
В программе использован обработчик события одинарного нажатия левой кнопки мышки на форме, при этом из всех запусков обработчика программа реагирует только на нажатие кнопки мышки, когда ее курсор находится в левом верхнем углу формы:
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if ((e.X < 20 && e.X > 0 && e.Y < 20 & e.Y > 0) && p == 0)
Этот прием часто используется программистами для формирования реакции программы на «клик» мышки в определенных местах экрана, например, карты города или фото группы студентов – легко написать необходимые комментарии при «попадании» мышки в определенный участок формы.
Обработчик события перемещения мышки по форме (дополнительное условие p==1) позволяет записать положения курсора мышки в массив 100 точек.
Просмотр массива в графическом режиме осуществляется с помощью обработчика двойного нажатия левой кнопки мышки.
С помощью обработчика – нажатия клавиши в окне редактора осуществляется начальная установка программы.
Исходный код программы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public int p,i,j;
int[,] tk = new int[100, 2];
public Form1()
{
InitializeComponent();
textBox1.Text = "";
p = 0; i = 0; j = 0;
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if ((e.X < 20 && e.X > 0 && e.Y < 20 & e.Y > 0) && p == 0)
{
textBox1.AppendText("Вы кликнули мышкой в верхнем левом углу
\r\n");
p++;
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (p == 1)
if (i < 100) { tk[i, 0] = e.X; tk[i, 1] = e.Y; i++; }
else
{
textBox1.AppendText("Заполнение массива закончено \r\n");
p++;
}
}
private void Form1_MouseDoubleClick(object sender,
MouseEventArgs e)
{
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Pen myPen = new Pen(Color.Red, 2);
Graphics g = e.Graphics;
for (int n = 0; n < 100; n++)
g.DrawEllipse(myPen, tk[n, 0], tk[n, 1], 2, 2);
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
p = 0; i = 0;
}
}
}
Работа программы представлена на рисунках 14.1 и 14.2.
Рисунок 14.1 – Запуск программы и заполнение массива
Рисунок 14.2 – Просмотр массива, сброс программы и ее повторный запуск
14.4 Нестандартные события классов
Помимо стандартных событий – как реакция программы на действия пользователя, события могут формироваться и внутри Windows-приложений с помощью специальных методов.
События, формируемые самим приложением, позволяют организовать динамическую (во время работы приложения) связь между различными объектами, например, продажа некоторого товара в магазине должна автоматически изменять содержимое многих документов – общий доход от продажи, документ по продаже конкретного товара, наличие этого товара на складе и рекомендации по пополнению товара и т.д.
Таким образом, возникает необходимость информирования некоторых объектов приложения о событии, происшедшем в объекте источнике сообщения.
Механизм взаимодействия источника события с его получателями (иногда их называют клиентами) основан на использовании делегата. В приложении объявляется экземпляр делегата, которому соответствуют стандартные методы обработчиков событий.
Далее необходимо определить класс, являющегося источником события (sender), и в нем метод описывающий событие, и метод инициирующий событие.
В процессе работы приложения объекты обработчиков событий (клиентов), которые хотят получать уведомление об изменении состояния источника, необходимо включить в список методов, обрабатываемых делегатом. Этот процесс называется регистрацией обработчиков событий.
При появлении события все зарегистрированные методы поочередно, с помощью делегата, вызываются на выполнение.
Работу механизма взаимодействия источника события с его получателями рассмотрим на следующем учебном примере.
Задача 14.1 Сформировать массив из 10 случайных целых чисел в диапазоне от минус 5 до 10. Предположим, что отрицательные значения недопустимы и для них мы будем формировать события. Необходимо напечатать массив, вычислить его сумму и нарисовать график изменения значений.
Если значение массива число отрицательное, то необходимо формировать событие, на которое должны реагировать два обработчика. Первый должен поменять знак у отрицательного числа, а второй должен изменить сумму чисел в соответствии с новым значением элемента массива.
Для наглядности предусмотрим вывод графика измененных значений массива.
Итак, для создания и использования события нужно, прежде всего, объявить делегата, с помощью которого реализуется связь между источником события и его клиентами.
В библиотеке .NET описано огромное количество стандартных делегатов, предназначенных для реализации механизма обработки событий. Большинство этих классов оформлено по одним и тем же правилам:
– имя делегата включает название события и заканчивается суффиксом EventHandler;
– делегат имеет два формальных параметра. Первый параметр задает источник события и имеет тип object. Второй параметр задает аргументы события и имеет тип EventArgs или производный от него.
Рекомендуется при объявлении делегата придерживаться этих правил, например:
public delegate void ZamenaEventHandler(object sender, ZamenaEventArgs arge);
В этом примере мы создаем делегата для обработки события Zamena (замена), связанного с изменениями, которые должны произойти в объекте - источнике события. В описании делегата указаны два аргумента: объект sender, создавший событие, и объект arge типа ZamenaEventArgs, содержащий связанные с событием параметры.
Поскольку нам понадобится передавать только индекс массива, то лучше определить класс ZamenaEventArgs следующим образом:
public class ZamenaEventArgs : EventArgs
{
public int item;
}
Следующим этапом в реализации механизма обработки событий является определение класса, являющегося источником события (sender), и в нем метода, инициирующего событие. Этот метод имеет специальный формат записи и во многом определяется форматом записи соответствующего ему делегата – после определения спецификатора доступа к методу (обычно это public) записывается служебное слово event, после которого указывается тип, заданный делегатом, и имя события. Например:
public event ZamenaEventHandler Zamena;
Полное описание класса выглядит следующим образом:
class sobit
{
public event ZamenaEventHandler Zamena;
public void prov(ZamenaEventArgs arge)
{
if (masi[arge.item] < 0)
{
Zamena(this,arge);
}
}
}
На следующем этапе реализации механизма обработки событий необходимо определиться с классами получателями событий. Особенность этих классов является то, что в них должны находиться методы обработчиков событий, формат записи которых должен совпадать с форматом записи соответствующего делегата. Например:
class zam1
{
public void OnZam1(object sender, ZamenaEventArgs e)
{
masi[e.item] = masi[e.item] * (-1);
}
}
Регистрацию обработчиков событий необходимо производить для объектов (не классов) классов обработчиков событий. Это возможно только во время работы приложения – объекты (переменные) создаются во время работы приложения, например, во время инициализации формы:
public Form1()
{
InitializeComponent();
zam1 z1 = new zam1();
zam2 z2 = new zam2();
so.Zamena += z1.OnZam1;
so.Zamena += z2.OnZam2;
}
Для демонстрации работы приложения использованы две кнопки – «Формирование массива» и «Проверка массива и запуск событий».
Исходный код программы имеет следующий вид:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public delegate void ZamenaEventHandler(object sender,
ZamenaEventArgs arge);
public int cob=0;
public static int sum = 0;
public static int[] masi = new int[10];
public class ZamenaEventArgs : EventArgs
{
public int item;
}
class sobit
{
public event ZamenaEventHandler Zamena;
public void prov(ZamenaEventArgs arge)
{
if (masi[arge.item] < 0)
{
Zamena(this,arge);
}
}
}
sobit so = new sobit();
class zam1
{
public void OnZam1(object sender, ZamenaEventArgs e)
{
masi[e.item] = masi[e.item] * (-1);
}
}
class zam2
{
public void OnZam2(object sender, ZamenaEventArgs e)
{
sum = sum + 2 * masi[e.item];
}
}
public Form1()
{
InitializeComponent();
zam1 z1 = new zam1();
zam2 z2 = new zam2();
so.Zamena += z1.OnZam1;
so.Zamena += z2.OnZam2;
}
private void button1_Click(object sender, EventArgs e)
{
cob = 0; sum = 0;
string ss="";
Random rnd = new Random();
for(int i=0;i<10;i++)
{
masi[i] = rnd.Next() % 15 - 5;
sum = sum + masi[i];
ss = ss + masi[i].ToString() + " ";
}
textBox1.AppendText("Исходный массив: \r\n");
textBox1.AppendText(ss + "\r\n");
textBox1.AppendText("Сумма элементов="+sum.ToString()+"\r\n");
this.Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
cob=1;
ZamenaEventArgs zz = new ZamenaEventArgs();
for (int i = 0; i < 10; i++)
{
zz.item = i;
so.prov(zz);
}
textBox1.AppendText("Сумма элементов="+sum.ToString()+"\r\n");
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawLine(new Pen(Brushes.Blue, 2), 10, 200, 250, 200);
Pen myPen = new Pen(Color.Red, 2);
if (cob == 0)
{
for (int i = 1; i < 10; i++)
g.DrawLine(myPen,i*10,(200-masi[i-1]*10),(i+1)*10,(200-masi[i]*10));
}
if (cob == 1)
{
for (int i = 1; i < 10; i++)
g.DrawLine(myPen,i*10+110,(200-masi[i-1]*10),(i+1)*10+110, (200-masi[i]*10));
}
}
}
}
Работа программы представлена на рисунке 14.3.
Рисунок 14.3 Работа приложения с обработкой событий
