{"id":673,"date":"2014-01-06T14:24:47","date_gmt":"2014-01-06T14:24:47","guid":{"rendered":"http:\/\/piatkosia.k4be.pl\/wordpress\/?p=673"},"modified":"2014-01-06T14:41:40","modified_gmt":"2014-01-06T14:41:40","slug":"c-zdarzenia-ostatni-z-konkursowych","status":"publish","type":"post","link":"https:\/\/piatkosia.k4be.pl\/wordpress\/2014\/01\/06\/c-zdarzenia-ostatni-z-konkursowych\/","title":{"rendered":"[c#] Zdarzenia &#8211; ostatni z konkursowych"},"content":{"rendered":"<p style=\"text-align: justify;\">Zdarzenia s\u0105 wywo\u0142ywane, je\u017celi co\u015b konkretnego stanie si\u0119 w trakcie dzia\u0142ania naszego programu. Akcj\u0105 wywo\u0142uj\u0105c\u0105 je mo\u017ce by\u0107 osi\u0105gni\u0119cie przez zmienn\u0105 pewnej warto\u015bci, przej\u015bcie wykonania programu do okre\u015blonego bloku, u\u017cycie mechanizmu drag and drop, lub chocia\u017cby klikni\u0119cie na przycisk lub najechanie myszk\u0105 na dane pole na ekranie. To w\u0142a\u015bnie dzi\u0119ki zdarzeniom dany obiekt mo\u017ce poinformowa\u0107 inny (kt\u00f3ry dane publiczne zdarzenie obs\u0142uguje) o zmianie swojego stanu. Klasa naszego obiektu mo\u017ce mie\u0107 bardzo wiele zdarze\u0144, kt\u00f3re s\u0105 wywo\u0142ywane po zaistnieniu \u015bci\u015ble okre\u015blonego warunku (jak zako\u0144czenie pobierania pliku, przyci\u015bni\u0119cie przycisku czy ustawienie zmiennej w setterze). U\u017cytkownik pisz\u0105c w Visual Studio cz\u0119sto sobie takie zdarzenia \u201ewyklikiwa\u0142\u201d projektuj\u0105c interfejs \u2013 na przyk\u0142ad przeci\u0105ga\u0142 z toolboxa kontrolk\u0119 typu button, nadaj\u0105c jej nazw\u0119, a nast\u0119pnie klikaj\u0105c na ni\u0105 2 razy. Po takiej operacji zosta\u0142 wygenerowany nast\u0119puj\u0105cy kod:\n<\/p>\n<pre class=\"brush: csharp; collapse: false\"> \r\nprivate void button1_Click(object sender, RoutedEventArgs e)\r\n        {\r\n            \r\n        }\r\n<\/pre>\n<p style=\"text-align: justify;\">Jak wida\u0107 funkcj\u0105 obs\u0142uguj\u0105c\u0105 zdarzenie jest (i musi by\u0107) funkcja, kt\u00f3ra nie zwraca warto\u015bci, a pobiera obiekt, kt\u00f3ry wywo\u0142a zdarzenie, oraz obiekt typu EventArgs. W przyk\u0142adzie powy\u017cej mamy obiekt typu RoutedEventArgs. Naje\u017cd\u017caj\u0105c na nazw\u0119 tego typu i po wci\u015bni\u0119ciu F12 mo\u017cemy zobaczy\u0107 taki fragment kodu public class RoutedEventArgs : EventArgs .<br \/>\nJak widzimy, klasa RoutedEventArgs dziedziczy po EventArgs \u2013 czyli wszystko jest jak by\u0107 powinno. Powy\u017csz\u0105 klas\u0119 nale\u017cy wype\u0142ni\u0107 kodem, kt\u00f3ry zostanie wywo\u0142any przy zaj\u015bciu zdarzenia \u2013 klikni\u0119cia na przycisk o nazwie button1.<br \/>\nAby nasza funkcja obs\u0142u\u017cy\u0142a dane zdarzenie nale\u017ca\u0142oby dokona\u0107 subskrypcji poprzez dopisanie delegaty do listy delegat, czyli zdarzenia. W przyk\u0142adzie powy\u017cej nie musieli\u015bmy tego robi\u0107? Nie prawda, te\u017c musieli\u015bmy, ale zrobi\u0142a to za nas platforma. W pliku MojaKlasa.g.cs (przy nowym projekcie MainWindow.g.cs), kt\u00f3ry jest generowany na podstawie naszego pliku .cs oraz .xaml czytamy:\n<\/p>\n<pre class=\"brush: csharp; collapse: false\"> \r\n#line 6 \"..\\..\\..\\MainWindow.xaml\"\r\nthis.button1.Click += new System.Windows.RoutedEventHandler(this.button1_Click);\r\n<\/pre>\n<p><!--more--><\/p>\n<p style=\"text-align: justify;\">W powy\u017cszym kodzie widzimy utworzenie delegatu do funkcji podanej w parametrze. Og\u00f3lnie robi si\u0119 to tak:\n<\/p>\n<pre class=\"brush: csharp; collapse: false\"> \r\npublic delegate void TypDelegatu();\r\n<\/pre>\n<p>poza klasami, a potem gdzie\u015b w \u015brodku funkcji<\/p>\n<pre class=\"brush: csharp; collapse: false\">  \r\nTypDelegatu JakisHandler = new TypDelegatu (JakasMetoda);\r\nobiekt.JakisEvent += JakisHandler;\r\nlub po prostu obiekt.JakisEvent += new TypDelegatu(jakasMetoda);\r\n<\/pre>\n<p style=\"text-align: justify;\">Bezpieczniej jest u\u017cy\u0107 += ni\u017c =, poniewa\u017c nie wiemy, czy co\u015b ju\u017c zosta\u0142o do zdarzenia dopisane. Mo\u017cemy do obs\u0142ugi zdarzenia doda\u0107 kilka funkcji, wystarczy doda\u0107 obiekt.JakisEvent += new TypDelegatu(InnaMetoda);<br \/>\nMetody wywo\u0142aj\u0105 si\u0119 w takiej kolejno\u015bci, w jakiej zosta\u0142y dopisane do obs\u0142ugi zdarzenia, w kolejno\u015bci od najwcze\u015bniej dodanej, do najp\u00f3\u017aniej.<br \/>\nEvent jest niczym innym, jak w\u0142asno\u015bci\u0105 klasy, kt\u00f3ra mo\u017ce go wygenerowa\u0107. W takim razie, deklarujemy go (zwykle publicznie) w ciele klasy. Na przyk\u0142ad\n<\/p>\n<pre class=\"brush: csharp; collapse: false\">\r\npublic event JakisHandler JakisEvent;\r\n<\/pre>\n<p style=\"text-align: justify;\">\nPrzy za\u0142o\u017ceniach, \u017ce JakisHandler to typ delegatu.<br \/>\nNapiszmy teraz w\u0142asne zdarzenie i je obs\u0142u\u017cmy. Najpro\u015bciej b\u0119dzie to zrobi\u0107 umieszczaj\u0105c wywo\u0142anie zdarzenia w setterze i zareagowanie na zmian\u0119.  Widzimy to w poni\u017cszym kodzie\n<\/p>\n<pre class=\"brush: csharp; collapse: true\"> \r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\n\r\nnamespace ConsoleApplication2\r\n{\r\n    public enum swiatlo { czerwone, zolte, zielone };\r\n\r\n    public delegate void RedHandler();\r\n    public delegate void YellowHandler();\r\n    public delegate void GreenHandler();\r\n\r\n    public class sygnalizator\r\n    {\r\n        private swiatlo _kolorswiatla;\r\n\r\n        public event RedHandler Redevent;\r\n        public event YellowHandler Yellowevent;\r\n        public event GreenHandler Greenevent;\r\n\r\n        public swiatlo kolorswiatla\r\n        {\r\n            get { return _kolorswiatla; }\r\n            set\r\n            {\r\n                _kolorswiatla = value;\r\n                if (value == swiatlo.zielone) if (Greenevent != null) Greenevent(); \/\/sprawdzamy czy s\u0105 jakie\u015b zdarzenia by unikn\u0105\u0107 NullPointerExeption\r\n                if (value == swiatlo.czerwone) if (Redevent != null) Redevent();\r\n                if (value == swiatlo.zolte) if (Yellowevent != null) Yellowevent();\r\n            }\r\n        }\r\n\r\n    }\r\n    class Program\r\n    {\r\n        static void Beep() { for (int i=0; i<3; i++) Console.Beep(); }\r\n        static void Redalert() { Console.WriteLine(\"\u015bwiat\u0142o czerwone\"); }\r\n        static void Greenalert() { Console.WriteLine(\"\u015bwiat\u0142o zielone\"); }\r\n        static void Yellowalert() { Console.WriteLine(\"\u015bwiat\u0142o \u017c\u00f3\u0142te\"); }\r\n        static void Main(string[] args)\r\n        {\r\n            \/\/Stworzenie obiektu\r\n            sygnalizator Sygnalizator = new sygnalizator();\r\n            \/\/dodanie obs\u0142ugi zdarze\u0144\r\n            Sygnalizator.Greenevent+=new GreenHandler(Greenalert);\r\n            Sygnalizator.Yellowevent += new YellowHandler(Yellowalert);\r\n            Sygnalizator.Redevent += new RedHandler(Redalert);\r\n            Sygnalizator.Redevent += new RedHandler(Beep);\r\n            Sygnalizator.kolorswiatla = swiatlo.czerwone;\r\n            System.Threading.Thread.Sleep(5000);\r\n            Sygnalizator.kolorswiatla = swiatlo.zolte;\r\n            System.Threading.Thread.Sleep(1000);\r\n            Sygnalizator.kolorswiatla = swiatlo.zielone;\r\n            Console.ReadKey();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">\nKlasa wywo\u0142uj\u0105ca zdarzenie, klasa w kt\u00f3rej zdarzenie zosta\u0142o wywo\u0142ane oraz u\u017cycie obu klas, mog\u0105 by\u0107 zupe\u0142nie w innych miejscach. Wyobra\u017amy sobie lotnisko (program g\u0142\u00f3wny), na kt\u00f3rym stoi kazio i obserwuje lec\u0105cy samolot (subskrybuje powiadomenia o stanie samolotu). Mogliby\u015bmy to zaimplementowa\u0107 w nast\u0119puj\u0105cy spos\u00f3b:\n<\/p>\n<pre class=\"brush: csharp; collapse: true\"> \r\nusing System;\r\nusing System.Threading;\r\n \r\nnamespace Okecie\r\n{\r\n     public class Samolot\r\n    {\r\n        public delegate void LotHandler (object samolot, EventArgs info);\r\n        public event LotHandler Lot;\r\n        protected void OnLot(object samolot, EventArgs info)\r\n        {\r\n            if (Lot != null)\r\n            {\r\n                Lot(this, info);\r\n            }\r\n        }\r\n        public void odlot(int a)\r\n        {\r\n            for (int i = 0; i < a; i++)\r\n            {\r\n                Thread.Sleep(1000);\r\n                Console.WriteLine(\"Samolot leci\");\r\n                OnLot(this, new EventArgs());\r\n            }\r\n            Console.WriteLine(\"Samolot dolecia\u0142\");\r\n            OnLot(this, new EventArgs());\r\n\r\n        }\r\n    }\r\n \r\n    public class Obserwator\r\n    {\r\n        public void Subscribe(Samolot machine)\r\n        {\r\n            machine.Lot += new Samolot.LotHandler(CheckResult);\r\n        }\r\n        public void CheckResult(object samolot, EventArgs info)\r\n        {\r\n            Console.WriteLine();\r\n        }\r\n    }\r\n \r\n    class Lotnisko\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            Samolot samolocik = new Samolot();\r\n            Obserwator kazio = new Obserwator();\r\n \r\n            kazio.Subscribe(samolocik);\r\n            samolocik.odlot(10);\r\n            Console.ReadKey();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">\nMamy tu u\u017cycie zdarze\u0144, kt\u00f3re sami napisali\u015bmy, na obiektach naszej produkcji.<br \/>\nJak wida\u0107, u\u017cycie zdarze\u0144 jest naprawd\u0119 prostsze ni\u017c mo\u017cna by domniema\u0107 ogl\u0105daj\u0105c przyk\u0142ad u\u017cycia prezentowany w dokumentacji MSDN. W bardzo \u0142atwy spos\u00f3b mo\u017cemy u\u017cywa\u0107 zdarze\u0144, jakie zosta\u0142y dla nas przygotowane przez platform\u0119, oraz tworzy\u0107 swoje. Dzi\u0119ki zdarzeniom nasza klasa mo\u017ce wywo\u0142a\u0107 funkcje, o jakich nie ma zielonego poj\u0119cia w chwili jej tworzenia \u2013 wa\u017cne tylko, by przyjmowa\u0142a okre\u015blone parametry.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Zdarzenia s\u0105 wywo\u0142ywane, je\u017celi co\u015b konkretnego stanie si\u0119 w trakcie dzia\u0142ania naszego programu. Akcj\u0105 wywo\u0142uj\u0105c\u0105 je mo\u017ce by\u0107 osi\u0105gni\u0119cie przez zmienn\u0105 pewnej warto\u015bci, przej\u015bcie wykonania<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/piatkosia.k4be.pl\/wordpress\/2014\/01\/06\/c-zdarzenia-ostatni-z-konkursowych\/\">Lecim dalej<span class=\"screen-reader-text\">[c#] Zdarzenia &#8211; ostatni z konkursowych<\/span> <i class=\"fas fa-angle-right\"><\/i><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-673","post","type-post","status-publish","format-standard","hentry","category-bez-kategorii","entry"],"_links":{"self":[{"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts\/673","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/comments?post=673"}],"version-history":[{"count":10,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts\/673\/revisions"}],"predecessor-version":[{"id":683,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts\/673\/revisions\/683"}],"wp:attachment":[{"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/media?parent=673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/categories?post=673"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/tags?post=673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}