1
00:00.110 --> 00:00.890
خوش برگشتید.

2
00:00.890 --> 00:05.930
تو این ویدیو قراره از **generic delegate**، یعنی **EventHandler<TEventArgs>** استفاده کنیم.

3
00:05.930 --> 00:08.900
خب، کلمات زیادی اینجا هست، درسته؟

4
00:08.900 --> 00:10.490
ما می‌دونیم **delegate** چیه.

5
00:10.490 --> 00:16.580
و هنوز نمی‌دونیم **EventHandler** چیه، و نه **TEventArgs** چی هستن.

6
00:16.580 --> 00:23.630
قبلاً کلمه **generic** رو شنیدیم، اما بیایید ببینیم چرا این موضوع اهمیت داره.

7
00:23.630 --> 00:28.910
پس اول از همه، چرا **Event Args** مهم هستن و اصلاً چی هستن؟

8
00:28.910 --> 00:31.350
**Event Args** همون **Event Arguments** (آرگومان‌های رویداد) هستن.

9
00:31.350 --> 00:38.220
خب، اساساً وقتی یک **event** **raise** (راه اندازی) می‌شه، شما گاهی اوقات می‌خواید اطلاعاتی درباره اون **event** ارسال کنید.

10
00:38.220 --> 00:44.370
اول از همه، اون شخص یا **object**ای که **event** رو **raise** کرده کی بوده.

11
00:44.370 --> 00:54.250
و دوماً، یک سری اطلاعات اضافی، یک سری **argument** (پارامتر) اضافی که می‌خواید به هر کسی که داره **event** رو مصرف می‌کنه، ارسال کنید.

12
00:54.250 --> 01:06.640
یعنی به **subscriber**ها، چون **subscriber**ها، شاید به این اطلاعات نیاز داشته باشن، اطلاعاتی که مربوط به اون **event** هست و می‌خوان نمایشش بدن، یا بعداً باهاش کار کنن یا چیزی شبیه اون.

13
01:06.640 --> 01:13.360
و برای دستیابی به این موضوع، باید از **Event Arguments** استفاده کنید.

14
01:13.360 --> 01:15.880
و معمولاً چیزی که خواهید دید، این موارد هستن:

15
01:15.880 --> 01:23.290
پس، این **delegate** **generic** به اسم **EventHandler** وجود داره. بیایید یک **public event** ایجاد کنیم و این یکی **EventHandler** خواهد بود.

16
01:23.290 --> 01:24.370
این یکی اینجا.

17
01:24.370 --> 01:25.570
در واقع، این یکی هست.

18
01:25.570 --> 01:27.040
این **generic** (عمومی) هست.

19
01:27.040 --> 01:33.160
پس اگه موس رو روش ببرید، می‌بینید که می‌گه **EventHandler<TEventArgs> object sender TEventArgs**. اوکی.

20
01:33.160 --> 01:34.510
پس بیایید این رو بررسی کنیم.

21
01:34.510 --> 01:38.800
پس تو این **EventHandler** می‌تونیم ببینیم چی می‌گه.

22
01:38.800 --> 01:41.080
پس این **EventHandler** یک **delegate** هست، درسته؟

23
01:41.080 --> 01:44.410
و می‌دونیم که برای آماده‌سازی **event**ها به **delegate**ها نیاز داریم.

24
01:44.410 --> 01:48.340
حالا این **EventHandler** همچنین دو تا **argument** داره.

25
01:48.340 --> 01:56.350
یکی از اونها **sender** (فرستنده) هست که از نوع **object** (قابل خالی بودن) هست. و اون یکی **EventArgs** هست.

26
01:56.350 --> 02:05.840
خب، **EventArgs** فقط **base class** (کلاس پایه) برای **class**هایی هست که داده‌های **event** رو شامل می‌شن، و یک مقدار برای استفاده در **event**هایی که شامل داده‌های **event** نیستن، فراهم می‌کنه.

