Sunday, August 15, 2010

How to use Cross Referencing Functoids in Biztalk

Technorati Tags: ,

From Silverlight development to Biztalk development, things have changed pretty soon.

Scenario

We are integrating two applications, where a particular field of the source maps to another field in destination. But their values aren’t so agreeable, for example, say we have a field called OrderStatus in Application1 which maps to a field named OrderStatus in Application2, but the list of possible values are different.

Field

Application1

Application2

OrderStatus 1 Delivered
OrderStatus 2 Pending

Table 1

How do you go about mapping them? Apparently there are a number of ways to solve the problem as briefly explained by Michael Stephenson. The pattern that was suggested to me was to use Cross Referencing Functions. Michael Stephenson’s post explains the underlying concept well, but it falls short of providing a complete example. The MSDN page stops at how to import data for cross reference functoids. What I needed was a simple example as to how to use it. So I decided to do one myself.

Solution

Lets take the above problem and solve it.

First we need to have all the data needed (as per Table 1) in our database. For this purpose we will set up the following xml files.

listOfAppType.xml

Contains a types of the applications.

<?xml version="1.0" encoding="utf-8"?>
<
listOfAppType>
<
appType>
<
name>Application1</name>
<
description/>
</
appType>
<
appType>
<
name>Application2</name>
<
description/>
</
appType>
</
listOfAppType>


listOfAppInstance.xml

Contains the instance names of the applications
<?xml version="1.0" encoding="UTF-8"?>
<
listOfAppInstance>
<
appInstance>
<
instance>Application1Instance</instance>
<
type>Application1</type>
<
description/>
</
appInstance>
<
appInstance>
<
instance>Application2Instance</instance>
<
type>Application2</type>
<
description/>
</
appInstance>
</
listOfAppInstance>


listOfIDXRef.xml

Contains the list of fields to be stored for mapping.
<?xml version="1.0" encoding="UTF-8"?>
<
listOfIDXRef>
<
idXRef>
<
name>OrderStatus</name>
<
description>Status of the order</description>
</
idXRef>
</
listOfIDXRef>


listOfIDXRefData.xml

Contains the values of the fields in each application and the common values used to refer to them.
<?xml version="1.0" encoding="UTF-8"?>
<
listOfIDXRefData>
<
idXRef name="OrderStatus">
<
appInstance name="Application1Instance">
<
appID commonID="D">1</appID>
<
appID commonID="P">2</appID>
</
appInstance>
<
appInstance name="Application2Instance">
<
appID commonID="D">Delivered</appID>
<
appID commonID="P">Pending</appID>
</
appInstance>
</
idXRef>
</
listOfIDXRefData>


SetupFiles.xml

A setup file containing the paths to all these xmls
<?xml version="1.0" encoding="UTF-8"?>
<
Setup-Files>
<
App_Type_file>G:\Microsoft\Biztalk\Biztalk Server Examples\CrossReferenceFunctoids\listOfAppType.xml</App_Type_file>
<
App_Instance_file>G:\Microsoft\Biztalk\Biztalk Server Examples\CrossReferenceFunctoids\listOfAppInstance.xml</App_Instance_file>
<
IDXRef_file>G:\Microsoft\Biztalk\Biztalk Server Examples\CrossReferenceFunctoids\listOfIDXRef.xml</IDXRef_file>
<
IDXRef_Data_file>G:\Microsoft\Biztalk\Biztalk Server Examples\CrossReferenceFunctoids\listOfIDXRefData.xml</IDXRef_Data_file>
</
Setup-Files>
Now lets put them into the database. For this will will use the BTSXRefImport tool found in the biztalk directory. Use the following command to do this.

Command[1]

Lets do the mapping part. Drag and drop the Get Common ID functoid and configure its input as follows:

GetCommonIDIP[1]


The first Input being the name of the common field, the second the name of the application instance and the third being the value for the application

Then drag and drop the Get Application ID functoid and configure its input as follows:

GetApplicatIDIP[1]

The first Input being the name of the common field, the second the name of the application instance and the third being the common id from the Get Common Id functoid.

Map[1]

Let test our Map. Given the following input:
<ns0:Root xmlns:ns0="http://CrossRefrence.Schema1">
<
OrderStatus>1</OrderStatus>
</
ns0:Root>
Our Map gives the following output:
<ns0:Root xmlns:ns0="http://CrossRefrence.Schema2">
<
OrderStatus>Delivered</OrderStatus>
</
ns0:Root>

Monday, May 31, 2010

String, string, Byte, byte, int, Int32....

I have often wondered while typing “string” in Visual Studio (the IntelliSense shows string and String), what’s the difference between a string and String? NONE

