Нестандартные события классов

 

Помимо стандартных событий – как реакция программы на действия пользователя, события могут формироваться и внутри Windows-приложений с помощью специальных методов.

События, формируемые самим приложением, позволяют организовать динамическую (во время работы приложения) связь между различными объектами, например, продажа некоторого товара в магазине должно автоматически изменять содержимое многих документов – общий доход от продажи, документ по продаже конкретного товара, наличие этого товара на складе и рекомендации по пополнению товара и т.д.

Таким образом, возникает необходимость информирования некоторых объектов приложения о событии, происшедшем в объекте источнике сообщения.

Механизм взаимодействия источника события с его получателями (иногда их называют клиентами) основан на использовании делегата. В приложении объявляется экземпляр делегата, которому соответствуют стандартные методы обработчиков событий.

Далее необходимо определить класс, являющегося источником события (sender), и в нем метод описывающий событие, и метод инициирующий событие.

В процессе работы приложения объекты обработчиков событий (клиентов), которые хотят получать уведомление об изменении состояния источника, необходимо включить в список методов, обрабатываемых делегатом. Этот процесс называется регистрацией обработчиков событий..

При появлении события все зарегистрированные методы поочередно, с помощью делегата, вызываются на выполнение.

Работу механизма взаимодействия источника события с его получателями рассмотрим на следующем учебном примере.

Задача 14.1 Сформировать массив из 10 случайных целых чисел в диапазоне от минус 5 до 10. Предположим, что отрицательные значения недопустимы и для них мы будем формировать события.Необходимо напечатать массив, вычислить его сумму и нарисовать график изменения значений.

Если значение массива число отрицательное, то необходимо формировать событие, не которое должны реагировать два обработчика. Первый должен поменять знак у отрицательного числа, а второй должен изменить сумму чисел в соответствии с новым значением элемента массива.

Для наглядности предусмотреть вывод графика измененных значений массива.

Итак, для создания и использования события нужно, прежде всего, объявить делегата, с помощью которого реализуется связь между источником события и его клиентами.

В библиотеке .NET описано огромное количество стандартных делегатов, предназначенных для реализации механизма обработки событий. Большинство этих классов оформлено по одним и тем же правилам:

– имя делегата включает название события и заканчивается суффиксом EventHandler;

– делегат имеет два формальных параметра. Первый параметр задает источник события и имеет тип object. Второй параметр задает аргументы события и имеет тип EventArgs или производный от него.

Рекомендуется при объявлении делегата придерживаться этих правил, например:

public delegate voidZamenaEventHandler(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)

{

//if(masi[e.item]>0)//Проверка очередности обработки событий

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 Работа приложения с обработкой событий

 

 








Дата добавления: 2018-11-25; просмотров: 233;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.025 сек.