27
02:05.840 --> 02:15.110
پس اگه می‌خواید **event** خودتون رو ایجاد کنید که بعداً داده هم به **subscriber**ها ارسال کنه، باید از **EventArgs** استفاده کنید.

28
02:15.140 --> 02:19.730
حالا نکته جالب اینه که می‌تونید از **EventArgs** **inherit** (ارث‌بری) کنید، چون اگه به **EventArgs** نگاه کنیم،

29
02:19.730 --> 02:24.230
می‌بینید که یک **public class** هست. **sealed** (مُهر و موم شده) نیست، پس می‌تونیم ازش ارث‌بری کنیم.

30
02:24.230 --> 02:31.410
و زیر **class**های **EventArgs** زیادی وجود داره. پس **class**هایی که از **class EventArgs** ارث می‌برن.

31
02:31.410 --> 02:34.680
خیلی ساده هست. همونطور که می‌بینید، **class EventArgs**،

32
02:34.680 --> 02:48.150
تنها کاری که انجام می‌ده اینه که یک **static read only EventArgs** داره، که یک **EventArgs** خالی هست. و کار زیادی انجام نمی‌ده، درسته؟ اما وقتی اون رو برای کارهای خودمون استفاده می‌کنیم، خیلی قدرتمند می‌شه.

33
02:48.180 --> 02:55.710
اوکی، بنابراین برای انجام این کار، بیایید با پیروی از این موضوع شروع کنیم.

34
02:55.710 --> 03:01.110
پس بیایید **class EventArgs** سفارشی خودمون رو ایجاد کنیم.

35
03:01.140 --> 03:03.120
بسیار خب، من اون رو اینجا بالا ایجاد می‌کنم.

36
03:03.120 --> 03:14.400
پس می‌گم **public class TemperatureChangedEventArgs**. پس این نام **EventArgs** اینجا مهمه.

37
03:14.400 --> 03:19.330
تا بدونیم این **class** داره از **EventArgs** **inherit** می‌کنه. این فقط یک روش معموله.

38
03:19.330 --> 03:30.550
اوکی، پس حالا **class** خودمون داره از این **class EventArgs** ارث می‌بره و اون رو **extend** (گسترش) می‌ده، به این معنی که داره **functionality** (عملکرد) بهش اضافه می‌کنه. درسته.

39
03:30.550 --> 03:39.820
پس اطلاعاتی که می‌خوام ذخیره کنم، قراره **temperature** (دما) باشه. و این یکی رو فقط می‌تونم **get**ش کنم. فقط می‌گم **set**ش نکن.

40
03:39.850 --> 03:59.780
اوکی. پس این **TemperatureEventArgs**، و اگه بخوام دما رو **set** کنم، فقط می‌تونم اون رو تو **constructor** انجام بدم. پس **public TemperatureChangedEventArgs** که همون **constructor** هست. و دارم دما رو پاس می‌دم. و اون دما رو تو **object** مربوط به **EventArgs** ذخیره می‌کنم. پس **EventArgs** حالا دما رو نگهداری می‌کنه، اوکی.

41
03:59.780 --> 04:10.610
پس هر وقت یک **object** ازش ایجاد می‌کنیم. پس این **constructor** و این **temperature property** هست. بسیار خب.

42
04:10.610 --> 04:18.980
پس حالا که این **EventArgs** رو داریم، گام بعدی اینه که اونها رو داخل **TemperatureMonitor**مون استفاده کنیم.

43
04:18.980 --> 04:32.160
چون می‌خوام هر وقت **event** رو **raise** می‌کنم، فقط یک **string message** پاس ندم. در واقع می‌خوام **TemperatureEventArgs** رو پاس بدم، هرچیزی که هست. پس حالا می‌تونم بگم:

44
04:32.160 --> 04:37.290
**TemperatureChangedEventArgs**. و یک اسم رایج **E** هست، اوکی.

