{"id":523,"date":"2016-05-02T18:03:11","date_gmt":"2016-05-02T16:03:11","guid":{"rendered":"http:\/\/www.daniel.slask.pl\/?p=523"},"modified":"2021-02-12T21:04:20","modified_gmt":"2021-02-12T20:04:20","slug":"visual-studio-2015-dynamiczne-tworzenie-kontrolek-tworzenie-obsluga-i-objasnienia-jezykiem-poczatkujacego","status":"publish","type":"post","link":"https:\/\/daniel.slask.pl\/m\/visual-studio-2015-dynamiczne-tworzenie-kontrolek-tworzenie-obsluga-i-objasnienia-jezykiem-poczatkujacego\/","title":{"rendered":"[Visual Studio 2015] Dynamiczne tworzenie kontrolek &#8211; tworzenie, obs\u0142uga i obja\u015bnienia. J\u0119zykiem pocz\u0105tkuj\u0105cego"},"content":{"rendered":"\n<p>Witam.<\/p>\n\n\n\n<p>Tym razem chcia\u0142bym si\u0119 z wami podzieli\u0107 wiedz\u0105 dot. dynamicznego tworzenia kontrolek w C#, oraz ich obs\u0142ugi. Opis kolejnych czynno\u015bci (kod\u00f3w w programie) opisywa\u0142 b\u0119d\u0119 <span style=\"text-decoration: underline;\">&#8222;j\u0119zykiem pocz\u0105tkuj\u0105cego&#8221;<\/span>, czyli tak jak Ja to rozumiem.<br>Od razu chcia\u0142bym przeprosi\u0107 bardziej zaawansowanych czytelnik\u00f3w za form\u0119 i niepoprawne nazewnictwo niekt\u00f3rych czynno\u015bci &#8211; pisz\u0119 tak aby pocz\u0105tkuj\u0105ca osoba potrafi\u0142a zrozumie\u0107 co si\u0119 dzieje w danej linijce kody. Jednak je\u017celi pope\u0142ni\u0142em jakie\u015b ra\u017c\u0105ce b\u0142\u0119dy, prosz\u0119 o zwr\u00f3cenie mi uwagi.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><strong>Zaczynajmy!<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image alignnone\"><a href=\"http:\/\/www.daniel.slask.pl\/m\/wp-content\/uploads\/2016\/05\/Dzia\u0142aj\u0105cy_program.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"http:\/\/www.daniel.slask.pl\/m\/wp-content\/uploads\/2016\/05\/Dzia\u0142aj\u0105cy_program-150x150.jpg\" alt=\"Wygl\u0105d dzia\u0142aj\u0105cego programu\" class=\"wp-image-524\" srcset=\"https:\/\/daniel.slask.pl\/m\/wp-content\/uploads\/2016\/05\/Dzia\u0142aj\u0105cy_program-150x150.jpg 150w, https:\/\/daniel.slask.pl\/m\/wp-content\/uploads\/2016\/05\/Dzia\u0142aj\u0105cy_program.jpg 300w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/><\/a><figcaption>Wygl\u0105d dzia\u0142aj\u0105cego programu<\/figcaption><\/figure>\n\n\n\n<p>Program, kt\u00f3ry powstanie b\u0119dzie powodowa\u0142 dynamiczne utworzenie kontrolek &#8211; ilo\u015b\u0107 tych kontrolek b\u0119dzie zale\u017cna od tego ile u\u017cytkownik wpisze do odpowiedniego pola. Kontrolki, kt\u00f3re zostan\u0105 utworzone w spos\u00f3b dynamiczny (tzn. ilo\u015b\u0107 nie jest zdefiniowana w momencie kompilacji programu &#8211; b\u0119d\u0105 one tworzone w czasie dzia\u0142ania programu) to:<\/p>\n\n\n\n<ol><li><em>TextBox<\/em><\/li><li><em>Button<\/em><\/li><li><em>Label<\/em><\/li><\/ol>\n\n\n\n<p>Dodatkowo, program b\u0119dzie umo\u017cliwia\u0142 wykonanie przepisania zawarto\u015bci z <em>TextBox<\/em> do <em>Label<\/em> po wci\u015bni\u0119ciu odpowiadaj\u0105cego im przycisku.<\/p>\n\n\n\n<p>W programie zostan\u0105 u\u017cyte jeszcze 4 kontrolki &#8211; <em>Label, TextBox, Button<\/em> x2szt.<\/p>\n\n\n\n<p>Wygl\u0105d okna formularza przedstawia si\u0119 nast\u0119puj\u0105co:<\/p>\n\n\n\n<figure class=\"wp-block-image alignnone\"><a href=\"http:\/\/www.daniel.slask.pl\/m\/wp-content\/uploads\/2016\/05\/Wyglad_formularza.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"http:\/\/www.daniel.slask.pl\/m\/wp-content\/uploads\/2016\/05\/Wyglad_formularza-150x150.jpg\" alt=\"Wygl\u0105d formularza\" class=\"wp-image-525\"\/><\/a><figcaption>Wygl\u0105d formularza<\/figcaption><\/figure>\n\n\n\n<p>Pod przyciskiem <em>Zamknij<\/em> znajduje si\u0119 polecenie umo\u017cliwiaj\u0105ce zamkni\u0119cie programu:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c# decode:true\"><code lang=\"csharp\" class=\"language-csharp\">Close();<\/code><\/pre>\n\n\n\n<p>Natomiast ca\u0142y program kt\u00f3ry b\u0119dzie tworzy\u0142 nowe kontrolki b\u0119dzie znajdowa\u0142 si\u0119 pod przyciskiem <em>Utw\u00f3rz.<\/em> Do <em>TextBox&#8217;a<\/em> b\u0119dzie wpisywana ilo\u015b\u0107 komplet\u00f3w element\u00f3w jaka ma zosta\u0107 utworzona.<\/p>\n\n\n\n<p>Jednak przed przyst\u0105pieniem do pisania kodu zerknijmy jak <em>Visual Studio<\/em> tworzy komponenty (po co samemu si\u0119 g\u0142owi\u0107 jak mamy dost\u0119pne gotowe rozwi\u0105zania)- w tym celu przechodzimy do pliku <em>Form1.Designer.cs<\/em> (wybieramy go z eksploratora projektu kt\u00f3ry znajduje si\u0119 po prawej stronie). Na samym ko\u0144cu naszej g\u0142\u00f3wnej klasy mamy deklaracj\u0119 u\u017cytych komponent\u00f3w:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c# decode:true\"><code lang=\"csharp\" class=\"language-csharp line-numbers\">        private System.Windows.Forms.Button button1;\n        private System.Windows.Forms.Button button2;\n        private System.Windows.Forms.TextBox textBox1;\n        private System.Windows.Forms.Label label1;<\/code><\/pre>\n\n\n\n<p>Dalej w pliku tym znajdujemy metod\u0119 (czyli funkcj\u0119 z klasy naszego programu) <em>InitializeComponent()<\/em> &#8211; znajduje si\u0119 ona przed deklaracj\u0105 komponent\u00f3w. Wewn\u0105trz tej metody (mo\u017ce ona by\u0107 zwini\u0119ta &#8211; je\u017celi tak jest nale\u017cy po lewej stronie nacisn\u0105\u0107 + aby j\u0105 rozwin\u0105\u0107) znajduje si\u0119 ca\u0142y kod odpowiedzialny za tworzenie naszego formularza i tego co si\u0119 w nim znajduje. Na pocz\u0105tku widzimy definicj\u0119 nowych kontrolek &#8211; <em>obiekt\u00f3w (instancji klasy)<\/em> ale o tym za chwil\u0119. Fragment tego kodu prezentuje si\u0119 nast\u0119puj\u0105co:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c# decode:true\"><code lang=\"csharp\" class=\"language-csharp line-numbers\">            this.button1 = new System.Windows.Forms.Button();\n            this.button2 = new System.Windows.Forms.Button();\n            this.textBox1 = new System.Windows.Forms.TextBox();\n            this.label1 = new System.Windows.Forms.Label();<\/code><\/pre>\n\n\n\n<p>Widzimy tutaj wyra\u017cenie &#8211; <em>this<\/em> (z ang. to, ten). Oznacza ono \u017ce odnosimy si\u0119 do obecnej klasy, w kt\u00f3rej zosta\u0142 wywo\u0142any (stosuje si\u0119 go g\u0142\u00f3wnie po to, aby unikn\u0105\u0107 np. zbie\u017cno\u015bci nazw zmiennych wyst\u0119puj\u0105cych w klasie i np. w funkcji\/metodzie). Do nowej zmiennej, np. <em>button1,<\/em> przypisywany jest nowy obiekt <em>Button(),<\/em> a dok\u0142adnie tworzony (uruchamiany jest konstruktor tego obiektu, czyli naszej kontrolki) obiekt &#8211; rezerwowane jest miejsce w pami\u0119ci na wszystkie funkcje (metody) kt\u00f3re s\u0105 przypisane dla tej klasy (kt\u00f3ra opisuje dan\u0105 kontrolk\u0119) &#8211; wszystko dzi\u0119ki u\u017cyciu <em>new.<\/em><\/p>\n\n\n\n<p>Dalej w kodzie widzimy konfiguracj\u0119 przycisku:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c decode:true\"><code lang=\"csharp\" class=\"language-csharp line-numbers\">            \/\/\n            \/\/ button1\n            \/\/\n            this.button1.Location = new System.Drawing.Point(197, 12);\n            this.button1.Name = \"button1\";\n            this.button1.Size = new System.Drawing.Size(75, 23);\n            this.button1.TabIndex = 0;\n            this.button1.Text = \"Zamknij\";\n            this.button1.UseVisualStyleBackColor = true;\n            this.button1.Click += new System.EventHandler(this.button1_Click);<\/code><\/pre>\n\n\n\n<p>W pierwszej kolejno\u015bci ustawiamy punkt w kt\u00f3rym b\u0119dzie utworzony nasz komponent. Tworzona jest lokalizacja obiektu w podanym punkcie. Wsp\u00f3\u0142rz\u0119dne podawane s\u0105 w nast\u0119puj\u0105cej kolejno\u015bci: X, Y.<br>Nast\u0119pnie podawana jest nazwa przycisku (wyja\u015bnione to zostanie w dalszej cz\u0119\u015bci), rozmiar (tworzony jest obiekt w sensie wizualnym), okre\u015blany jest kolejny numer podczas prze\u0142\u0105czania mi\u0119dzy kontrolkami przy u\u017cyciu <em>TAB.<\/em> P\u00f3\u017aniej ustawiamy wy\u015bwietlany tekst, oraz okre\u015blenie czy t\u0142o ma by\u0107 rysowane wg styli wizualnych. Na samym ko\u0144cu dodawana jest metoda w przypadku wykonania klikni\u0119cia &#8211; dla zdarzenia <em>CLICK.<\/em> Dodawana z tego wzgl\u0119du, \u017ce mo\u017ce by\u0107 wywo\u0142anych wiele metod.<br>Tworzony jest nowy uchwyt\/odno\u015bnik dla zdarzenia <em>(EventHandler<\/em> jest<span style=\"color: #000000;\"> <a style=\"color: #000000;\" href=\"http:\/\/www.daniel.slask.pl\/?p=502\">delegatem,<\/a><\/span> czyli wska\u017anikiem) &#8211; m\u00f3wi\u0105c pro\u015bciej, do zdarzenia <em>Click<\/em> przypisywany jest wska\u017anik funkcji kt\u00f3ra ma zosta\u0107 wywo\u0142ana (jako parametr przekazujemy funkcj\u0119\/metod\u0119 kt\u00f3ra ma obs\u0142u\u017cy\u0107 to zdarzenie)<\/p>\n\n\n\n<p>Przechodzimy jeszcze pod koniec tej metody. W sektorze odpowiedzialnym za utworzenie formularza odnajdujemy nast\u0119puj\u0105ce fragmenty kodu:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c decode:true\"><code lang=\"csharp\" class=\"language-csharp line-numbers\">            this.Controls.Add(this.label1);\n            this.Controls.Add(this.textBox1);\n            this.Controls.Add(this.button2);\n            this.Controls.Add(this.button1);<\/code><\/pre>\n\n\n\n<p>Linijki kodu odpowiedzialne one s\u0105 za dodanie naszych kontrolek do formularza, a dok\u0142adanie do kolekcji formularza, czyli takiej tablicy, kt\u00f3ra mo\u017ce w spos\u00f3b dynamiczny mie\u0107 zmienian\u0105 wielko\u015b\u0107 &#8211; w kolekcji \u0142atwiejszy spos\u00f3b s\u0105 dodawane i usuwane warto\u015bci. Wszystkie kontrolki, kt\u00f3re tworzymy (czy to z poziomu projektanta formularza, czy dynamicznie) znajduj\u0105 si\u0119 w takiej kolekcji. Niekoniecznie musi by\u0107 to kolekcja formularza, mo\u017ce znale\u017a\u0107 si\u0119 r\u00f3wnie\u017c kolekcja tzw. kontener\u00f3w &#8211; <em>GroupBox, Panel,<\/em> itp.<\/p>\n\n\n\n<p>Czyli ju\u017c wiemy na czym polega utworzenie nowej kontrolki. Przedstawi\u0119 teraz w punktach kolejno\u015b\u0107 post\u0119powania w przypadku tworzenia nowej kontrolki:<\/p>\n\n\n\n<ol><li>Deklaracja nowej kontrolki &#8211; tworzymy now\u0105 zmienn\u0105 (kt\u00f3rej typem jest kontrolka)<\/li><li>Przypisanie do naszej zmiennej obiektu kontrolki (wywo\u0142anie konstruktora)<\/li><li>Ustawienie po\u0142o\u017cenia kontrolki, oraz jej rozmiaru<\/li><li>Przypisanie jej nazwy<\/li><li>Pozosta\u0142a konfiguracja kontrolki<\/li><li>Dodanie kontrolki do kolekcji np. formularza<\/li><\/ol>\n\n\n\n<p>W taki spos\u00f3b b\u0119dziemy tworzy\u0107 r\u00f3wnie\u017c w spos\u00f3b dynamiczny nasze kontrolki.<\/p>\n\n\n\n<p>Tworzenie dynamiczne kontrolek b\u0119dzie wykonywane po podaniu liczby w <em>textbox<\/em> i naci\u015bni\u0119ciu przycisku Utw\u00f3rz. Kod, kt\u00f3ry znajduje si\u0119 pod tym przyciskiem wygl\u0105da nast\u0119puj\u0105co:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c# decode:true\"><code lang=\"csharp\" class=\"language-csharp\">        private void button2_Click(object sender, EventArgs e)\n        {\n            int liczba_elementow = Convert.ToInt16(textBox1.Text); \/\/Konwersja wpisanej warto\u015bci do textboxa na int\n\n            for (int i = 0; i &lt; liczba_elementow; i++)\n            {\n                \/\/tworzymy now\u0105 kontrolk\u0119 - textbox, button, oraz label\n                TextBox ntextbox = new TextBox();\n                Button nbutton = new Button();\n                Label nlabel = new Label();\n\n                \/\/umieszczanie na ekranie danej kontrolki\n                ntextbox.Location = new System.Drawing.Point(12, 110 + 26 * i);\n                nbutton.Location = new System.Drawing.Point(118, 108 + 26 * i);\n                nlabel.Location = new Point(213, 113 + 26 * i);\n\n                \/\/okre\u015blenie rozmiar\u00f3w kontrolki\n                ntextbox.Size = new System.Drawing.Size(100, 20);\n                nbutton.Size = new System.Drawing.Size(75, 23);\n                nlabel.Size = new Size(35, 13);\n\n                \/\/przypisanie nazwy danej kontrolce\n                ntextbox.Name = \"d_box_\" + i.ToString();\n                nbutton.Name = \"d_button_\" + i.ToString();\n                nlabel.Name = \"d_label_\" + i.ToString();\n\n                \/\/konfiguracja danej kontrolki - wyswietlany tekst, ewentualne ustawienia\n                nbutton.Text = \"Przepisz\";   \/\/nazwa przycisku\n                nlabel.AutoSize = true;      \/\/ustawienie automatycznego dopasowania szeroko\u015bci\n\n                \/\/ustawienie zdarzenia dla przycisk\u00f3w\n                nbutton.Click += new System.EventHandler(Nbutton_Click);\n\n                \/\/dodanie kontrolek do formularza (do kolekcji - tablicy)\n                Controls.Add(ntextbox);\n                Controls.Add(nbutton);\n                Controls.Add(nlabel);\n\n            }\n        }<\/code><\/pre>\n\n\n\n<p>Wi\u0119kszo\u015b\u0107 kodu zosta\u0142a wyja\u015bniona w komentarzach, b\u0105d\u017a om\u00f3wiona wcze\u015bniej.<br>Mo\u017cna jednak zauwa\u017cy\u0107 \u017ce dla okre\u015blenia po\u0142o\u017cenia i rozmiaru kontrolki u\u017cy\u0142em innego sposobu przypisania parametr\u00f3w. Chcia\u0142em w ten spos\u00f3b pokaza\u0107, \u017ce dzi\u0119ki zdefiniowaniu na pocz\u0105tku przestrzeni nazw <em>System.Drawing<\/em> nie musimy za ka\u017cdym razem pisa\u0107 sk\u0105d dana metoda ma zosta\u0107 zaczerpni\u0119ta. Przydaje si\u0119 to jednak w tedy, gdy w r\u00f3\u017cnych przestrzeniach (klasach) mamy podobno brzmi\u0105ce metody &#8211; w tedy zastosowanie pe\u0142nych nazw powoduje unikni\u0119cia b\u0142\u0119du (pe\u0142nych nazw, czyli z jakiej przestrzeni\/klasy jest zaczerpni\u0119ta dana metoda\/funkcja).<\/p>\n\n\n\n<p>Jak to jest z t\u0105 nazw\u0105 tej kontrolki? Ot\u00f3\u017c gdy tworzymy dynamicznie np. przycisk w kodzie musimy jako\u015b nazwa\u0107 nasz nowy obiekt np. <em>nbutton,<\/em> dla kt\u00f3rego b\u0119dziemy ustawia\u0107 parametry. Dla jednego przycisku nie by\u0142oby problemu, ale dla wi\u0119kszej ilo\u015bci musieliby\u015bmy utworzy\u0107 wi\u0119cej zmiennych &#8211; tylko to si\u0119 mija z dynamicznym tworzeniem kontrolek. Dlatego gdy tworzymy w spos\u00f3b dynamiczny now\u0105 kontrolk\u0119 najpierw wykorzystujemy nazw\u0119 kt\u00f3r\u0105 zdefiniowali\u015bmy w programie (tworzymy tylko jedn\u0105 zmienn\u0105 dla jednego typu &#8211; bo po co wi\u0119cej!?), aby \u0142atwiej si\u0119 konfigurowa\u0142o ten i nast\u0119pny komponent (tworzony jest taki wska\u017anik na dany obiekt, kt\u00f3ry w danej chwili jest konfigurowany), a w kolejnych czynno\u015bci zmieniana jest dynamicznie nazwa tego komponentu. Pod t\u0105 nazw\u0105 znajduje si\u0119 adres (indeks w kolekcji\/tabeli) kt\u00f3ry wskazuje na nasz obiekt (kontrolk\u0119) kt\u00f3ry jest teraz konfigurowany, wi\u0119c nazwa ta mo\u017ce by\u0107 zmieniana &#8211; zmieniaj\u0105c nazw\u0119 nie zmieniamy adresu gdzie przechowywana jest nasza kontrolka. Troch\u0119 to jest pokr\u0119cone, ale dzi\u0119ki parametrowi <em>Name,<\/em> tw\u00f3rcy tego komponentu umo\u017cliwili w \u0142atwy spos\u00f3b mo\u017cliwo\u015b\u0107 zmiany nazwy tej kontrolki w spos\u00f3b dynamiczny, oraz w prosty spos\u00f3b odnoszenie si\u0119 do jej w\u0142a\u015bciwo\u015bci. Po dodaniu kontrolki do kolekcji np. formularza, aby si\u0119 do niej odwo\u0142a\u0107, nale\u017cy wykorzysta\u0107 nazw\u0119, jaka zosta\u0142a przypisana poprzez parametr <em>Name.<\/em><br>Dla kontrolek utworzony w projektancie formularza, parametr <em>Name<\/em> raczej nie b\u0119dzie zmieniany w spos\u00f3b dynamiczny podczas dzia\u0142ania programu &#8211; bo po co, jak i tak w dalszej cz\u0119\u015bci programu nazwa tej kontrolki zostanie niezmieniona i ka\u017cda pr\u00f3ba odwo\u0142ania si\u0119 do tej kontrolki (kt\u00f3ra b\u0119dzie mia\u0142a ju\u017c zmienion\u0105 nazw\u0119) mo\u017ce spowodowa\u0107 b\u0142\u0105d programu.<br>Mam nadziej\u0119, \u017ce opisa\u0142em to do\u015b\u0107 zrozumiale &#8211; jakby co to pisa\u0107.<\/p>\n\n\n\n<p>Musimy jeszcze napisa\u0107 funkcj\u0119\/metod\u0119 kt\u00f3ra b\u0119dzie wykonywana po naci\u015bni\u0119ciu na przycisk, kt\u00f3ry zosta\u0142 utworzony dynamicznie. Umie\u015bcimy j\u0105 po obs\u0142udze przycisku <em>Utw\u00f3rz<\/em>. B\u0119dzie ona mia\u0142a nast\u0119puj\u0105co posta\u0107:<\/p>\n\n\n\n<pre class=\"wp-block-code lang:c decode:true\"><code lang=\"csharp\" class=\"language-csharp line-numbers\">        private void Nbutton_Click(object sender, EventArgs e)\n        {\n            \/\/odczytanie numeru przycisku kt\u00f3ry spowodowa\u0142 wywo\u0142anie tego zdarzenia\n            string nr_kontrolki = (sender as Button).Name.Remove(0, 9);\n\n            \/\/tworzymy nowe obiekty - dok\u0142adnie uchwyty do istniej\u0105cych obiekt\u00f3w (poprzez wyszukanie FIND)\n            TextBox ptextbox = (TextBox)this.Controls.Find(\"d_box_\" + nr_kontrolki, false).First();\n            Label plabel = this.Controls.Find(\"d_label_\" + nr_kontrolki, false).First() as Label;\n\n            \/\/przepisanie zawarto\u015bci\n            plabel.Text = ptextbox.Text;\n\n            \/\/usuni\u0119cie przycisku kt\u00f3ry spowodowa\u0142 to zdarzenie - usuni\u0119cie z kolekcji\n            Controls.Remove(sender as Button);\n\n        }<\/code><\/pre>\n\n\n\n<p>R\u00f3wnie\u017c w tym przypadku zaczerpn\u0105\u0142em z gotowego rozwi\u0105zania, kt\u00f3re daje nam <em>Visual<\/em> &#8211; typy jakie s\u0105 przekazywane do tej metody, oraz typ jaki zwraca ta metoda &#8211; a dok\u0142adnie \u017ce nic nie zwraca;).<br>Co jest przekazywane do tej metody:<br>Poprzez zmienn\u0105 <em>sender<\/em> przekazywany jest typ <em>object,<\/em> kt\u00f3ry informuje u\u017cytkownika, czyli nas z kt\u00f3rego komponentu nast\u0105pi\u0142o wywo\u0142anie tego zdarzenia. Dzi\u0119ki temu mamy mo\u017cliwo\u015b\u0107 odwo\u0142ania si\u0119 do wszystkich w\u0142a\u015bciwo\u015bci tego komponentu. Drugim parametrem jest <em>EventArgs,<\/em> kt\u00f3ry przechowuje informacje o zdarzeniu &#8211; prawd\u0119 m\u00f3wi\u0105c jeszcze dok\u0142adnie nie wiem do czego on mo\u017ce s\u0142u\u017cy\u0107 wi\u0119c pomin\u0119 opis tego parametru.<\/p>\n\n\n\n<p>Aby mo\u017cna by\u0142o odwo\u0142a\u0107 si\u0119 do kontrolki, kt\u00f3ra wywo\u0142a\u0142a to zdarzenie, nale\u017cy wykorzysta\u0107 operator <em>as<\/em> (jako, tak jak), kt\u00f3ry umo\u017cliwi konwersj\u0119 &#8211; w wolnym t\u0142umaczeniu obiekt <em>sender<\/em> traktujemy jako przycisk <em>button<\/em> (dla tego rozwa\u017canego przypadku). Dzi\u0119ki temu mo\u017cliwy jest dost\u0119p do wszystkich w\u0142a\u015bciwo\u015bci kontrolki, kt\u00f3ra spowodowa\u0142a wywo\u0142anie tego zdarzenia.<\/p>\n\n\n\n<p>Wr\u00f3\u0107my jeszcze na chwil\u0119 do poprzedniego kodu. Tam jako nazw\u0119 dla danej kontrolki u\u017cy\u0142em specjalnie d\u0142u\u017cszego tekstu, kt\u00f3ry zako\u0144czony jest kolejnym numer &#8211; kt\u00f3ry jest ten sam dla ka\u017cdej grupy kontrolek (w tym przypadku grupa kontrolek dla mnie to <em>label, button<\/em> i <em>textbox).<\/em> Mo\u017cna by\u0142o u\u017cy\u0107 samego numeru co by u\u0142atwi\u0142o identyfikacj\u0119 kt\u00f3ra grupa zosta\u0142a wywo\u0142ana &#8211; ale chcia\u0142em wykorzysta\u0107 i sprawdzi\u0107 metody kt\u00f3re znajduj\u0105 si\u0119 w klasie <em>string.<\/em><br>Tak wi\u0119c w pierwszej kolejno\u015bci w obs\u0142udze przycisku musimy odczyta\u0107 kt\u00f3ra grupa jest wywo\u0142ana. Dokonujemy tego poprzez wyci\u0119cia s\u0142owa <em>&#8222;d_button_&#8221;<\/em> kt\u00f3re ma 9 znak\u00f3w &#8211; u\u017cyjemy w tym celu metody <em>Remove,<\/em> do kt\u00f3rej nale\u017cy przekaza\u0107 indeks od kt\u00f3rego ma zacz\u0105\u0107 usuwa\u0107 znaki, oraz ilo\u015b\u0107 znak\u00f3w do usuni\u0119cia. Tak przygotowan\u0105 informacj\u0119 przepisujemy do zmiennej <em>nr_kontrolki,<\/em> kt\u00f3ra jest typu <em>string<\/em> &#8211; nie jest konieczna konwersja na <em>int,<\/em> z tego wzgl\u0119du, \u017ce w dalszej cz\u0119\u015bci programu sk\u0142adane b\u0119d\u0105 nazwy kolejnych kontrolek.<\/p>\n\n\n\n<p>Nast\u0119pnie tworzone s\u0105 dwa nowe obiekty &#8211; <em>label<\/em> i <em>textbox.<\/em> Do nazw tych obiekt\u00f3w przypisujemy kontrolki, kt\u00f3re zosta\u0142y utworzone przez nas w spos\u00f3b dynamiczny. Aby tego dokona\u0107 nale\u017cy wykorzysta\u0107 metod\u0119 <em>Find,<\/em> kt\u00f3ra powoduje wyszukanie w danej kolekcji kontrolki o podanej nazwie. Drugim parametrem jest warto\u015b\u0107 typu <em>bool,<\/em> kt\u00f3ra okre\u015bla czy maj\u0105 zosta\u0107 r\u00f3wnie\u017c wyszukane kontrolki tzw. potomne (w naszym przypadku nie, wi\u0119c ustawiamy <em>false).<\/em> Metoda ta zwraca w postaci tabeli wszystkie odpowiadaj\u0105ce kontrolki. Mo\u017cna w \u0142atwy spos\u00f3b poprzez metod\u0119 <em>First(),<\/em> zwr\u00f3ci\u0107 pierwsz\u0105 warto\u015b\u0107 tej tablicy. Nale\u017cy jeszcze przekonwertowa\u0107 na odpowiedni\u0105 kontrolk\u0119 dany <em>obiekt<\/em> &#8211; tutaj przedstawi\u0142em dwa sposoby: poprzez jawne rzutowani i z zastosowaniem <em>as (as<\/em> w przypadku gdy nie uda si\u0119 przekonwertowa\u0107 danych nie spowoduje b\u0142\u0119du, tylko wpisze do zmiennej <em>null,<\/em> czego nie mo\u017cna powiedzie\u0107 o innych sposobach konwersji typ\u00f3w).<br>Nast\u0119pnie s\u0105 przepisywane dane z jednej kontrolki do drugiej.<br>Na samym ko\u0144cu usuwany jest przycisk kt\u00f3ry nacisn\u0119li\u015bmy &#8211; jest on usuwany ca\u0142kowicie z kolekcji i nie mamy do niego dost\u0119pu w \u017caden spos\u00f3b.<\/p>\n\n\n\n<p>Ustawiamy jeszcze dla formularza w\u0142a\u015bciwo\u015b\u0107 <em>AutoScroll<\/em> na <em>true<\/em> &#8211; dzi\u0119ki czemu pojawi\u0105 nam si\u0119 paski przewijania w przypadku gdy kontrolki wyjd\u0105 poza nasz formularz. Zmiany tej dokonujemy w projektancie formularza we w\u0142a\u015bciwo\u015bciach naszego <em>Form1.<\/em><\/p>\n\n\n\n<p>Chyba to wszystko. Mam nadziej\u0119, \u017ce uda\u0142o mi si\u0119 w prosty spos\u00f3b (ale pewnie zakr\u0119cony) wyt\u0142umaczy\u0107 niekt\u00f3re aspekty dynamicznego tworzenia kontrolek. Mo\u017cliwe, \u017ce czasami za bardzo zakr\u0119ci\u0142em opisem, za co przepraszam.<\/p>\n\n\n\n<p>W przypadku jakich\u015b b\u0142\u0119d\u00f3w, czy pyta\u0144 pisa\u0107. Ka\u017cda forma krytyki b\u0119dzie motywuj\u0105ca;)<\/p>\n\n\n\n<p>Jeszcze w za\u0142\u0105czniku przesy\u0142am ca\u0142y program wraz z komentarzami, aby ka\u017cdy m\u00f3g\u0142 sprawdzi\u0107 jak to dzia\u0142a.<\/p>\n\n\n\n<a  data-e-Disable-Page-Transition=\"true\" class=\"download-link download-button aligncenter\" title=\"Wersja v1.0\" href=\"https:\/\/daniel.slask.pl\/m\/download\/526\/?tmstv=1788163887\" rel=\"nofollow\" id=\"download-link-526\" >\n\t<p>\n\t\tPobierz &ldquo;Cs_02_dynamiczne_kontrolki.zip&rdquo;\t<\/p>\n\t<small>Cs_02_dynamiczne_kontrolki.zip\t\t&ndash; Pobrano 440 razy\t\t&ndash; 59,16 KB<\/small>\n<\/a>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>P.S.<br>Podobny wpis zosta\u0142 r\u00f3wnie\u017c umieszczony przeze mnie na forum <a href=\"http:\/\/www.microgeek.eu\">microgeek<\/a> \u2013 zach\u0119cam do rejestracji i cz\u0119stych wizyt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Witam. Tym razem chcia\u0142bym si\u0119 z wami podzieli\u0107 wiedz\u0105 dot. dynamicznego tworzenia kontrolek w C#, oraz ich obs\u0142ugi. Opis kolejnych czynno\u015bci (kod\u00f3w w programie) opisywa\u0142 b\u0119d\u0119 &#8222;j\u0119zykiem pocz\u0105tkuj\u0105cego&#8221;, czyli tak jak Ja to rozumiem.Od razu chcia\u0142bym przeprosi\u0107 bardziej zaawansowanych czytelnik\u00f3w&#8230;<br \/><a class=\"read-more-button\" href=\"https:\/\/daniel.slask.pl\/m\/visual-studio-2015-dynamiczne-tworzenie-kontrolek-tworzenie-obsluga-i-objasnienia-jezykiem-poczatkujacego\/\">Wi\u0119cej<\/a><\/p>\n","protected":false},"author":1,"featured_media":373,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,59],"tags":[33,69,65,66,70],"views":4526,"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/daniel.slask.pl\/m\/wp-content\/uploads\/2015\/12\/code-1076533_640.jpg","jetpack_shortlink":"https:\/\/wp.me\/pcPgV3-8r","_links":{"self":[{"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/posts\/523"}],"collection":[{"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/comments?post=523"}],"version-history":[{"count":6,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/posts\/523\/revisions"}],"predecessor-version":[{"id":1641,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/posts\/523\/revisions\/1641"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/media\/373"}],"wp:attachment":[{"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/media?parent=523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/categories?post=523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daniel.slask.pl\/m\/wp-json\/wp\/v2\/tags?post=523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}