Then why have two names for the same data type? One is the Base Class Library (BCL) name(String) and the other is a short form for it. Since these basic data types are frequently used we are given short forms which are much easier to use e.g. int for Int32.

For the compiler it doesn’t make any difference, whether you had used an int or Int32. Consider the IL (Intermediate Language) for the following piece of code:



IL Code:

Saturday, May 8, 2010

Using the Command prompt to run C# program

For those of us who had gone on the fast track to learn C# (remember I was into java before the leap to .NET) Visual Studio IDE does a great job in encapsulating the details. For a beginner it just looks great, just write your code, hit F5 (or) run. You are done! But as you move on you begin to wonder how do you do it the old fashioned way (Command Line)?

That's exactly what I discovered learning C# 4.0. You have this tool called csc.exe (like javac), Go to your Visual Studio command prompt, navigate to the folder that has you program and do this:

> csc.exe yourprogramname.cs

This compliles your code and generates an exe. You can run your code using:
> youprogramname.exe

Replace yourprogramname with the name of your program.

Wednesday, September 23, 2009

Silverlight DatePicker Validation States

One of the cool features of silverlight is the error glyphs it automatically comes up with, when data validation for an input control fails. No coding required what so ever!

Silverlight Error Glyph

The Problem

I had to use DatePicker control and validate the selected date based on some business logic. Everything was was set up, and when I tested it there was no error glyph showing! So I started Debugging the application and found that there was nothing wrong with the logic, and the DatePicker is in fact being invalidated. Just that the DatePicker isn’t showing the error glyph like the other controls.

I did a quick Google search and ended up empty other than a few silverlight forum posts [1,2]. What I did learn from these posts is DatePicker does get invalidated but there are no view states associated with the DatePicker template.

The same could be confirmed from DatePicker’s Styles and Template Page (Though the table containing Visual States mention InvalidFocused and InvalidUnfocused states, the template doesn’t have them) of the MSDN.

Solution

Pretty Simple, edit the DatePicker’s template to support these states!

We need to have an error glyph similar to that of say the TextBox. So lets take a look at the Template of the TextBox and, we get the following validation states:





  1. <VisualStateGroup x:Name="ValidationStates">
  2. <VisualState x:Name="Valid"/>
  3. <VisualState x:Name="InvalidUnfocused">
  4. <Storyboard>
  5. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
  6. <DiscreteObjectKeyFrame KeyTime="0">
  7. <DiscreteObjectKeyFrame.Value>
  8. <Visibility>Visible</Visibility>
  9. </DiscreteObjectKeyFrame.Value>
  10. </DiscreteObjectKeyFrame>
  11. </ObjectAnimationUsingKeyFrames>
  12. </Storyboard>
  13. </VisualState>
  14. <VisualState x:Name="InvalidFocused">
  15. <Storyboard>
  16. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
  17. <DiscreteObjectKeyFrame KeyTime="0">
  18. <DiscreteObjectKeyFrame.Value>
  19. <Visibility>Visible</Visibility>
  20. </DiscreteObjectKeyFrame.Value>
  21. </DiscreteObjectKeyFrame>
  22. </ObjectAnimationUsingKeyFrames>
  23. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen">
  24. <DiscreteObjectKeyFrame KeyTime="0">
  25. <DiscreteObjectKeyFrame.Value>
  26. <System:Boolean>True</System:Boolean>
  27. </DiscreteObjectKeyFrame.Value>
  28. </DiscreteObjectKeyFrame>
  29. </ObjectAnimationUsingKeyFrames>
  30. </Storyboard>
  31. </VisualState>




The Storyboard.TargetName Property of the Invalid states refer to an Border element named ValidationErrorElement.





  1. <Border x:Name="ValidationErrorElement" Visibility="Collapsed" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1">
  2. <ToolTipService.ToolTip>
  3. <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}">
  4. <ToolTip.Triggers>
  5. <EventTrigger RoutedEvent="Canvas.Loaded">
  6. <BeginStoryboard>
  7. <Storyboard>
  8. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible">
  9. <DiscreteObjectKeyFrame KeyTime="0">
  10. <DiscreteObjectKeyFrame.Value>
  11. <System:Boolean>true</System:Boolean>
  12. </DiscreteObjectKeyFrame.Value>
  13. </DiscreteObjectKeyFrame>
  14. </ObjectAnimationUsingKeyFrames>
  15. </Storyboard>
  16. </BeginStoryboard>
  17. </EventTrigger>
  18. </ToolTip.Triggers>
  19. </ToolTip>
  20. </ToolTipService.ToolTip>
  21. <Grid Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12" Background="Transparent">
  22. <Path Fill="#FFDC000C" Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z"/>
  23. <Path Fill="#ffffff" Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8"/>
  24. </Grid>
  25. </Border>