45
04:37.290 --> 04:41.070
پس معمولاً وقتی از **EventArgs** استفاده می‌کنید، فقط **E** صداش می‌زنید.

46
04:41.160 --> 04:47.280
پس حالا وقتی دما رو تغییر می‌دم، قراره **E** رو پاس بدم.

47
04:47.370 --> 05:03.840
خب، این کار نمی‌کنه، چون متد ما اینجا، **event** **OnTemperatureChanged** ما، از **TemperatureChangeHandler** پیروی می‌کنه که انتظار یک **message** رو داره. انتظار یک نوع داده **EventArgs** رو نداره.

48
05:03.840 --> 05:12.060
پس حالا قراره این کل موضوع رو تغییر بدیم. دیگه از این **delegate** استفاده نمی‌کنیم، به خاطر همینه که دیگه نمی‌تونیم از این خط استفاده کنیم.

49
05:12.060 --> 05:26.890
به جای اون، قراره یک **generic EventHandler event** ایجاد کنیم. پس این یکی اینجا با **TemperatureChangedEventArgs**. و قراره اون رو **TemperatureChanged** صدا بزنیم. خب حالا این **EventHandler** باید قطعاً یک **event** باشه.

50
05:26.890 --> 05:29.290
پس نیاز داریم کلمه کلیدی **event** رو اضافه کنیم.

51
05:29.290 --> 05:42.860
و اگه بهش نگاه کنید، **EventHandler** فقط یک **delegate** هست، درسته؟ پس اساساً همون چیزیه که وقتی ما این **event** رو اینجا ایجاد کردیم، بود، که اون هم از **TemperatureChangeHandler** که یک **delegate** بود، پیروی می‌کرد.

52
05:42.890 --> 05:56.750
اوکی، پس حالا فقط اینه که **EventHandler** یک **delegate** از پیش تعریف شده هست که حالا قراره **TemperatureChangeEventArgs** رو بپذیره. پس می‌بینید که از نوع **generic EventArgs** هست.

53
05:56.750 --> 06:15.540
بنابراین معنی این **generic EventArgs** اینه که ما **generic** رو به طور کلی دیدیم، اما **generic EventArgs** فقط می‌گه هر نوع **EventArgs**ای. من اهمیتی نمی‌دم که **base class**، **EventArgs** هست یا هر چیزی که شما با ارث‌بری از **EventArgs** ساختید، که همون کاری هست که ما اینجا انجام دادیم.

54
06:15.540 --> 06:24.660
اوکی، ما از **EventArgs** ارث بردیم، و حالا می‌تونیم از **TemperatureChangedEventArgs** برای **EventHandler**مون استفاده کنیم. اوکی.

55
06:24.660 --> 06:31.920
و علاوه بر اون، چیزی که خواهید دید اینه که می‌گه: یک **sender** (فرستنده) به من بده و **EventArgs** رو به من بده.

56
06:31.920 --> 06:52.710
پس هر وقت حالا بخوایم از **EventHandler**مون که اینجا استفاده می‌کنیم، استفاده کنیم، حالا متدی که تو **event** **TemperatureChanged** **subscribe** می‌شه، باید **object sender** و همچنین **TemperatureChangeEventArgs** **E** رو پاس بده، که حالا به این معنیه که باید بریم پایین به **subscriber**مون.

57
06:52.710 --> 06:55.180
پس این در اینجا **subscriber** ماست.

58
06:55.870 --> 07:07.900
و این **TemperatureAlert** این متد **OnTemperatureChanged** رو داره که حالا نیاز داره **object sender** و همچنین **TemperatureChangeEventArgs E** رو بپذیره.

59
07:08.110 --> 07:24.220
و حالا اینجا می‌تونیم بگیم: **Alert**. و بذارید در واقع از **string manipulation** اینجا استفاده کنم. **Alert** و **temperature is** (دما هست) و بعد **E.** و **E** دما رو نگه می‌داره.

