Кластардың стандартты емес оқиғалары
Пайдаланушы әрекеттеріне қосымшаның жауап қайтаруы ретіндегі стандартты оқиғалармен қатар Windows-қосымшаның ішінде арнайы әдістер арқылы оқиғалар құрылуы мүмкін.
Қосымшаның өзі құратын оқиғалар түрлі объекттер арасында динамикалық байланысты ұйымдастыруға мүмкіндік береді, мысалы, дүкенде белгілі бір тауардың сатылуы көптеген құжаттардың ішіндегісін
автоматты түрде өзгертуі ерек (Сатудан түсетін жалпы кіріс, нақты тауарды сату бойынша құжат, осы тауардың қоймада болуы, т.б.).
Сонымен, хабарды шығару көзінен пайда болған оқиға туралы қосымшаның кейбір объекттеріне хабар беру қажеттілігі туындайды.
Оқиға көзі және оқиғану алушы (кейде оларды клиент деп атайды) арасындағы өзара әрекеттерінің механизмі делегатты пайдалануға негізделген.
Қосымшада делегат данасы жарияланады, ол оқиғалар өңдеуіштерінің стандартты әдістеріне сәйкес болып келеді.
Одан кейін оқиға көзі (sender) болып келетін класты анықтау керек және сол жерде оқиғаны сипаттайтын әдісті, оқиғаны іске асыратын (инициирующий) әдісті анықтау керек.
Қосымшаның жұмысы барысында оқиғалар өңдеуіштерінің объекттерін (клиенттері) делегат арқылы өңделетін әдістер тізіміне қосу керек. Осы процесс оқиғалар өңдеуіштерін тіркеу деп аталады.
Оқиға пайда болғанда барлық тіркелген әдістер делегат арқылы кезек бойынша орындалуға шақырылады.
Оқиға көзі мен пайдаланушы арасындағы өзара әрекеттесу механизмінің жұмысы келесі мысалда қарастырылған.
14.1-есеп. Минус 5-тен 10-ға дейінгі аралықта болатын 10 кездейсоқ бүтін сандардан тұратын массивті құру керек. Теріс сандарды қолдануға болмайды деп жорамалдайық және олар үшін оқиғаларды құрайық. массивті экранға басып шығару, оның қосындысын және мәндердің өзгеру графигінің суретін салу керек.
Егер массив мәні теріс сан болатын болса, онда оқиғаны құру керек және осы оқиғаға екі өңдеуіш жауап беруі керек.
Біріншісі теріс санның таңбасын ауыстыру керек, екіншісі – массив элементтерінің жаңа мәндеріне сәйкес сандардың қосындысын өзгерту керек.
Көрнекілік үшін массивтің өзгерген мәндерінің графигі шығарылсын.
Сонымен, оқиғаны құру және қолдану үшін алдымен делегатты жариялау керек (делегат арқылы клиент пен оқиға көзі арасында байланыс орнайды).
.NET кітапханасында стандартты делегаттардың көптеген түрі сипатталған, олар оқиғаларды өңдеу механизмін жүзеге асыру үшін арналған. Осы кластардың көпшілігі бір ереже бойынша жазылған:
делегат атауы оқиға атауымен басталып EventHandler жұрнағымен аяқталады;
делегаттың екі формалды параметрі бар. Бірінші параметр оқиға көзін анықтайды және object типінде болады. Екінші параметр оқиға аргументін анықтайды және EventArgs типінде немесе одан туындайтын типте болады.
Делегатты жариялағанда осы ережелерді ұстанған жөн, мысалы:
public delegate void ZamenaEventHandler(object sender, ZamenaEventArgs arge);
Осы мысалда біз Zamena оқиғасын өңдеу үшін делегатты құрамыз, оқиға объектте – оқиға көзінде пайда болатын өзгерістермен байланысты. Делегат сипаттамасында екі аргумент көрсетілген: оқиғаны туындатқан sender объекті және оқиғаға байланысты параметрлері бар ZamenaEventArgs типіндегі arge объекті.
Бізге массив индексін ғана беру керек болғандықтан, 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.Drawing;
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-суретте көрсетілген.
14.3-сурет – Оқиғаларды өңдеу бойынша қосымша жұмысы
Өзін-өзі тексеру сұрақтары
Оқиға ұғымы.
Пайдаланушы әрекеттеріне арналған, басқару элементтерінің оқиғалар өңдеуіштерінің дайындамалары қай жерде орналасқан?
Кластың оқиғалары әдетте қалай аталады?
Формадағы батырманы екі рет шерткенде не орындалады?
Барлық хабарлама өңдеуіштерінің бірінші формалды параметрі нені анықтайды?
Хабарлама өңдеуішінің екінші формалды параметрі нені анықтайды? 7 Формада орналасқан басқару элементтерінің оқиғалары қай жерде
көрсетіледі?
Кластың барлық оқиғаларын қалай біріктіруге болады?
Форманың көпадресті делегатында оқиғаларды қосу қай жерде орындалады?
Форманың көпадресті делегаты қай жерде жарияланады?
Достарыңызбен бөлісу: |