{"id":48,"date":"2012-06-09T22:55:00","date_gmt":"2012-06-09T22:55:00","guid":{"rendered":"http:\/\/tpodolak.com.hostingasp.pl\/blog\/2012\/06\/09\/windows-phone-wyswietlanie-bledow-walidacji\/"},"modified":"2016-01-31T00:14:49","modified_gmt":"2016-01-31T00:14:49","slug":"windows-phone-wyswietlanie-bledow-walidacji","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2012\/06\/09\/windows-phone-wyswietlanie-bledow-walidacji\/","title":{"rendered":"Windows Phone &#8211; wy\u015bwietlanie b\u0142\u0119d\u00f3w walidacji"},"content":{"rendered":"<p>Kilka miesi\u0119cy temu w <a href=\"http:\/\/tpodolak.com\/blog\/2011\/11\/28\/walidacja\">tym<\/a> po\u015bcie przedstawia\u0142em r\u00f3\u017cne sposoby walidacji jakie s\u0105 dost\u0119pne na platformie Silverlight. Jako, \u017ce ostatnio mam wi\u0119cej czasu aby pisa\u0107 jakie\u015b proste aplikacje pod Windows Phonem potrzebowa\u0142em mechanizmu walidacji dzia\u0142aj\u0105cego pod t\u0105 platform\u0105. Wed\u0142ug MSDN-u wszystkie metody walidacji przedstawione we wspomnianym wcze\u015bniej po\u015bcie powinny dzia\u0142a\u0107. Niestety po przerzuceniu mechanizmu z Silverlighta na Windows Phona okaza\u0142o si\u0119, \u017ce b\u0142\u0119dy walidacji nie zostaj\u0105 wy\u015bwietlone na interfejsie. Po przeszukaniu kilku for oraz blog\u00f3w dowiedzia\u0142em si\u0119, \u017ce przyczyn\u0105 takiego stanu rzeczy jest brak obs\u0142ugi reakcji na b\u0142\u0119dy w templacie TextBox\u00f3w (i innych element\u00f3w typu input). Zatem aby wy\u015bwietli\u0107 b\u0142\u0119dy walidacji, pozostaje nam zmodyfikowa\u0107 istniej\u0105cy template TextBox-a. Zacznijmy od wyci\u0105gni\u0119cia standardowego templatu TextBox-a z Windows Phona. W tym celu mo\u017cemy u\u017cy\u0107 aplikacji Expression Blend. Otw\u00f3rzmy w niej jakikolwiek projekt typu Windows Phone Application, w kt\u00f3rym na kontrolce mamy naniesionego Textboxa. W moim przypadku, po wczytaniu projektu do Blenda ekran wygl\u0105da w nast\u0119puj\u0105cy spos\u00f3b<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/blend.jpg\" rel=\"attachment wp-att-416\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/blend.jpg\" alt=\"blend\" width=\"500\" class=\"aligncenter size-full wp-image-416\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/blend.jpg 731w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/blend-137x150.jpg 137w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/blend-274x300.jpg 274w\" sizes=\"(max-width: 731px) 100vw, 731px\" \/><\/a><br \/>\nNast\u0119pnie zaznaczamy w Blendzie TextBox-a i z opcji znajduj\u0105cych si\u0119 w lewym g\u00f3rnym rogu aktualnej zak\u0142adki wybieramy TextBox->Edit Template-> Edit Copy.<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/BlendTemplateExtraction.png\" rel=\"attachment wp-att-417\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/BlendTemplateExtraction.png\" alt=\"BlendTemplateExtraction\" width=\"500\" class=\"aligncenter size-full wp-image-417\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/BlendTemplateExtraction.png 469w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/BlendTemplateExtraction-150x45.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/BlendTemplateExtraction-300x90.png 300w\" sizes=\"(max-width: 469px) 100vw, 469px\" \/><\/a><br \/>\nW oknie, kt\u00f3re si\u0119 pojawi klikamy OK. Nast\u0119pnie mo\u017cemy przej\u015b\u0107 do widoku XAML-a, w sekcji phone:PhoneApplicationPage.Resources powinien pojawi\u0107 si\u0119 nam nowy styl wygl\u0105daj\u0105cy w ten spos\u00f3b<\/p>\n<pre lang=\"xml\">\r\n<ControlTemplate x:Key=\"PhoneDisabledTextBoxTemplate\" TargetType=\"TextBox\">\r\n   <ContentControl x:Name=\"ContentElement\" BorderThickness=\"0\" HorizontalContentAlignment=\"Stretch\" Margin=\"{StaticResource PhoneTextBoxInnerMargin}\" Padding=\"{TemplateBinding Padding}\" VerticalContentAlignment=\"Stretch\"\/>\r\n   <\/ControlTemplate>\r\n   <Style x:Key=\"TextBoxStyle1\" TargetType=\"TextBox\">\r\n      <Setter Property=\"FontFamily\" Value=\"{StaticResource PhoneFontFamilyNormal}\"\/>\r\n      <Setter Property=\"FontSize\" Value=\"{StaticResource PhoneFontSizeMediumLarge}\"\/>\r\n      <Setter Property=\"Background\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n      <Setter Property=\"Foreground\" Value=\"{StaticResource PhoneTextBoxForegroundBrush}\"\/>\r\n      <Setter Property=\"BorderBrush\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n      <Setter Property=\"SelectionBackground\" Value=\"{StaticResource PhoneAccentBrush}\"\/>\r\n      <Setter Property=\"SelectionForeground\" Value=\"{StaticResource PhoneTextBoxSelectionForegroundBrush}\"\/>\r\n      <Setter Property=\"BorderThickness\" Value=\"{StaticResource PhoneBorderThickness}\"\/>\r\n      <Setter Property=\"Padding\" Value=\"2\"\/>\r\n      <Setter Property=\"Template\">\r\n       <Setter.Value>\r\n        <ControlTemplate TargetType=\"TextBox\">\r\n         <Grid Background=\"Transparent\">\r\n          <VisualStateManager.VisualStateGroups>\r\n           <VisualStateGroup x:Name=\"CommonStates\">\r\n            <VisualState x:Name=\"Normal\"\/>\r\n            <VisualState x:Name=\"MouseOver\"\/>\r\n            <VisualState x:Name=\"Disabled\">\r\n             <Storyboard>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"EnabledBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                <DiscreteObjectKeyFrame.Value>\r\n                 <Visibility>Collapsed<\/Visibility>\r\n                <\/DiscreteObjectKeyFrame.Value>\r\n               <\/DiscreteObjectKeyFrame>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                <DiscreteObjectKeyFrame.Value>\r\n                 <Visibility>Visible<\/Visibility>\r\n                <\/DiscreteObjectKeyFrame.Value>\r\n               <\/DiscreteObjectKeyFrame>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n             <\/Storyboard>\r\n            <\/VisualState>\r\n            <VisualState x:Name=\"ReadOnly\">\r\n             <Storyboard>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"EnabledBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                <DiscreteObjectKeyFrame.Value>\r\n                 <Visibility>Collapsed<\/Visibility>\r\n                <\/DiscreteObjectKeyFrame.Value>\r\n               <\/DiscreteObjectKeyFrame>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                <DiscreteObjectKeyFrame.Value>\r\n                 <Visibility>Visible<\/Visibility>\r\n                <\/DiscreteObjectKeyFrame.Value>\r\n               <\/DiscreteObjectKeyFrame>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Background\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"BorderBrush\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Foreground\" Storyboard.TargetName=\"DisabledOrReadonlyContent\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxReadOnlyBrush}\"\/>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n             <\/Storyboard>\r\n            <\/VisualState>\r\n           <\/VisualStateGroup>\r\n           <VisualStateGroup x:Name=\"FocusStates\">\r\n            <VisualState x:Name=\"Focused\">\r\n             <Storyboard>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Background\" Storyboard.TargetName=\"EnabledBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxEditBackgroundBrush}\"\/>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"BorderBrush\" Storyboard.TargetName=\"EnabledBorder\">\r\n               <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxEditBorderBrush}\"\/>\r\n              <\/ObjectAnimationUsingKeyFrames>\r\n             <\/Storyboard>\r\n            <\/VisualState>\r\n            <VisualState x:Name=\"Unfocused\"\/>\r\n           <\/VisualStateGroup>\r\n          <\/VisualStateManager.VisualStateGroups>\r\n          <Border x:Name=\"EnabledBorder\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Margin=\"{StaticResource PhoneTouchTargetOverhang}\">\r\n           <ContentControl x:Name=\"ContentElement\" BorderThickness=\"0\" HorizontalContentAlignment=\"Stretch\" Margin=\"{StaticResource PhoneTextBoxInnerMargin}\" Padding=\"{TemplateBinding Padding}\" VerticalContentAlignment=\"Stretch\"\/>\r\n          <\/Border>\r\n          <Border x:Name=\"DisabledOrReadonlyBorder\" BorderBrush=\"{StaticResource PhoneDisabledBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"Transparent\" Margin=\"{StaticResource PhoneTouchTargetOverhang}\" Visibility=\"Collapsed\">\r\n           <TextBox x:Name=\"DisabledOrReadonlyContent\" Background=\"Transparent\" Foreground=\"{StaticResource PhoneDisabledBrush}\" FontWeight=\"{TemplateBinding FontWeight}\" FontStyle=\"{TemplateBinding FontStyle}\" FontSize=\"{TemplateBinding FontSize}\" FontFamily=\"{TemplateBinding FontFamily}\" IsReadOnly=\"True\" SelectionForeground=\"{TemplateBinding SelectionForeground}\" SelectionBackground=\"{TemplateBinding SelectionBackground}\" TextAlignment=\"{TemplateBinding TextAlignment}\" TextWrapping=\"{TemplateBinding TextWrapping}\" Text=\"{TemplateBinding Text}\" Template=\"{StaticResource PhoneDisabledTextBoxTemplate}\"\/>\r\n          <\/Border>\r\n         <\/Grid>\r\n        <\/ControlTemplate>\r\n       <\/Setter.Value>\r\n      <\/Setter>\r\n   <\/Style>\r\n<\/ControlTemplate>\r\n<\/pre>\n<p>W ten oto spos\u00f3b uda\u0142o nam si\u0119 wydoby\u0107 domy\u015blny styl oraz template TextBoxa w Windows Phonie. W kolejnym kroku musimy zmodyfikowa\u0107 ten template w taki spos\u00f3b, aby zacz\u0105\u0142 reagowa\u0107 na zmiany stanu walidacji. Zacznijmy od sprawdzenia jakie stany wizualne mo\u017ce obs\u0142ugiwa\u0107 TextBox. W tym celu musimy przegl\u0105dn\u0105\u0107 metadane TextBoxa &#8211; mo\u017cemy to zrobi\u0107 klikaj\u0105c PPM na klasie TextBox-a i wybieraj\u0105c Go To Definition. Naszym oczom powinno ukaza\u0107 si\u0119 co\u015b takiego.<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/validationstates.png\" rel=\"attachment wp-att-420\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/validationstates.png\" alt=\"validationstates\" width=\"500\" class=\"aligncenter size-full wp-image-420\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/validationstates.png 467w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/validationstates-150x83.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/validationstates-300x165.png 300w\" sizes=\"(max-width: 467px) 100vw, 467px\" \/><\/a><br \/>\nWidzimy, \u017ce klasa TextBox jest opatrzona atrybutami TemplateVisualState, nas interesuj\u0105 najbardziej trzy z tych atrybut\u00f3w:<\/p>\n<ul>\n<li>[TemplateVisualState(GroupName = &#8220;ValidationStates&#8221;, Name = &#8220;Valid&#8221;)]<\/li>\n<li>[TemplateVisualState(GroupName = &#8220;ValidationStates&#8221;, Name = &#8220;InvalidFocused&#8221;)]<\/li>\n<li>[TemplateVisualState(GroupName = &#8220;ValidationStates&#8221;, Name = &#8220;InvalidUnfocused&#8221;)]<\/li>\n<\/ul>\n<p>M\u00f3wi\u0105 nam one, \u017ce w przypadku gdy wyst\u0105pi\u0105 b\u0142\u0119dy walidacji nasza kontrolka przechodzi w stan InvalidFocused lub InvalidUnfocused. Natomiast, w przypadku gdy nie ma b\u0142\u0119d\u00f3w znajduje si\u0119 ona w stanie Valid. Analizuj\u0105c kod domy\u015blnego templatu TextBoxa widzimy, \u017ce stany z grupy ValidationStates nie s\u0105 obs\u0142ugiwane &#8211; czas zatem to zmieni\u0107. Po pierwsze do templatu musimy dorzuci\u0107 elementy, kt\u00f3re b\u0119d\u0105 wy\u015bwietla\u0142y b\u0142\u0119dy walidacji. Zmie\u0144my zatem opakowuj\u0105cy wszystko element Grid na StackPanel, a nast\u0119pnie dodajmy element typu TextBlock oraz Border. Elementy wy\u015bwietlaj\u0105ce b\u0142\u0119dy walidacji musimy umie\u015bci\u0107 w jednym kontenerze z elementami odpowiadaj\u0105cymi za wy\u015bwietlanie tekstu. Zatem musimy je opakowa\u0107 w Grida. Po zastosowaniu powy\u017cszych wskaz\u00f3wek nasz template b\u0119dzie wygl\u0105da\u0142 w nast\u0119puj\u0105cy spos\u00f3b<\/p>\n<pre lang=\"xml\">\r\n<StackPanel>\r\n...\r\n...\r\n...\r\n    <Grid>\r\n       <Grid.RowDefinitions>\r\n           <RowDefinition Height=\"Auto\"><\/RowDefinition>\r\n           <RowDefinition Height=\"Auto\"><\/RowDefinition>\r\n       <\/Grid.RowDefinitions>\r\n       <Border x:Name=\"EnabledBorder\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Margin=\"{StaticResource PhoneTouchTargetOverhang}\">\r\n             <ContentControl x:Name=\"ContentElement\" BorderThickness=\"0\" HorizontalContentAlignment=\"Stretch\"   Padding=\"{TemplateBinding Padding}\" VerticalContentAlignment=\"Stretch\"\/>\r\n       <\/Border>\r\n       <Border x:Name=\"DisabledOrReadonlyBorder\" BorderBrush=\"{StaticResource PhoneDisabledBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"Transparent\" Margin=\"{StaticResource PhoneTouchTargetOverhang}\" Visibility=\"Collapsed\">\r\n          <TextBox x:Name=\"DisabledOrReadonlyContent\" Background=\"Transparent\" Foreground=\"{StaticResource PhoneDisabledBrush}\" FontWeight=\"{TemplateBinding FontWeight}\" FontStyle=\"{TemplateBinding FontStyle}\" FontSize=\"{TemplateBinding FontSize}\" FontFamily=\"{TemplateBinding FontFamily}\" IsReadOnly=\"True\" SelectionForeground=\"{TemplateBinding SelectionForeground}\" SelectionBackground=\"{TemplateBinding SelectionBackground}\" TextAlignment=\"{TemplateBinding TextAlignment}\" TextWrapping=\"{TemplateBinding TextWrapping}\" Text=\"{TemplateBinding Text}\" Template=\"{StaticResource PhoneDisabledTextBoxTemplate}\"\/>\r\n       <\/Border>\r\n       <Border x:Name=\"ValidationBorder\" Grid.RowSpan=\"2\" BorderBrush=\"Red\" BorderThickness=\"2\" Visibility=\"Collapsed\"  >\r\n       <\/Border>\r\n       <TextBlock x:Name=\"ValidationMessage\" Foreground=\"Red\" FontSize=\"16\" Visibility=\"Collapsed\" Grid.Row=\"1\" Text=\"{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}\"  Padding=\"0,0,0,2\" Margin=\"10,-14,0,0\"  \/>\r\n    <\/Grid>\r\n<\/StackPanel>\r\n<\/pre>\n<p>Dodanie element\u00f3w wy\u015bwietlaj\u0105cych b\u0142\u0119dy to nie wszystko, musimy jeszcze okre\u015bli\u0107 kiedy nasze elementy maj\u0105 by\u0107 widoczne. W chwili obecnej ich w\u0142a\u015bciwo\u015b\u0107 Visibility jest ustawiona na Collapsed. Zatem elementy te nie b\u0119d\u0105 widoczne, jak r\u00f3wnie\u017c nie b\u0119d\u0105 zajmowa\u0142y miejsca na interfejsie. Jak ju\u017c wcze\u015bniej wspomnia\u0142em kontrolka TextBoxa w przypadku wyst\u0105pienia b\u0142\u0119d\u00f3w walidacji przejdzie do stan\u00f3w InvalidFocused lub InvalidUnfocused. Pozostaje nam zatem zareagowa\u0107 na przej\u015bcie kontrolki w te stany i odpowiednio zmodyfikowa\u0107 w\u0142a\u015bciwo\u015b\u0107 Visibility bordera oraz textblocka. W tym celu pos\u0142u\u017cymy si\u0119 VisualStateManagerem oraz animacjami. Do naszego templatu dodajmy nast\u0119puj\u0105cy wpis<\/p>\n<pre lang=\"xml\">\r\n<VisualStateGroup x:Name=\"ValidationStates\">\r\n                                <VisualState x:Name=\"Valid\" >\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Collapsed\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationMessage\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Collapsed\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                                <VisualState x:Name=\"InvalidFocused\" >\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationMessage\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                                <VisualState x:Name=\"InvalidUnfocused\" >\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationMessage\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n<\/VisualStateGroup>\r\n<\/pre>\n<p>W ten oto spos\u00f3b zdefiniwali\u015bmy w XAML-u grup\u0119 (VisualStateGroup ) o nazwie ValidationStates &#8211; zauwa\u017cmy, \u017ce nazwa grupy jest taka sama jak nazwa grupy z atrybut\u00f3w klasy TextBox. Dodali\u015bmy r\u00f3wnie\u017c trzy stany wizualne (VisualState), kt\u00f3rych nazwy r\u00f3wnie\u017c odpowiadaj\u0105 nazw\u0105 zdefiniowanym w atrubytach klasy TextBox. Od tej chwili gdy kontrolka TextBoxa b\u0119dzie posiada\u0142a b\u0142\u0119dy walidacji, zostanie odpalona animacja zmieniaj\u0105ca w\u0142a\u015bciwo\u015b\u0107 Visibility bordera &#8220;ValidationBorder&#8221; oraz TextBlocka &#8220;ValidationMessage&#8221; na Visible. Ostatecznie ca\u0142y gotowy template b\u0119dzie wygl\u0105da\u0142 w nast\u0119puj\u0105cy spos\u00f3b<\/p>\n<pre lang=\"xml\">\r\n<ControlTemplate x:Key=\"PhoneDisabledTextBoxTemplate\" TargetType=\"TextBox\">\r\n    <ContentControl x:Name=\"ContentElement\" BorderThickness=\"0\" HorizontalContentAlignment=\"Stretch\" Margin=\"{StaticResource PhoneTextBoxInnerMargin}\" Padding=\"{TemplateBinding Padding}\" VerticalContentAlignment=\"Stretch\"\/>\r\n    <\/ControlTemplate>\r\n    <Style TargetType=\"TextBox\">\r\n        <Setter Property=\"FontFamily\" Value=\"{StaticResource PhoneFontFamilyNormal}\"\/>\r\n        <Setter Property=\"FontSize\" Value=\"{StaticResource PhoneFontSizeMediumLarge}\"\/>\r\n        <Setter Property=\"Background\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n        <Setter Property=\"Foreground\" Value=\"{StaticResource PhoneTextBoxForegroundBrush}\"\/>\r\n        <Setter Property=\"BorderBrush\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n        <Setter Property=\"SelectionBackground\" Value=\"{StaticResource PhoneAccentBrush}\"\/>\r\n        <Setter Property=\"SelectionForeground\" Value=\"{StaticResource PhoneTextBoxSelectionForegroundBrush}\"\/>\r\n        <Setter Property=\"BorderThickness\" Value=\"{StaticResource PhoneBorderThickness}\"\/>\r\n        <Setter Property=\"Padding\" Value=\"2\"\/>\r\n        <Setter Property=\"Template\">\r\n            <Setter.Value>\r\n                <ControlTemplate TargetType=\"TextBox\">\r\n                    <StackPanel Background=\"Transparent\">\r\n                        <VisualStateManager.VisualStateGroups>\r\n                            <VisualStateGroup x:Name=\"CommonStates\">\r\n                                <VisualState x:Name=\"Normal\"\/>\r\n                                <VisualState x:Name=\"MouseOver\"\/>\r\n                                <VisualState x:Name=\"Disabled\">\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"EnabledBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                                                <DiscreteObjectKeyFrame.Value>\r\n                                                    <Visibility>Collapsed<\/Visibility>\r\n                                                <\/DiscreteObjectKeyFrame.Value>\r\n                                            <\/DiscreteObjectKeyFrame>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                                                <DiscreteObjectKeyFrame.Value>\r\n                                                    <Visibility>Visible<\/Visibility>\r\n                                                <\/DiscreteObjectKeyFrame.Value>\r\n                                            <\/DiscreteObjectKeyFrame>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                                <VisualState x:Name=\"ReadOnly\">\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"EnabledBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                                                <DiscreteObjectKeyFrame.Value>\r\n                                                    <Visibility>Collapsed<\/Visibility>\r\n                                                <\/DiscreteObjectKeyFrame.Value>\r\n                                            <\/DiscreteObjectKeyFrame>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\">\r\n                                                <DiscreteObjectKeyFrame.Value>\r\n                                                    <Visibility>Visible<\/Visibility>\r\n                                                <\/DiscreteObjectKeyFrame.Value>\r\n                                            <\/DiscreteObjectKeyFrame>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Background\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"BorderBrush\" Storyboard.TargetName=\"DisabledOrReadonlyBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxBrush}\"\/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Foreground\" Storyboard.TargetName=\"DisabledOrReadonlyContent\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxReadOnlyBrush}\"\/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                            <\/VisualStateGroup>\r\n                            <VisualStateGroup x:Name=\"FocusStates\">\r\n                                <VisualState x:Name=\"Focused\">\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Background\" Storyboard.TargetName=\"EnabledBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxEditBackgroundBrush}\"\/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"BorderBrush\" Storyboard.TargetName=\"EnabledBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"{StaticResource PhoneTextBoxEditBorderBrush}\"\/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                                <VisualState x:Name=\"Unfocused\"\/>\r\n                            <\/VisualStateGroup>\r\n                            <VisualStateGroup x:Name=\"ValidationStates\">\r\n                                <VisualState x:Name=\"Valid\" >\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Collapsed\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationMessage\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Collapsed\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                                <VisualState x:Name=\"InvalidFocused\" >\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationMessage\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                                <VisualState x:Name=\"InvalidUnfocused\" >\r\n                                    <Storyboard>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationBorder\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\" Storyboard.TargetName=\"ValidationMessage\">\r\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\" Value=\"Visible\" \/>\r\n                                        <\/ObjectAnimationUsingKeyFrames>\r\n                                    <\/Storyboard>\r\n                                <\/VisualState>\r\n                            <\/VisualStateGroup>\r\n                        <\/VisualStateManager.VisualStateGroups>\r\n                        <Grid>\r\n                            <Grid.RowDefinitions>\r\n                                <RowDefinition Height=\"Auto\"><\/RowDefinition>\r\n                                <RowDefinition Height=\"Auto\"><\/RowDefinition>\r\n                            <\/Grid.RowDefinitions>\r\n                            <Border x:Name=\"EnabledBorder\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Margin=\"{StaticResource PhoneTouchTargetOverhang}\">\r\n                                <ContentControl x:Name=\"ContentElement\" BorderThickness=\"0\" HorizontalContentAlignment=\"Stretch\"   Padding=\"{TemplateBinding Padding}\" VerticalContentAlignment=\"Stretch\"\/>\r\n                            <\/Border>\r\n                            <Border x:Name=\"DisabledOrReadonlyBorder\" BorderBrush=\"{StaticResource PhoneDisabledBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"Transparent\" Margin=\"{StaticResource PhoneTouchTargetOverhang}\" Visibility=\"Collapsed\">\r\n                                <TextBox x:Name=\"DisabledOrReadonlyContent\" Background=\"Transparent\" Foreground=\"{StaticResource PhoneDisabledBrush}\" FontWeight=\"{TemplateBinding FontWeight}\" FontStyle=\"{TemplateBinding FontStyle}\" FontSize=\"{TemplateBinding FontSize}\" FontFamily=\"{TemplateBinding FontFamily}\" IsReadOnly=\"True\" SelectionForeground=\"{TemplateBinding SelectionForeground}\" SelectionBackground=\"{TemplateBinding SelectionBackground}\" TextAlignment=\"{TemplateBinding TextAlignment}\" TextWrapping=\"{TemplateBinding TextWrapping}\" Text=\"{TemplateBinding Text}\" Template=\"{StaticResource PhoneDisabledTextBoxTemplate}\"\/>\r\n                            <\/Border>\r\n                            <Border x:Name=\"ValidationBorder\" Grid.RowSpan=\"2\" BorderBrush=\"Red\" BorderThickness=\"2\" Visibility=\"Collapsed\"  >\r\n                            <\/Border>\r\n                            <TextBlock x:Name=\"ValidationMessage\" Foreground=\"Red\" FontSize=\"16\" Visibility=\"Collapsed\" Grid.Row=\"1\" Text=\"{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}\"  Padding=\"0,0,0,2\" Margin=\"10,-14,0,0\"  \/>\r\n\r\n                        <\/Grid>\r\n\r\n                    <\/StackPanel>\r\n                <\/ControlTemplate>\r\n            <\/Setter.Value>\r\n        <\/Setter>\r\n    <\/Style>\r\n<\/ControlTemplate>\r\n<\/pre>\n<p>Tak natomiast przedstawiaj\u0105 si\u0119 b\u0142\u0119dy walidacji wy\u015bwietlone na TextBoxach<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/result.jpg\" rel=\"attachment wp-att-418\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/result.jpg\" alt=\"wy\u015bwietlanie b\u0142\u0119d\u00f3w walidacji\" width=\"425\" class=\"aligncenter size-full wp-image-418\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/result.jpg 425w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/result-80x150.jpg 80w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/06\/windows-phone-wyswietlanie-bledow-walidacji\/result-159x300.jpg 159w\" sizes=\"(max-width: 425px) 100vw, 425px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kilka miesi\u0119cy temu w tym po\u015bcie przedstawia\u0142em r\u00f3\u017cne sposoby walidacji jakie s\u0105 dost\u0119pne na platformie Silverlight. Jako, \u017ce ostatnio mam wi\u0119cej czasu aby pisa\u0107 jakie\u015b proste aplikacje pod Windows Phonem potrzebowa\u0142em mechanizmu walidacji dzia\u0142aj\u0105cego pod t\u0105 platform\u0105. Wed\u0142ug MSDN-u wszystkie metody walidacji przedstawione we wspomnianym wcze\u015bniej po\u015bcie powinny dzia\u0142a\u0107. Niestety po przerzuceniu mechanizmu z Silverlighta [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[107,84,108,30],"tags":[242,229,243,240,244],"class_list":["post-48","post","type-post","status-publish","format-standard","hentry","category-datatemplate","category-validation","category-walidacja","category-windows-phone","tag-datatemplate","tag-validation","tag-walidacja","tag-windows-phone","tag-wp7"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/48","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=48"}],"version-history":[{"count":5,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/48\/revisions"}],"predecessor-version":[{"id":554,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/48\/revisions\/554"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=48"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=48"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}