60
07:24.220 --> 07:29.410
پس حالا این **Event Arguments object** اطلاعاتی درباره دما نگهداری می‌کنه.

61
07:29.410 --> 07:41.740
چون اگه بهش نگاه کنیم، اگه به این **TemperatureChangedEventArgs** که ایجاد کردیم نگاه کنیم، این **property** به اسم **Temperature** رو داره. حالا بیایید اون رو گسترش بدیم و همچنین بگیم **sender** کی هست.

62
07:41.740 --> 07:49.370
پس **sender is** (فرستنده هست) و بعد **sender**. و من فقط می‌گم **sender**، اوکی. پس این **sender** درست اینجا، اوکی.

63
07:49.410 --> 07:57.560
حالا که این تغییر کرده، باید یک تغییر هم تو این قسمت اینجا ایجاد کنیم، اوکی.

64
07:57.560 --> 08:15.200
پس حالا **RaiseTemperatureChangedEvent**، من این رو **OnTemperatureChanged** صدا می‌زنم و کاری که انجام می‌ده اینه که از **event** **TemperatureChanged** ما استفاده می‌کنه و اون رو با **this** و **E** **invoke** می‌کنه. پس چه اتفاقی تو این خط داره می‌افته؟

65
08:15.200 --> 08:32.040
این یک خط فوق‌العاده باحاله، چون چیزی که داریم می‌گیم اینه که این **event** به اسم **TemperatureChanged** وجود داره. و به هر کسی، اگه هر کسی باشه، هر **subscriber**ای، من می‌خوام اون رو **invoke** کنم و می‌خوام شما رو **invoke** کنم.

66
08:32.040 --> 08:41.370
من می‌خوام اساساً این متد رو برای تک تک **subscriber**ها صدا بزنم. پس این فقط یک **subscriber** یا **TemperatureAlert** هست، اما می‌تونه **subscriber**های دیگه هم باشه، به تک تک اونها.

67
08:41.370 --> 08:43.050
می‌گم: هی، من قراره شما رو **invoke** کنم.

68
08:43.050 --> 08:47.450
قراره متد شما **OnTemperatureChanged** رو حالا صدا بزنم، چون تو نقطه بعدی

69
08:47.450 --> 08:58.330
می‌تونید اینجا ببینید که داریم اون رو اضافه می‌کنیم. پس اینجا بیایید اون رو به **TemperatureChanged** تغییر بدیم، چون این اسم جدیده، اگه بهش نگاه کنید، اسم **EventHandler** ما اینجا هست.

70
08:58.330 --> 09:26.030
و بعد تو این خط اساساً داریم از این **TemperatureAlert** استفاده می‌کنیم. اگه یادتون باشه، این **object TemperatureAlert** هست. و تو این خط چیزی که داریم می‌گیم اینه که: اوکی، **event** **TemperatureChanged** حالا یک **listener** جدید داره. و **listener** یا **subscriber**، این متد **OnTemperatureChanged** هست و وقتی **event** **TemperatureChanged** **trigger** بشه، این متد رو صدا بزن.

71
09:26.030 --> 09:39.290
پس این متد **OnTemperatureChanged** رو صدا بزن. کی **trigger** می‌شه؟ خب، این منطقیه که ما اینجا داخل **TemperatureMonitor**مون داریم که **event** رو **raise** می‌کنه، درسته؟ پس اینطوری ما **event** رو قبلاً **raise** می‌کردیم.

72
09:39.290 --> 09:42.170
حالا می‌خوایم این متد رو تو لحظه درست صدا بزنیم.

73
09:42.170 --> 09:51.860
پس کاری که قراره انجام بدم اینه که کد رو کمی تغییر بدم. قراره بگم هر بار که دما یک دمای جدید هست، قراره **event** رو **raise** کنیم.

