Created
October 10, 2011 19:11
-
-
Save subhasisrout/1276226 to your computer and use it in GitHub Desktop.
A XAML markup with custom Textbox Template. Default Textbox template is modified to show validation message on the top rather than on right (which is by default)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<UserControl x:Class="SLValidation.MainPage" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:local="clr-namespace:SLValidation" | |
xmlns:sys="clr-namespace:System;assembly=mscorlib" | |
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" | |
mc:Ignorable="d" | |
d:DesignHeight="300" d:DesignWidth="400"> | |
<UserControl.DataContext> | |
<local:MainPageViewModel /> | |
</UserControl.DataContext> | |
<UserControl.Resources> | |
<ControlTemplate x:Key="ValidationToolTipTemplate"> | |
<!--To move the error message towards right, increase the margin from 5 to say 65 :)--> | |
<!--To move the error message towards top, increase the margin from 0 to say 10 :)--> | |
<Grid x:Name="Root" Margin="5,0" RenderTransformOrigin="0,0" Opacity="0"> | |
<Grid.RenderTransform> | |
<TranslateTransform x:Name="xform" X="-25"/> | |
</Grid.RenderTransform> | |
<vsm:VisualStateManager.VisualStateGroups> | |
<vsm:VisualStateGroup Name="OpenStates"> | |
<vsm:VisualStateGroup.Transitions> | |
<vsm:VisualTransition GeneratedDuration="0"/> | |
<vsm:VisualTransition To="Open" GeneratedDuration="0:0:0.2"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="xform" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2"> | |
<DoubleAnimation.EasingFunction> | |
<BackEase Amplitude=".3" EasingMode="EaseOut"/> | |
</DoubleAnimation.EasingFunction> | |
</DoubleAnimation> | |
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.2"/> | |
</Storyboard> | |
</vsm:VisualTransition> | |
</vsm:VisualStateGroup.Transitions> | |
<vsm:VisualState x:Name="Closed"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0" Duration="0"/> | |
</Storyboard> | |
</vsm:VisualState> | |
<vsm:VisualState x:Name="Open"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="xform" Storyboard.TargetProperty="X" To="0" Duration="0"/> | |
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/> | |
</Storyboard> | |
</vsm:VisualState> | |
</vsm:VisualStateGroup> | |
</vsm:VisualStateManager.VisualStateGroups> | |
<Border Margin="4,4,-4,-4" Background="#052A2E31" CornerRadius="5"/> | |
<Border Margin="3,3,-3,-3" Background="#152A2E31" CornerRadius="4"/> | |
<Border Margin="2,2,-2,-2" Background="#252A2E31" CornerRadius="3"/> | |
<Border Margin="1,1,-1,-1" Background="#352A2E31" CornerRadius="2"/> | |
<Border Background="#FFDC000C" CornerRadius="2"/> | |
<Border CornerRadius="2"> | |
<TextBlock | |
UseLayoutRounding="false" | |
Foreground="White" Margin="8,4,8,4" MaxWidth="250" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}"/> | |
</Border> | |
</Grid> | |
</ControlTemplate> | |
<Style TargetType="TextBox" x:Key="myStyle"> | |
<Setter Property="BorderThickness" Value="1"/> | |
<Setter Property="Background" Value="#FFFFFFFF"/> | |
<Setter Property="Foreground" Value="#FF000000"/> | |
<Setter Property="Padding" Value="2"/> | |
<Setter Property="BorderBrush"> | |
<Setter.Value> | |
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> | |
<GradientStop Color="#FFA3AEB9" Offset="0"/> | |
<GradientStop Color="#FF8399A9" Offset="0.375"/> | |
<GradientStop Color="#FF718597" Offset="0.375"/> | |
<GradientStop Color="#FF617584" Offset="1"/> | |
</LinearGradientBrush> | |
</Setter.Value> | |
</Setter> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="TextBox"> | |
<Grid x:Name="RootElement"> | |
<vsm:VisualStateManager.VisualStateGroups> | |
<vsm:VisualStateGroup x:Name="CommonStates"> | |
<vsm:VisualState x:Name="Normal"/> | |
<vsm:VisualState x:Name="MouseOver"> | |
<Storyboard> | |
<ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="#FF99C1E2" Duration="0"/> | |
</Storyboard> | |
</vsm:VisualState> | |
<vsm:VisualState x:Name="Disabled"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/> | |
</Storyboard> | |
</vsm:VisualState> | |
<vsm:VisualState x:Name="ReadOnly"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="ReadOnlyVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> | |
</Storyboard> | |
</vsm:VisualState> | |
</vsm:VisualStateGroup> | |
<vsm:VisualStateGroup x:Name="FocusStates"> | |
<vsm:VisualState x:Name="Focused"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/> | |
</Storyboard> | |
</vsm:VisualState> | |
<vsm:VisualState x:Name="Unfocused"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="0" Duration="0"/> | |
</Storyboard> | |
</vsm:VisualState> | |
</vsm:VisualStateGroup> | |
<vsm:VisualStateGroup x:Name="ValidationStates"> | |
<vsm:VisualState x:Name="Valid"/> | |
<vsm:VisualState x:Name="InvalidUnfocused"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> | |
<DiscreteObjectKeyFrame KeyTime="0"> | |
<DiscreteObjectKeyFrame.Value> | |
<Visibility>Visible</Visibility> | |
</DiscreteObjectKeyFrame.Value> | |
</DiscreteObjectKeyFrame> | |
</ObjectAnimationUsingKeyFrames> | |
</Storyboard> | |
</vsm:VisualState> | |
<vsm:VisualState x:Name="InvalidFocused"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> | |
<DiscreteObjectKeyFrame KeyTime="0"> | |
<DiscreteObjectKeyFrame.Value> | |
<Visibility>Visible</Visibility> | |
</DiscreteObjectKeyFrame.Value> | |
</DiscreteObjectKeyFrame> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen"> | |
<DiscreteObjectKeyFrame KeyTime="0"> | |
<DiscreteObjectKeyFrame.Value> | |
<sys:Boolean>True</sys:Boolean> | |
</DiscreteObjectKeyFrame.Value> | |
</DiscreteObjectKeyFrame> | |
</ObjectAnimationUsingKeyFrames> | |
</Storyboard> | |
</vsm:VisualState> | |
</vsm:VisualStateGroup> | |
</vsm:VisualStateManager.VisualStateGroups> | |
<Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"> | |
<Grid> | |
<Border x:Name="ReadOnlyVisualElement" Opacity="0" Background="#5EC9C9C9"/> | |
<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent"> | |
<ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False"/> | |
</Border> | |
</Grid> | |
</Border> | |
<Border x:Name="DisabledVisualElement" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" Opacity="0" IsHitTestVisible="False"/> | |
<Border x:Name="FocusVisualElement" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" Margin="1" Opacity="0" IsHitTestVisible="False"/> | |
<Border x:Name="ValidationErrorElement" BorderThickness="1" CornerRadius="1" BorderBrush="#FFDB000C" Visibility="Collapsed"> | |
<ToolTipService.ToolTip> | |
<ToolTip x:Name="validationTooltip" Template="{StaticResource ValidationToolTipTemplate}" Placement="Top" | |
PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" | |
DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"> | |
<ToolTip.Triggers> | |
<EventTrigger RoutedEvent="Canvas.Loaded"> | |
<EventTrigger.Actions> | |
<BeginStoryboard> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible"> | |
<DiscreteObjectKeyFrame KeyTime="0"> | |
<DiscreteObjectKeyFrame.Value> | |
<sys:Boolean>true</sys:Boolean> | |
</DiscreteObjectKeyFrame.Value> | |
</DiscreteObjectKeyFrame> | |
</ObjectAnimationUsingKeyFrames> | |
</Storyboard> | |
</BeginStoryboard> | |
</EventTrigger.Actions> | |
</EventTrigger> | |
</ToolTip.Triggers> | |
</ToolTip> | |
</ToolTipService.ToolTip> | |
<Grid Width="12" Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Background="Transparent"> | |
<Path Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C"/> | |
<Path Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff"/> | |
</Grid> | |
</Border> | |
</Grid> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> | |
</UserControl.Resources> | |
<Grid x:Name="LayoutRoot" Background="White"> | |
<StackPanel Orientation="Vertical"> | |
<TextBlock Height="50"/> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="Name" Width="50" Margin="5,5,5,5" HorizontalAlignment="Left"/> | |
<TextBox Style="{StaticResource myStyle}" Margin="5,5,5,5" HorizontalAlignment="Left" Width="100" Text="{Binding Name,Mode=TwoWay, ValidatesOnExceptions=True,NotifyOnValidationError=True}" /> | |
</StackPanel> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="Age" Width="50" HorizontalAlignment="Left" Margin="5,5,5,5"/> | |
<TextBox Margin="5,5,5,5" HorizontalAlignment="Left" Width="100" Text="{Binding Age,Mode=TwoWay,ValidatesOnExceptions=True,NotifyOnValidationError=True}"/> | |
</StackPanel> | |
</StackPanel> | |
</Grid> | |
</UserControl> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment