{"id":1054,"date":"2017-03-12T21:35:41","date_gmt":"2017-03-12T20:35:41","guid":{"rendered":"http:\/\/piatkosia.k4be.pl\/wordpress\/?p=1054"},"modified":"2017-03-12T21:45:54","modified_gmt":"2017-03-12T20:45:54","slug":"wszystko-pod-kontrolka","status":"publish","type":"post","link":"https:\/\/piatkosia.k4be.pl\/wordpress\/2017\/03\/12\/wszystko-pod-kontrolka\/","title":{"rendered":"Wszystko pod kontrolk\u0105"},"content":{"rendered":"<p style=\"text-align: justify;\">Dobra, dzi\u015b w ramach konkursu \u201eDaj si\u0119 pozna\u0107\u201d poka\u017c\u0119, jak zrobi\u0107 zajebist\u0105 kontrolk\u0119, w pe\u0142ni responsywn\u0105 z nasz\u0105 aplikacj\u0105.<\/p>\n<p style=\"text-align: justify;\">Kontrolka jest kawa\u0142kiem interfejsu graficznego, kt\u00f3ry upraszcza nam projektowanie tego\u017c. Raz napisana przez kogo\u015b (na przyk\u0142ad przez nas) mo\u017ce by\u0107 u\u017cyta wiele razy w r\u00f3\u017cnych oknach. Najpro\u015bciej jest z\u0142o\u017cy\u0107 kontrolk\u0119 z kilku innych kontrolek i dokona\u0107 na nich pewn\u0105 akcj\u0119.<br \/>\n<!--more--><br \/>\nW wielu miejscach jest sytuacja, \u017ce mamy jaki\u015b ci\u0105g kontrolek kt\u00f3re wyst\u0119puj\u0105 ko\u0142o siebie. I tak powstaje \u201ekandydat na kontrolk\u0119. Z\u0142owi\u0142am takiego tak\u017ce u siebie, i to ju\u017c w jednym oknie:<br \/>\n<a href=\"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-content\/uploads\/2017\/03\/kawalek_okienka.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1055\" src=\"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-content\/uploads\/2017\/03\/kawalek_okienka.png\" alt=\"\" width=\"924\" height=\"179\" srcset=\"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-content\/uploads\/2017\/03\/kawalek_okienka.png 924w, https:\/\/piatkosia.k4be.pl\/wordpress\/wp-content\/uploads\/2017\/03\/kawalek_okienka-300x58.png 300w, https:\/\/piatkosia.k4be.pl\/wordpress\/wp-content\/uploads\/2017\/03\/kawalek_okienka-768x149.png 768w\" sizes=\"auto, (max-width: 924px) 100vw, 924px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Zasada DRY m\u00f3wi o tym, aby si\u0119 nie powtarza\u0107. Dlatego powtarzaj\u0105ce si\u0119 kawa\u0142ki kodu \u0142adujemy do funkcji, za\u015b powtarzaj\u0105ce si\u0119 kawa\u0142ki interfejsu \u0142adujemy do kontrolek.<\/p>\n<p style=\"text-align: justify;\">Czego na pocz\u0105tku od niej wymagamy? Mamy sobie textblock i textbox, kt\u00f3rego rozmiary maj\u0105 mie\u0107 mo\u017cliwo\u015b\u0107 dostosowania si\u0119 do miejsca jakie mu damy. Chcemy te\u017c mie\u0107 mo\u017cliwo\u015b\u0107 ustawienia tekstu w opisie bezpo\u015brednio z poziomu xaml oraz chcemy by\u0107 informowani o zmianie tekstu w textboxie. Chcemy tak\u017ce, aby dzia\u0142a\u0142 podgl\u0105d w visual studio i tyle. Starczy.<\/p>\n<p style=\"text-align: justify;\">Przyk\u0142adowe u\u017cycie w oknie ma si\u0119 przedstawia\u0107 nast\u0119puj\u0105co:<\/p>\n<pre class=\"brush: xml; collapse: false\"> <local:DescTextBox Margin=\"5\" Input=\"Nazwa zak\u0142adu\"  Grid.Row=\"0\" Grid.Column=\"0\" OutputChanged=\"DescTextBox_OutputChanged\"\/><\/pre>\n<p>Zacznijmy od pliku .xaml dla kontrolki:<\/p>\n<pre class=\"brush: xml; collapse: false\">\r\n&lt;UserControl x:Class=\"bezpieczniejsi.DescTextBox\"\r\n             xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\r\n             xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\r\n             xmlns:mc=\"http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006\" \r\n             xmlns:d=\"http:\/\/schemas.microsoft.com\/expression\/blend\/2008\" \r\n             xmlns:local=\"clr-namespace:bezpieczniejsi\"\r\n             mc:Ignorable=\"d\" \r\n           &gt;\r\n    &lt;Grid&gt;\r\n        &lt;Grid.ColumnDefinitions&gt;\r\n            &lt;ColumnDefinition Width=\"*\"\/&gt;\r\n            &lt;ColumnDefinition Width=\"*\"\/&gt;\r\n        &lt;\/Grid.ColumnDefinitions&gt;\r\n        &lt;TextBlock x:Name=\"InputBox\" TextWrapping=\"Wrap\" Text=\"\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" \/&gt;\r\n        &lt;TextBox x:Name=\"OutputBox\" Grid.Column=\"1\" TextWrapping=\"Wrap\" Text=\"\" HorizontalAlignment=\"Stretch\" VerticalAlignment=\"Stretch\" HorizontalContentAlignment=\"Center\" VerticalContentAlignment=\"Center\" TextChanged=\"OutputBox_TextChanged\" GotFocus=\"OutputBox_GotFocus\"\/&gt;\r\n    &lt;\/Grid&gt;\r\n<\/pre>\n<p>Prosz\u0119 zauwa\u017cy\u0107, \u017ce linijka d:DesignHeight=&#8221;300&#8243; d:DesignWidth=&#8221;300&#8243; z g\u00f3ry zosta\u0142a celowo usuni\u0119ta, aby\u015bmy uzyskali rzeczywisty podgl\u0105d.<\/p>\n<p>Kod .cs kontrolki wygl\u0105da nast\u0119puj\u0105co:<\/p>\n<pre class=\"brush: csharp; collapse: true\">\r\n public partial class DescTextBox : UserControl\r\n    {\r\n       \r\n        public DescTextBox()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n\r\n\r\n        public string Input\r\n        {\r\n            get { return (string)GetValue(InputProperty); }\r\n            set\r\n            {\r\n                SetValue(InputProperty, value);\r\n                InputBox.Text = value;\r\n            }\r\n        }\r\n\r\n        public static readonly DependencyProperty InputProperty =\r\n            DependencyProperty.Register(\"Input\", typeof(string), typeof(DescTextBox), new PropertyMetadata(string.Empty, InputValueChanged));\r\n\r\n        private static void InputValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\r\n        {\r\n            var control = d as DescTextBox;\r\n            if (control == null) return;\r\n            control.InputBox.Text = e.NewValue.ToString();\r\n        }\r\n        public delegate void OutputEventHandler(object sender, StringChangedEventArgs args);\r\n        StringChangedEventArgs args = new StringChangedEventArgs();\r\n        public event OutputEventHandler OutputChanged;\r\n        string _previousText = string.Empty;\r\n        private void OutputBox_TextChanged(object sender, TextChangedEventArgs e)\r\n        {\r\n            args.NewValue = OutputBox.Text;\r\n            args.OldValue = _previousText;\r\n            OutputChanged?.Invoke(this, args);\r\n        }\r\n\r\n        private void OutputBox_GotFocus(object sender, RoutedEventArgs e)\r\n        {\r\n            _previousText = OutputBox.Text;\r\n        }\r\n    }\r\n<\/pre>\n<p style=\"text-align: justify;\">Aby m\u00f3c mie\u0107 dost\u0119p z xaml u\u017cyto mechanizmu DependencyProperty (jak nie wiesz jak r\u0119cznie ogarn\u0105\u0107- wpisz propd i wci\u015bnij tab 2 razy), za\u015b zmiana tekstu jest realizowana jako event zdefiniowany przez u\u017cytkownika. Mo\u017cna albo przez xamla poda\u0107 nazw\u0119 funkcji, albo przez += z poziomu kodu.<\/p>\n<p>Kontrolka dzia\u0142a, co mo\u017cna zobaczy\u0107 otwieraj\u0105c ThreeGrade.xaml dost\u0119pnego gdzie\u015b w projekcie umieszczonym na <a href=\"https:\/\/github.com\/Piatkosia\/bezpieczniejsi\">https:\/\/github.com\/Piatkosia\/bezpieczniejsi<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dobra, dzi\u015b w ramach konkursu \u201eDaj si\u0119 pozna\u0107\u201d poka\u017c\u0119, jak zrobi\u0107 zajebist\u0105 kontrolk\u0119, w pe\u0142ni responsywn\u0105 z nasz\u0105 aplikacj\u0105. Kontrolka jest kawa\u0142kiem interfejsu graficznego, kt\u00f3ry<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/piatkosia.k4be.pl\/wordpress\/2017\/03\/12\/wszystko-pod-kontrolka\/\">Lecim dalej<span class=\"screen-reader-text\">Wszystko pod kontrolk\u0105<\/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":[240,268,239],"tags":[272,273,271,242],"class_list":["post-1054","post","type-post","status-publish","format-standard","hentry","category-dajsiepoznac","category-dsp2017","category-konkursy","tag-dependency-property","tag-events","tag-usercontrols","tag-wpf","entry"],"_links":{"self":[{"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts\/1054","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=1054"}],"version-history":[{"count":7,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts\/1054\/revisions"}],"predecessor-version":[{"id":1062,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/posts\/1054\/revisions\/1062"}],"wp:attachment":[{"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/media?parent=1054"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/categories?post=1054"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/piatkosia.k4be.pl\/wordpress\/wp-json\/wp\/v2\/tags?post=1054"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}