74
09:51.860 --> 10:02.690
پس هر بار که مقدار **temperature** برابر با مقداری که برای **set** کردن **temperature** پاس داده می‌شه، نیست. پس کجا داریم دما رو اینجا **set** می‌کنیم؟

75
10:02.690 --> 10:08.350
اینجا جاییه که داریم دمای **TemperatureMonitor**مون رو **set** می‌کنیم. پس این **class** **TemperatureMonitor** هست، درسته؟

76
10:08.350 --> 10:20.410
پس هر بار که داریم دما رو **set** می‌کنیم، برای مثال داریم اون رو از **API** می‌خونیم یا از یک **sensor** می‌خونیم. بررسی می‌کنیم که آیا دما یک دمای جدید هست یا نه.

77
10:20.410 --> 10:28.180
و اگه هست، خب بیایید دمای جدید رو **set** کنیم. و علاوه بر اون، بیایید **event** رو هم **raise** کنیم.

78
10:28.180 --> 10:41.700
پس قراره متد **OnTemperatureChanged**مون رو صدا بزنیم. و قراره **event** رو پاس بدیم. چطور می‌تونیم حالا **TemperatureChangeEventArgs E** رو پاس بدیم؟ خب، می‌تونیم یک **new TemperatureChangedEventArgs** ایجاد کنیم.

79
10:41.700 --> 10:58.820
و می‌تونیم دما رو پاس بدیم. خب، می‌تونیم یا **value** رو پاس بدیم یا می‌تونیم **underscore temperature** رو هم پاس بدیم. تو این نقطه هر دو یکی هستن، درسته؟ چون ما دما رو با **value** بازنویسی کردیم. پس حالا چیزی که داریم می‌گیم، و این حالا همه چیز رو کنار هم میاره، هر وقت من دارم **event** رو **raise** می‌کنم، دارم به شما یک سری **EventArgs** می‌دم، تو این حالت فقط یکی، که دما هست.

80
10:58.820 --> 11:11.510
پس بعدش فراخوانی واقعی متد. پس این اینجا مستقیماً داره این متد رو صدا می‌زنه. درسته.

81
11:11.510 --> 11:22.210
اما بعدش، اما اینجا جاییه که داریم **event** رو **invoke** می‌کنیم و همه رو مطلع می‌کنیم، هر **subscriber**ای رو.

82
11:22.210 --> 11:27.220
پس اینجا داریم می‌گیم که هر **subscriber**ای رو مطلع می‌کنیم.

83
11:27.220 --> 11:34.450
و چی رو بهشون اطلاع می‌دیم؟ بهشون درباره **EventArgs** اطلاع می‌دیم، که تو این حالت فقط دما هست.

84
11:34.450 --> 11:37.420
اما می‌تونه خیلی بیشتر باشه. می‌تونه خیلی اطلاعات بیشتری باشه.

85
11:37.420 --> 11:40.270
حالا کاملاً در کنترل شماست.

86
11:40.270 --> 11:51.920
و من همچنین **object**ای که **event** رو **invoke** کرده رو پاس می‌دم. پس **object**ای که **event** رو **raise** کرده. و اون چه **object**ای هست؟ این **this** هست. **this** چیه؟

87
11:51.920 --> 12:04.610
این **class** **EventsApp.TemperatureMonitor** هست. پس اگه بیرون بریم، می‌بینیم که در واقع این **class** **TemperatureMonitor** هست. چون این کلمه کلیدی **this** تو بستر این **class** استفاده می‌شه.

88
12:04.610 --> 12:17.850
پس این **class** هست. پس **object TemperatureMonitor** که داریم پاس می‌دیم. خود **class** نیست، بلکه **object** هست. چون اگه بهش نگاه کنیم، وقتی داریم دما رو **set** می‌کنیم، داریم اون رو تو **monitor** انجام می‌دیم. **monitor** کیه؟

89
12:17.850 --> 12:29.130
این **class** **TemperatureMonitor** هست. پس این **class** درست اینجا هست. و این کلمه کلیدی **this** داخل **class** هست، پس فقط **object** رو پاس خواهد داد.