So we will customize our DatePicker’s template to include these. Here is our DatePicker template which will do validation states.





  1. <Style x:Key="DatePickerStyle" TargetType="controls:DatePicker">
  2. <Setter Property="IsTabStop" Value="False"/>
  3. <Setter Property="Background" Value="#FFFFFFFF"/>
  4. <Setter Property="Padding" Value="2"/>
  5. <Setter Property="SelectionBackground" Value="#FF444444"/>
  6. <Setter Property="BorderBrush">
  7. <Setter.Value>
  8. <LinearGradientBrush EndPoint=".5,0" StartPoint=".5,1">
  9. <GradientStop Color="#FF617584" Offset="0"/>
  10. <GradientStop Color="#FF718597" Offset="0.375"/>
  11. <GradientStop Color="#FF8399A9" Offset="0.375"/>
  12. <GradientStop Color="#FFA3AEB9" Offset="1"/>
  13. </LinearGradientBrush>
  14. </Setter.Value>
  15. </Setter>
  16. <Setter Property="BorderThickness" Value="1"/>
  17. <Setter Property="Template">
  18. <Setter.Value>
  19. <ControlTemplate TargetType="controls:DatePicker">
  20. <Grid x:Name="Root">
  21. <Grid.Resources>
  22. <SolidColorBrush x:Key="DisabledBrush" Color="#8CFFFFFF"/>
  23. <ControlTemplate x:Key="DropDownButtonTemplate" TargetType="Button">
  24. <Grid>
  25. <VisualStateManager.VisualStateGroups>
  26. <VisualStateGroup x:Name="CommonStates">
  27. <VisualStateGroup.Transitions>
  28. <VisualTransition GeneratedDuration="0"/>
  29. <VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
  30. <VisualTransition GeneratedDuration="0:0:0.1" To="Pressed"/>
  31. </VisualStateGroup.Transitions>
  32. <VisualState x:Name="Normal"/>
  33. <VisualState x:Name="MouseOver">
  34. <Storyboard>
  35. <ColorAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#FF448DCA"/>
  36. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
  37. <SplineColorKeyFrame KeyTime="0" Value="#7FFFFFFF"/>
  38. </ColorAnimationUsingKeyFrames>
  39. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
  40. <SplineColorKeyFrame KeyTime="0" Value="#CCFFFFFF"/>
  41. </ColorAnimationUsingKeyFrames>
  42. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
  43. <SplineColorKeyFrame KeyTime="0" Value="#F2FFFFFF"/>
  44. </ColorAnimationUsingKeyFrames>
  45. </Storyboard>
  46. </VisualState>
  47. <VisualState x:Name="Pressed">
  48. <Storyboard>
  49. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
  50. <SplineColorKeyFrame KeyTime="0" Value="#FF448DCA"/>
  51. </ColorAnimationUsingKeyFrames>
  52. <DoubleAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="Highlight" Storyboard.TargetProperty="(UIElement.Opacity)">
  53. <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
  54. </DoubleAnimationUsingKeyFrames>
  55. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
  56. <SplineColorKeyFrame KeyTime="0" Value="#EAFFFFFF"/>
  57. </ColorAnimationUsingKeyFrames>
  58. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
  59. <SplineColorKeyFrame KeyTime="0" Value="#C6FFFFFF"/>
  60. </ColorAnimationUsingKeyFrames>
  61. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
  62. <SplineColorKeyFrame KeyTime="0" Value="#6BFFFFFF"/>
  63. </ColorAnimationUsingKeyFrames>
  64. <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
  65. <SplineColorKeyFrame KeyTime="0" Value="#F4FFFFFF"/>
  66. </ColorAnimationUsingKeyFrames>
  67. </Storyboard>
  68. </VisualState>
  69. <VisualState x:Name="Disabled">
  70. <Storyboard>
  71. <DoubleAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="DisabledVisual" Storyboard.TargetProperty="(UIElement.Opacity)">
  72. <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
  73. </DoubleAnimationUsingKeyFrames>
  74. </Storyboard>
  75. </VisualState>
  76. </VisualStateGroup>
  77. </VisualStateManager.VisualStateGroups>
  78. <Grid Height="18" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center" Width="19" Background="#11FFFFFF">
  79. <Grid.RowDefinitions>
  80. <RowDefinition Height="23*"/>
  81. <RowDefinition Height="19*"/>
  82. <RowDefinition Height="19*"/>
  83. <RowDefinition Height="19*"/>
  84. </Grid.RowDefinitions>
  85. <Grid.ColumnDefinitions>
  86. <ColumnDefinition Width="20*"/>
  87. <ColumnDefinition Width="20*"/>
  88. <ColumnDefinition Width="20*"/>
  89. <ColumnDefinition Width="20*"/>
  90. </Grid.ColumnDefinitions>
  91. <Border x:Name="Highlight" Margin="-1" Opacity="0" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="4" BorderBrush="#FF6DBDD1" BorderThickness="1" CornerRadius="0,0,1,1"/>
  92. <Border x:Name="Background" Margin="0,-1,0,0" Opacity="1" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" Background="#FF1F3B53" BorderBrush="#FFFFFFFF" BorderThickness="1" CornerRadius=".5"/>
  93. <Border x:Name="BackgroundGradient" Margin="0,-1,0,0" Opacity="1" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" BorderBrush="#BF000000" BorderThickness="1" CornerRadius=".5">
  94. <Border.Background>
  95. <LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
  96. <GradientStop Color="#FFFFFFFF" Offset="0"/>
  97. <GradientStop Color="#F9FFFFFF" Offset="0.375"/>
  98. <GradientStop Color="#E5FFFFFF" Offset="0.625"/>
  99. <GradientStop Color="#C6FFFFFF" Offset="1"/>
  100. </LinearGradientBrush>
  101. </Border.Background>
  102. </Border>
  103. <Rectangle StrokeThickness="1" Grid.ColumnSpan="4" Grid.RowSpan="1">
  104. <Rectangle.Stroke>
  105. <LinearGradientBrush EndPoint="0.48,-1" StartPoint="0.48,1.25">
  106. <GradientStop Color="#FF494949"/>
  107. <GradientStop Color="#FF9F9F9F" Offset="1"/>
  108. </LinearGradientBrush>
  109. </Rectangle.Stroke>
  110. <Rectangle.Fill>
  111. <LinearGradientBrush EndPoint="0.3,-1.1" StartPoint="0.46,1.6">
  112. <GradientStop Color="#FF4084BD"/>
  113. <GradientStop Color="#FFAFCFEA" Offset="1"/>
  114. </LinearGradientBrush>
  115. </Rectangle.Fill>
  116. </Rectangle>
  117. <Path Fill="#FF2F2F2F" Stretch="Fill" HorizontalAlignment="Center" Margin="4,3,4,3" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" Data="M11.426758,8.4305077 L11.749023,8.4305077 L11.749023,16.331387 L10.674805,16.331387 L10.674805,10.299648 L9.0742188,11.298672 L9.0742188,10.294277 C9.4788408,10.090176 9.9094238,9.8090878 10.365967,9.4510155 C10.82251,9.0929432 11.176106,8.7527733 11.426758,8.4305077 z M14.65086,8.4305077 L18.566387,8.4305077 L18.566387,9.3435936 L15.671368,9.3435936 L15.671368,11.255703 C15.936341,11.058764 16.27293,10.960293 16.681133,10.960293 C17.411602,10.960293 17.969301,11.178717 18.354229,11.615566 C18.739157,12.052416 18.931622,12.673672 18.931622,13.479336 C18.931622,15.452317 18.052553,16.438808 16.294415,16.438808 C15.560365,16.438808 14.951641,16.234707 14.468243,15.826504 L14.881817,14.929531 C15.368796,15.326992 15.837872,15.525723 16.289043,15.525723 C17.298809,15.525723 17.803692,14.895514 17.803692,13.635098 C17.803692,12.460618 17.305971,11.873379 16.310528,11.873379 C15.83071,11.873379 15.399232,12.079271 15.016094,12.491055 L14.65086,12.238613 z"/>
  118. <Ellipse Fill="#FFFFFFFF" StrokeThickness="0" Height="3" HorizontalAlignment="Center" VerticalAlignment="Center" Width="3" Grid.ColumnSpan="4"/>
  119. <Border x:Name="DisabledVisual" Opacity="0" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="4" BorderBrush="#B2FFFFFF" BorderThickness="1" CornerRadius="0,0,.5,.5"/>
  120. </Grid>
  121. </Grid>
  122. </ControlTemplate>
  123. </Grid.Resources>
  124. <VisualStateManager.VisualStateGroups>
  125. <VisualStateGroup x:Name="CommonStates">
  126. <VisualState x:Name="Normal"/>
  127. <VisualState x:Name="Disabled">
  128. <Storyboard>
  129. <DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisual" Storyboard.TargetProperty="Opacity" To="1"/>
  130. </Storyboard>
  131. </VisualState>

  132. </VisualStateGroup>
  133. <VisualStateGroup x:Name="ValidationStates">
  134. <VisualState x:Name="Valid"/>
  135. <VisualState x:Name="InvalidUnfocused">
  136. <Storyboard>
  137. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
  138. <DiscreteObjectKeyFrame KeyTime="0">
  139. <DiscreteObjectKeyFrame.Value>
  140. <Visibility>Visible</Visibility>
  141. </DiscreteObjectKeyFrame.Value>
  142. </DiscreteObjectKeyFrame>
  143. </ObjectAnimationUsingKeyFrames>
  144. </Storyboard>
  145. </VisualState>
  146. <VisualState x:Name="InvalidFocused">
  147. <Storyboard>
  148. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
  149. <DiscreteObjectKeyFrame KeyTime="0">
  150. <DiscreteObjectKeyFrame.Value>
  151. <Visibility>Visible</Visibility>
  152. </DiscreteObjectKeyFrame.Value>
  153. </DiscreteObjectKeyFrame>
  154. </ObjectAnimationUsingKeyFrames>
  155. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen">
  156. <DiscreteObjectKeyFrame KeyTime="0">
  157. <DiscreteObjectKeyFrame.Value>
  158. <System:Boolean>True</System:Boolean>
  159. </DiscreteObjectKeyFrame.Value>
  160. </DiscreteObjectKeyFrame>
  161. </ObjectAnimationUsingKeyFrames>
  162. </Storyboard>
  163. </VisualState>
  164. </VisualStateGroup>
  165. </VisualStateManager.VisualStateGroups>
  166. <Grid.ColumnDefinitions>
  167. <ColumnDefinition Width="*"/>
  168. <ColumnDefinition Width="Auto"/>
  169. </Grid.ColumnDefinitions>
  170. <System_Windows_Controls_Primitives:DatePickerTextBox x:Name="TextBox" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Column="0" SelectionBackground="{TemplateBinding SelectionBackground}"/>
  171. <Button x:Name="Button" Margin="2,0,2,0" Width="20" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Foreground="{TemplateBinding Foreground}" Template="{StaticResource DropDownButtonTemplate}" Grid.Column="1"/>
  172. <Grid x:Name="DisabledVisual" IsHitTestVisible="False" Opacity="0" Grid.ColumnSpan="2">
  173. <Grid.ColumnDefinitions>
  174. <ColumnDefinition Width="*"/>
  175. <ColumnDefinition Width="Auto"/>
  176. </Grid.ColumnDefinitions>
  177. <Rectangle Fill="#8CFFFFFF" RadiusX="1" RadiusY="1"/>
  178. <Rectangle Fill="#8CFFFFFF" RadiusX="1" RadiusY="1" Height="18" Margin="2,0,2,0" Width="19" Grid.Column="1"/>
  179. </Grid>
  180. <Popup x:Name="Popup"/>
  181. <Border x:Name="ValidationErrorElement" Visibility="Collapsed" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1">
  182. <ToolTipService.ToolTip>
  183. <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}">
  184. <ToolTip.Triggers>
  185. <EventTrigger RoutedEvent="Canvas.Loaded">
  186. <BeginStoryboard>
  187. <Storyboard>
  188. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible">
  189. <DiscreteObjectKeyFrame KeyTime="0">
  190. <DiscreteObjectKeyFrame.Value>
  191. <System:Boolean>true</System:Boolean>
  192. </DiscreteObjectKeyFrame.Value>
  193. </DiscreteObjectKeyFrame>
  194. </ObjectAnimationUsingKeyFrames>
  195. </Storyboard>
  196. </BeginStoryboard>
  197. </EventTrigger>
  198. </ToolTip.Triggers>
  199. </ToolTip>
  200. </ToolTipService.ToolTip>
  201. <Grid Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12" Background="Transparent">
  202. <Path Fill="#FFDC000C" Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z"/>
  203. <Path Fill="#ffffff" Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8"/>
  204. </Grid>
  205. </Border>
  206. </Grid>
  207. </ControlTemplate>
  208. </Setter.Value>
  209. </Setter>
  210. </Style>




Place this in the App.xaml and refer this style in your DatePicker Control.





  1. <controls:DatePicker x:Name="deliverlyDate" Style="{StaticResource DatePickerStyle}" VerticalAlignment="Top" SelectedDate="{Binding Date, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}" HorizontalAlignment="Center" Margin="0" Grid.Column="1"/>




Our DatePicker now behaves just like other controls during invalid states:

DatePicker with Validation States

Demo:





Reblog this post [with Zemanta]