90
12:29.130 --> 12:37.720
بیایید فقط تستش کنیم و خواهید دید که این درسته، اوکی. پس بذارید بهتون نشون بدم.

91
12:37.720 --> 12:57.880
و ما اینجا هستیم: **Alert temperature is 20, sender is EventsApp.TemperatureMonitor**. پس می‌بینید که حالا **alert** ما هر بار که دما تغییر می‌کنه، فعال می‌شه. پس اگه دما رو مثلاً به 23 درجه تغییر بدیم، بعد می‌گه: **Temperature is 23, sender is EventsApp.TemperatureMonitor**.

92
12:57.880 --> 13:09.460
پس **sender** که این **sender object** برای **subscriber** ما هست، مهم نیست **subscriber** کیه. می‌تونه مثلاً یک **subscriber** سوم یا پنجم باشه. می‌تونیم ده تا **subscriber** داشته باشیم.

93
13:09.460 --> 13:12.940
بیایید یک **subscriber** دیگه فقط سریع کپی کنیم.

94
13:12.940 --> 13:28.970
پس این یکی خواهد بود، مثلاً، **temp cooling alert** (هشدار خنک کننده دما). بسیار خب. و قراره همون کار رو انجام بده، و فقط می‌گه **temp cooling alert**. بسیار خب.

95
13:28.970 --> 13:32.990
و حالا بیایید جلو بریم و اون **temp cooling alert** رو هم اضافه کنیم.

96
13:32.990 --> 13:37.250
پس **temp cooling alert**، **alert two** (هشدار دو) **new temp cooling alert**.

97
13:37.250 --> 13:49.040
و حالا **monitor** ما هم قراره **subscribe** کنه یا مثلاً **alert two** ما که همون **temp cooling alert** ماست، هم قراره تو **event** **TemperatureChanged** **monitor** **subscribe** کنه.

98
13:49.040 --> 13:58.340
پس حالا اگه این رو اجرا کنیم، برای هر دوی اونها **trigger** می‌شه. پس می‌بینید که **sender** تو هر دو حالت **EventsApp.TemperatureMonitor** هست.

99
13:58.340 --> 14:04.430
چون این نام **class** **object**ای هست که داره **event** رو **raise** می‌کنه، اوکی.

100
14:04.430 --> 14:09.690
پس تو این نقطه، فکر می‌کنم کل موضوع رو گذروندیم.

101
14:09.690 --> 14:22.560
حالا می‌دونید چطور می‌تونید اطلاعات خودتون رو پاس بدید، چطور می‌تونید **EventArgs** خودتون رو ایجاد کنید، به اصطلاح، تا جزئیات خودتون رو مثل دما یا هر پارامتر دیگه ای که می‌خواید داشته باشید، پاس بدید.

102
14:22.560 --> 14:33.150
دیدید که چطور از **generic EventHandler** استفاده کنید، و دیدید که چطور **event**ها رو **raise** کنید و همچنین چطور **subscriber** داشته باشید. پس این **subscriber** دو هست.

103
14:33.150 --> 14:39.300
و بعد چطور همه چیز رو کنار هم بیارید تا در واقع اون رو اجرا کنید، اوکی.

104
14:39.300 --> 14:40.950
پس این برای این ویدیو کافیه.

105
14:40.950 --> 14:42.570
طولانی‌ترین ویدیوی دوره تا الان.

106
14:42.570 --> 14:46.620
اما من نمی‌تونستم اون رو تو ویدیوهای جداگانه بذارم.

107
14:46.980 --> 14:55.290
چون هر بخش به تنهایی واقعاً بدون بخش‌های دیگه معنی نداشت. واقعاً مثل اینه که همه چیز به هم تعلق داره. اما حالا شما اون رو به دست آوردید.

108
14:55.290 --> 14:56.340
تبریک می‌گم.