WPF Reusability Factor – User Controls & Custom Controls

There is always seen a perplexity/confusion exist in terms of User Controls and Custom Controls in regards to WPF. They both work alike in terms of reusability, like you can reuse them over and over, again and again. But there are also finite number of differences between them. And in today's post I’ll highlight them with the help of examples.

A User Control is actually a composite of other UI controls, that means it is composing it with the help of other controls and that can be styled and reused as needed. You compose the existing controls in a User Control using XAML like we do in case of Window or so. And the interaction is done in the code behind, if needed. User Control is derived from a ContentControl (Figure-1). That means it Can only have one Child by nature that you set with the help of its content property. In order to compose with more elements, you need to have a Composite Control like a Panel as its root, like we see in case of compositing the Window itself.

Lets now turn our focus to the Custom Control. By Custom Control we mean it is customizable by the end user/consumer. Lets see how! You derive it from Control or ContentControl or other rich controls like RadioButton control or checkbox control etc. It takes part in the themes as well as skinning mechanism for the end users/consumers with the help of Generic theme defined under Themes/Generic.xaml, where you redefine the ControlTemplate or Visual Tree for this custom control and also provide with a default style as needed. Custom controls provides a much more flexible model in terms of customization as well as reusability as compared to User Controls. If the consumer wants to apply a different theme, all he needs to do is to change the control-template/style of that custom control and that's it, it is customized.

UserControls-CustomControls Figure-1

I’ll explain you all these concepts with the help of a concrete example. Here is how the Project looks like:

image Figure-2

I have created a MainWindow that is composed of a Grid that has two rows. First Row contains a Custom Control “GlassRadioControl” and Row#2 contains a User Control (MessageBoxControl) that mimics more like a MessageWindow or so. Class Hierarchy is shown in the Figure-1 above. Here is the XAML for it.

Code Snippet
  1. <Window x:Class="WpfTestApp.MainWindow"
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     xmlns:local="clr-namespace:WpfTestApp"
  5.     Title="[Custom Control] vs [User Control]" Height="300" Width="500">
  6.     <Window.Resources>
  7.         <Style x:Key="MessageBoxControlStyle1" TargetType="{x:Type local:MessageBoxControl}">
  8.             <Setter Property="Background" Value="LightGreen" />
  9.             <Setter Property="BorderBrush" Value="Gray" />
  10.             <Setter Property="BorderThickness" Value="2" />
  11.             <Setter Property="Template">
  12.                 <Setter.Value>
  13.                     <ControlTemplate TargetType="{x:Type local:MessageBoxControl}">
  14.                         <Border SnapsToDevicePixels="true"
  15.                             Background="{TemplateBinding Background}"
  16.                             BorderBrush="{TemplateBinding BorderBrush}"
  17.                             BorderThickness="{TemplateBinding BorderThickness}"
  18.                             Padding="{TemplateBinding Padding}">
  19.                         <ContentPresenter
  20.                             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
  21.                             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
  22.                             SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
  23.                         </Border>
  24.                     </ControlTemplate>
  25.                 </Setter.Value>
  26.             </Setter>
  27.         </Style>
  28.     </Window.Resources>
  29.     <Grid Margin="5" Background="Beige">
  30.         <Grid.RowDefinitions>
  31.             <RowDefinition Height="57" />
  32.             <RowDefinition />
  33.         </Grid.RowDefinitions>
  34.         <GroupBox Header="Custom Control's Example" Margin="3">
  35.             <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" >
  36.                 <local:GlassRadioControl DockPanel.Dock="Top" IsChecked="True" LeftColumnWidth="77" />
  37.                 <local:GlassRadioControl DockPanel.Dock="Top" IsRadioChecked="{x:Null}" LeftColumnWidth="77"/>
  38.                 <local:GlassRadioControl IsRadioChecked="False" LeftColumnWidth="77"/>
  39.             </StackPanel>
  40.         </GroupBox>
  41.         <GroupBox Grid.Row="1" Header="User Control's Example" Margin="3">
  42.             <local:MessageBoxControl Message="Hello World"
  43.                 Style="{DynamicResource MessageBoxControlStyle1}" />
  44.         </GroupBox>
  45.     </Grid>
  46. </Window>

Figure-3

Here is the output of the User Control’s:

image Figure-4

and the XAML is shown below.

Code Snippet
  1. <UserControl x:Class="WpfTestApp.MessageBoxControl"
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  4.  
  5.     <Grid>
  6.         <Grid.RowDefinitions>
  7.             <RowDefinition Height="*"/>
  8.             <RowDefinition Height="37"/>
  9.         </Grid.RowDefinitions>
  10.         <Border BorderThickness="1" Opacity="0.75">
  11.             <TextBlock x:Name="MessageText" Text="Message here" Margin="2" VerticalAlignment="Center" />
  12.         </Border>
  13.         <Border Grid.Row="1" Background="LightGray" Opacity="0.65" >
  14.             <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
  15.                 <Button Content="Cancel" Margin="1" Width="100" Click="ButtonCancelClick" />
  16.                 <Button Content="OK" IsDefault="True" Click="ButtonOkClick" Margin="1" Width="100" />
  17.             </StackPanel>
  18.         </Border>
  19.     </Grid>
  20. </UserControl>

Figure-5

Basically we composed a TextBlock control and Two button controls and lay them out in the Grid and we have the UserControl ready. And the instance is created at line 42, Figure-3 above.

Lets now move on to the Custom Control, GlassRadioControl. This Control is derived from RadioButton (See Figure-1). And what’s the rationale behind extending the RadioButton, is actually we wanted the same behavior as of RadioButton but it should have a look and feel of a specialized split button. This could have done by using just the Control as a base with a little more hard work. Here is what we wanted to accomplish in this Custom-Control:

1) When it is selected, it should have an outline around it.
2) The button has to be split to show text on your Left and visual representation on the right, that is based on some state. Like When it is ok to Run, shows a Tick mark, while if its in progress shows revolving/animated Arrowed-Circle and when there is an error shows a cross, etc. Here is how it looks like for different states:


image

 Figure-6

In order to achieve this, I have modified the control template in the Themes/Generic.xaml, and here is how it looks like (see line 69):

Code Snippet
  1. <ResourceDictionary
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     xmlns:local="clr-namespace:WpfTestApp">
  5.  
  6.     <Style x:Key="CrossPathStyle" TargetType="{x:Type Path}" >
  7.         <Setter Property="Data" Value="M0,0L10,10 M10,0L0,10"/>
  8.         <Setter Property="Stroke" Value="#FFFF0000"/>
  9.         <Setter Property="StrokeThickness" Value="1.25"/>
  10.         <Setter Property="StrokeStartLineCap" Value="Round"/>
  11.         <Setter Property="StrokeEndLineCap" Value="Round"/>
  12.         <Setter Property="StrokeLineJoin" Value="Round"/>
  13.         <Setter Property="RenderTransformOrigin" Value="0.479,0.475"/>
  14.         <Setter Property="Opacity" Value="0.75"/>
  15.         <Setter Property="RenderTransform">
  16.             <Setter.Value>
  17.                 <TransformGroup>
  18.                     <ScaleTransform ScaleX="1" ScaleY="1"/>
  19.                     <SkewTransform AngleX="0" AngleY="0"/>
  20.                     <RotateTransform Angle="0"/>
  21.                     <TranslateTransform X="0" Y="0"/>
  22.                 </TransformGroup>
  23.             </Setter.Value>
  24.         </Setter>
  25.     </Style>
  26.  
  27.     <Style x:Key="TickPathStyle" TargetType="{x:Type Path}">
  28.         <Setter Property="Data" Value="M0,5L3,10 10,0"/>
  29.         <Setter Property="Stroke" Value="#FF90EE90"/>
  30.         <Setter Property="StrokeThickness" Value="1.25"/>
  31.         <Setter Property="StrokeStartLineCap" Value="Round"/>
  32.         <Setter Property="StrokeEndLineCap" Value="Round"/>
  33.         <Setter Property="StrokeLineJoin" Value="Round"/>
  34.         <Setter Property="RenderTransformOrigin" Value="0.479,0.475"/>
  35.         <Setter Property="Opacity" Value="0.75"/>
  36.         <Setter Property="RenderTransform">
  37.             <Setter.Value>
  38.                 <TransformGroup>
  39.                     <ScaleTransform ScaleX="1" ScaleY="1"/>
  40.                     <SkewTransform AngleX="0" AngleY="0"/>
  41.                     <RotateTransform Angle="0"/>
  42.                     <TranslateTransform X="0" Y="0"/>
  43.                 </TransformGroup>
  44.             </Setter.Value>
  45.         </Setter>
  46.     </Style>
  47.     
  48.     <Style x:Key="ArrowRoundPath" TargetType="{x:Type Path}">
  49.         <Setter Property="RenderTransformOrigin" Value="0.556,0.5" />
  50.         <!--<Setter Property="Margin" Value="0,0,0,10" />-->
  51.         <Setter Property="Stretch" Value="Uniform" />
  52.         <Setter Property="Stroke" Value="#BF0000FF" />
  53.         <Setter Property="StrokeThickness" Value="2.75" />
  54.         <Setter Property="StrokeMiterLimit" Value="2.5" />
  55.         <Setter Property="Data" Value="M6.8783809,21.019825 C5.7961721,19.096961 5.1789828,16.872546 5.1789828,14.499944 5.1789828,7.228976 10.982436,1.333335 18.142628,1.333335 25.30132,1.333335 31.104814,7.228976 31.104814,14.499944 31.104814,21.771013 25.30132,27.666664 18.142628,27.666664 15.331431,27.666664 12.729834,26.756829 10.606237,25.213419 M9.1658801,15.547488 L1.333335,19.323817 7.9703076,22.081687 9.1658801,15.547488 z" />
  56.         <Setter Property="RenderTransform">
  57.             <Setter.Value>
  58.                 <TransformGroup>
  59.                     <ScaleTransform ScaleX="-1" ScaleY="1"/>
  60.                     <SkewTransform AngleX="0" AngleY="0"/>
  61.                     <RotateTransform Angle="0"/>
  62.                     <TranslateTransform X="0" Y="0"/>
  63.                 </TransformGroup>
  64.             </Setter.Value>
  65.         </Setter>
  66.         <Setter Property="Opacity" Value="0.75"/>
  67.     </Style>
  68.     
  69.     <ControlTemplate x:Key="GlassRadioTemplate" TargetType="{x:Type local:GlassRadioControl}">
  70.         <ControlTemplate.Resources>
  71.             <Storyboard x:Key="OnLoaded1">
  72.                 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="path2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" RepeatBehavior="Forever">
  73.                     <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
  74.                     <SplineDoubleKeyFrame KeyTime="00:00:01.0000000" Value="360"/>
  75.                 </DoubleAnimationUsingKeyFrames>
  76.             </Storyboard>
  77.             <Storyboard x:Key="Timeline1">
  78.                 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
  79.                     <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1"/>
  80.                 </DoubleAnimationUsingKeyFrames>
  81.             </Storyboard>
  82.             <Storyboard x:Key="Timeline2">
  83.                 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
  84.                     <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
  85.                 </DoubleAnimationUsingKeyFrames>
  86.             </Storyboard>
  87.         </ControlTemplate.Resources>
  88.         <Border BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
  89.             <Border x:Name="border" Background="#7F000000" BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
  90.                 <Grid>
  91.                     <Grid.RowDefinitions>
  92.                         <RowDefinition Height="0.55*"/>
  93.                         <RowDefinition Height="0.45*" />
  94.                     </Grid.RowDefinitions>
  95.                     <Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4">
  96.                         <Border.Background>
  97.                             <RadialGradientBrush>
  98.                                 <RadialGradientBrush.RelativeTransform>
  99.                                     <TransformGroup>
  100.                                         <ScaleTransform ScaleX="1.702" ScaleY="2.243"/>
  101.                                         <SkewTransform AngleX="0" AngleY="0"/>
  102.                                         <RotateTransform Angle="0"/>
  103.                                         <TranslateTransform X="-0.368" Y="-0.152"/>
  104.                                     </TransformGroup>
  105.                                 </RadialGradientBrush.RelativeTransform>
  106.                                 <GradientStop Color="#B28DBDFF" Offset="0"/>
  107.                                 <GradientStop Color="#008DBDFF" Offset="1"/>
  108.                             </RadialGradientBrush>
  109.                         </Border.Background>
  110.                     </Border>
  111.                     <Grid Grid.Row="0" Grid.RowSpan="2" Margin="0">
  112.                         <Grid.ColumnDefinitions>
  113.                             <ColumnDefinition Width="{TemplateBinding LeftColumnWidth}" />
  114.                             <ColumnDefinition Width="{TemplateBinding RightColumnWidth}" />
  115.                         </Grid.ColumnDefinitions>
  116.  
  117.                         <ContentPresenter Grid.Column="0" Margin="3,0,0,0" x:Name="contentPresenter"
  118.                                 Content="{TemplateBinding Content}"
  119.                                 ContentTemplate="{TemplateBinding ContentTemplate}"
  120.                                 HorizontalAlignment="Center"
  121.                                 VerticalAlignment="Center" />
  122.  
  123.                         <Border Grid.Column="1" BorderBrush="Silver" BorderThickness="1.5,0,0,0" />
  124.                         <Border Grid.Column="1" BorderBrush="Black" BorderThickness="1.25,0,0,0" />
  125.                         <Viewbox Grid.Column="1" x:Name="view1" Visibility="Visible" Margin="5" RenderTransformOrigin="0.5,0.5">
  126.                             <Path x:Name="path" Style="{StaticResource CrossPathStyle}" />
  127.                         </Viewbox>
  128.                         <Viewbox Grid.Column="1" x:Name="view2" Visibility="Collapsed" Margin="2">
  129.                             <Path x:Name="path2" Style="{StaticResource ArrowRoundPath}"/>
  130.                         </Viewbox>
  131.                     </Grid>
  132.                     <Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0">
  133.                         <Border.Background>
  134.                             <LinearGradientBrush EndPoint="0.494,0.889" StartPoint="0.494,0.028">
  135.                                 <GradientStop Color="#99FFFFFF" Offset="0"/>
  136.                                 <GradientStop Color="#33FFFFFF" Offset="1"/>
  137.                             </LinearGradientBrush>
  138.                         </Border.Background>
  139.                     </Border>
  140.                 </Grid>
  141.             </Border>
  142.         </Border>
  143.         <ControlTemplate.Triggers>
  144.             <Trigger Property="IsChecked" Value="True">
  145.                 <Setter Property="BorderBrush" TargetName="border" Value="#FFFFA500"/>
  146.             </Trigger>
  147.             <Trigger Property="IsPressed" Value="True">
  148.                 <Setter Property="Opacity" TargetName="shine" Value="0.4"/>
  149.                 <Setter Property="Background" TargetName="border" Value="#CC000000"/>
  150.                 <Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
  151.             </Trigger>
  152.             <Trigger Property="IsMouseOver" Value="True">
  153.                 <Trigger.EnterActions>
  154.                     <BeginStoryboard Storyboard="{StaticResource Timeline1}"/>
  155.                 </Trigger.EnterActions>
  156.                 <Trigger.ExitActions>
  157.                     <BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}"/>
  158.                 </Trigger.ExitActions>
  159.             </Trigger>
  160.             <Trigger Property="IsRadioChecked" Value="True">
  161.                 <Setter Property="Content" Value="{Binding Path=TickContentText}" />
  162.                 <Setter TargetName="view2"
  163.                             Property="Visibility"
  164.                             Value="Collapsed" />
  165.                 <Setter TargetName="path"
  166.                             Property="Style"
  167.                             Value="{StaticResource TickPathStyle}" />
  168.             </Trigger>
  169.             
  170.             <Trigger Property="IsRadioChecked" Value="False">
  171.                 <!--<Setter TargetName="contentPresenter" Property="Content" Value="{Binding Path=CrossContentText}" />-->
  172.                                 <Setter Property="Content" Value="{Binding Path=CrossContentText}" />
  173.             </Trigger>
  174.  
  175.             <Trigger Property="IsRadioChecked" Value="{x:Null}">
  176.                 <Setter Property="Content" Value="{Binding Path=ProgressContentText}" />
  177.                 <Setter TargetName="view2"
  178.                             Property="Visibility"
  179.                             Value="Visible" />
  180.                 <Setter TargetName="view1"
  181.                             Property="Visibility"
  182.                             Value="Collapsed" />
  183.             </Trigger>
  184.             <!--<EventTrigger RoutedEvent="FrameworkElement.Loaded">
  185.                 <BeginStoryboard Storyboard="{StaticResource OnLoaded1}"/>
  186.             </EventTrigger>-->
  187.         </ControlTemplate.Triggers>
  188.     </ControlTemplate>
  189.  
  190.     <Style TargetType="{x:Type local:GlassRadioControl}">
  191.         <Setter Property="Template" Value="{StaticResource GlassRadioTemplate}"/>
  192.     </Style>
  193.     
  194.     <!--<Style TargetType="{x:Type local:GlassRadioControl}">
  195.         <Setter Property="Template">
  196.             <Setter.Value>
  197.                 <ControlTemplate TargetType="{x:Type local:GlassRadioControl}">
  198.                     <Border Background="{TemplateBinding Background}"
  199.                             BorderBrush="{TemplateBinding BorderBrush}"
  200.                             BorderThickness="{TemplateBinding BorderThickness}">
  201.                     </Border>
  202.                 </ControlTemplate>
  203.             </Setter.Value>
  204.         </Setter>
  205.     </Style>-->
  206. </ResourceDictionary>

 Figure-7

In this Custom Control, GlassRadioControl, there are three things noticeable. If you look at the XAML (Figure-7), I have created three styles for the paths and referred them under the ControlTemplate section of the Generic.xaml, resource dictionary under. The Control Template’s Resource section contains the animation logic for the circular motion of the Arrow. Also I took advantage of Triggers in the Control Template to obtain the Conditional Logic for the control, like when it is selected, a Border will be drawn etc.
And here is the Code behind for it. If you look at the code, we defined IsRadioChecked Dependency Property, that is responsible for states, like running or error states or so while LeftColumnWidth and RightColumnWidth Dependency properties are responsible for Setting the Left and Right Width of the Split sections. Also you can set the Ticked Content using TickContentText Property, CrossContentText Property when it sees an Error state as well as the ProgressContentText property for showing the running state.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14. using System.Windows.Media.Animation;
  15.  
  16. namespace WpfTestApp
  17. {
  18.     /// <summary>
  19.     /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
  20.     ///
  21.     /// Step 1a) Using this custom control in a XAML file that exists in the current project.
  22.     /// Add this XmlNamespace attribute to the root element of the markup file where it is
  23.     /// to be used:
  24.     ///
  25.     ///     xmlns:MyNamespace="clr-namespace:WpfTestApp"
  26.     ///
  27.     ///
  28.     /// Step 1b) Using this custom control in a XAML file that exists in a different project.
  29.     /// Add this XmlNamespace attribute to the root element of the markup file where it is
  30.     /// to be used:
  31.     ///
  32.     ///     xmlns:MyNamespace="clr-namespace:WpfTestApp;assembly=WpfTestApp"
  33.     ///
  34.     /// You will also need to add a project reference from the project where the XAML file lives
  35.     /// to this project and Rebuild to avoid compilation errors:
  36.     ///
  37.     ///     Right click on the target project in the Solution Explorer and
  38.     ///     "Add Reference"->"Projects"->[Browse to and select this project]
  39.     ///
  40.     ///
  41.     /// Step 2)
  42.     /// Go ahead and use your control in the XAML file.
  43.     ///
  44.     ///     <MyNamespace:GlassRadioControl/>
  45.     ///
  46.     /// </summary>
  47.     public partial class GlassRadioControl : RadioButton
  48.     {
  49.         static GlassRadioControl()
  50.         {
  51.             try
  52.             {
  53.                 DefaultStyleKeyProperty.OverrideMetadata(typeof(GlassRadioControl),
  54.                     new FrameworkPropertyMetadata(typeof(GlassRadioControl)));
  55.             }
  56.             catch
  57.             {
  58.  
  59.             }
  60.         }
  61.  
  62.         public static readonly DependencyProperty IsRadioCheckedProperty = DependencyProperty.Register("IsRadioChecked",
  63.             typeof(bool?),
  64.             typeof(GlassRadioControl),
  65.             new FrameworkPropertyMetadata(true,
  66.             new PropertyChangedCallback(RadioCheckedPropertyChangedCallBack)));
  67.  
  68.         public bool? IsRadioChecked
  69.         {
  70.             get { return (bool?)GetValue(IsRadioCheckedProperty); }
  71.             set { SetValue(IsRadioCheckedProperty, value); }
  72.         }
  73.  
  74.         static void RadioCheckedPropertyChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
  75.         {
  76.  
  77.         }
  78.  
  79.         public static readonly DependencyProperty LeftColumnWidthProperty = DependencyProperty.Register("LeftColumnWidth",
  80.             typeof(GridLength),
  81.             typeof(GlassRadioControl),
  82.             new FrameworkPropertyMetadata(new GridLength(0.25, GridUnitType.Auto),
  83.             new PropertyChangedCallback(LeftColumnWidthPropertyChangedCallBack)));
  84.  
  85.         public GridLength LeftColumnWidth
  86.         {
  87.             get { return (GridLength)GetValue(LeftColumnWidthProperty); }
  88.             set { SetValue(LeftColumnWidthProperty, value); }
  89.         }
  90.  
  91.         static void LeftColumnWidthPropertyChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
  92.         {
  93.         }
  94.  
  95.         public static readonly DependencyProperty RightColumnWidthProperty = DependencyProperty.Register("RightColumnWidth",
  96.              typeof(GridLength),
  97.              typeof(GlassRadioControl),
  98.              new FrameworkPropertyMetadata(new GridLength(0.25, GridUnitType.Auto),
  99.              new PropertyChangedCallback(RightColumnWidthPropertyChangedCallBack)));
  100.  
  101.         public GridLength RightColumnWidth
  102.         {
  103.             get { return (GridLength)GetValue(RightColumnWidthProperty); }
  104.             set { SetValue(RightColumnWidthProperty, value); }
  105.         }
  106.  
  107.  
  108.         static void RightColumnWidthPropertyChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
  109.         {
  110.         }
  111.  
  112.         public static readonly DependencyProperty TickContentTextProperty = DependencyProperty.Register("TickContentText",
  113.             typeof(string),
  114.             typeof(GlassRadioControl),
  115.             new FrameworkPropertyMetadata("Run",
  116.             new PropertyChangedCallback(TickContentTextPropertyChangedCallBack)));
  117.  
  118.         public string TickContentText
  119.         {
  120.             get { return (string)GetValue(TickContentTextProperty); }
  121.             set { SetValue(TickContentTextProperty, value); }
  122.         }
  123.  
  124.         static void TickContentTextPropertyChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
  125.         {
  126.         }
  127.  
  128.         public static readonly DependencyProperty CrossContentTextProperty = DependencyProperty.Register("CrossContentText",
  129.             typeof(string),
  130.             typeof(GlassRadioControl),
  131.             new FrameworkPropertyMetadata("Error",
  132.             new PropertyChangedCallback(CrossContentTextPropertyChangedCallBack)));
  133.  
  134.         public string CrossContentText
  135.         {
  136.             get { return (string)GetValue(CrossContentTextProperty); }
  137.             set { SetValue(CrossContentTextProperty, value); }
  138.         }
  139.  
  140.         static void CrossContentTextPropertyChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
  141.         {
  142.         }
  143.  
  144.         public static readonly DependencyProperty ProgressContentTextProperty = DependencyProperty.Register("ProgressContentText",
  145.             typeof(string),
  146.             typeof(GlassRadioControl),
  147.             new FrameworkPropertyMetadata("Runing",
  148.             new PropertyChangedCallback(ProgressContentTextPropertyChangedCallBack)));
  149.  
  150.         public string ProgressContentText
  151.         {
  152.             get { return (string)GetValue(ProgressContentTextProperty); }
  153.             set { SetValue(ProgressContentTextProperty, value); }
  154.         }
  155.  
  156.         static void ProgressContentTextPropertyChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
  157.         {
  158.         }
  159.  
  160.         public GlassRadioControl()
  161.         {
  162.             // this is important if you want to bind the properties in the triggers or so...
  163.             this.DataContext = this;
  164.         }
  165.  
  166.         public override void OnApplyTemplate()
  167.         {
  168.             base.OnApplyTemplate();
  169.  
  170.             Storyboard storyboard = (Storyboard)this.Template.Resources["OnLoaded1"];
  171.             storyboard.Begin(this, this.Template);
  172.         }
  173.  
  174.     }
  175. }

 Figure-8

Once this Custom Control is developed, you may reuse it over and over and again and again, as you can see Lines 36-38, Figure-3.
Now, the purpose of the test application is to show you how we consume both Custom Controls and User Controls and how they can be reused and customized for our needs. Here is the final output for it:

image

 Figure-9

That's all for now, I’ll elaborate the concept of custom controls in a more like a tutorial, when I cover the Control Templates in context to Another Reusability Factor i.e Styling, Themes and Skinning  , So stay tuned. Enjoy :)

Download File - Sample Project

If you enjoyed reading this blog, leave your valuable feedback and consider subscribing to the RSS feed. You can also subscribe to it by email. Also, you can follow me on Twitter. Thank you!

Technorati Tags: ,,

Comments (2) -

Bonte Wrinkle Cream
12/8/2017 5:06:46 PM #

Howdy very cool website!! Guy .. Excellent .. Superb .. I will bookmark your site and take the feeds additionally...I'm satisfied to seek out so many helpful info here in the put up, we want develop extra techniques in this regard, thank you for sharing.

Commercial Painting
12/9/2017 3:46:59 PM #

Thank you a bunch for sharing this with all folks you actually understand what you are speaking about! Bookmarked. Kindly also seek advice from my website =). We will have a hyperlink trade contract among us  Also visit my web-site:  Commercial Painting - http://studentnet.ge/forum//profile.php?id=913732

cheap auto parts
12/9/2017 5:42:55 PM #

Excellent site you have here but I was curious if you knew of any user discussion forums that cover the same topics talked about in this article? I'd really love to be a part of group where I can get feed-back from other experienced people that share the same interest. If you have any suggestions, please let me know. Appreciate it!  My web blog;  cheap auto parts - buzzon.khaleejtimes.com/author/wang24mclaughlin/

ledarskapsutbildning stockholm
12/9/2017 11:38:41 PM #

Bless you for this particular facts I has been checking all Msn to be able to come across it!

vps server price in india
12/10/2017 6:29:30 PM #

web hosting discounts  web hosting service navi mumbai - www.buena.space/...osting-service-navi-mumbai.html  move joomla 3 site to another server  domain and email hosting canada - www.buena.space/...n-and-email-hosting-canada.html  best windows reseller hosting  cheap vps uk - https://www.buena.space/cheap-vps-uk.html  vps linux server uk  cheapest vps provider - https://www.buena.space/cheapest-vps-provider.html  importing wordpress site to new host  wordpress multisite hosting uk - www.buena.space/...press-multisite-hosting-uk.html  cheap hosting reseller plans  cheap vps windows hosting - www.buena.space/cheap-vps-windows-hosting.html  website hosting australia cheap  cpanel vps uk - https://www.buena.space/cpanel-vps-uk.html  how to move wordpress to another host  cheap windows vps server - www.buena.space/cheap-windows-vps-server.html  wordpress domain hosting package  ddos mitigation dedicated server - www.buena.space/...itigation-dedicated-server.html  trial windows vps  vps hosting xen - https://www.buena.space/vps-hosting-xen.html  cheap managed  vps server price in india - www.buena.space/vps-server-price-in-india.html  server  uk based windows vps - https://www.buena.space/uk-based-windows-vps.html  windows dedicated server india  cheap vps 1 dollar - https://www.buena.space/cheap-vps-1-dollar.html  web hosting russia  dedicated server hosting define - www.buena.space/...ated-server-hosting-define.html  hosting reseller program  web hosting prices in pakistan - www.buena.space/...hosting-prices-in-pakistan.html  cheap wordpress hosting  domain and email hosting canada - www.buena.space/...n-and-email-hosting-canada.html  web hosting toronto review  unlimited reseller hosting - www.buena.space/unlimited-reseller-hosting.html  cheapest yearly vps  windows server 2003 vps hosting - www.buena.space/...ws-server-2003-vps-hosting.html  100tb dedicated server  dedicated server reseller program - www.buena.space/...ed-server-reseller-program.html  dedicated server hosting low cost  dedicated server name server setup - www.buena.space/...d-server-name-server-setup.html  resellerspanel hosting  free vps server ukraine - www.buena.space/free-vps-server-ukraine.html  website and email hosting malaysia  vps hosting custom os - https://www.buena.space/vps-hosting-custom-os.html  moving wordpress site to new domain and server  windows dedicated server - www.buena.space/windows-dedicated-server.html  how to resell hosting  vps windows cheapest - https://www.buena.space/vps-windows-cheapest.html  move wordpress site to different domain name  cheap windows vps server - www.buena.space/cheap-windows-vps-server.html  web hosting mumbai  rent dedicated server sweden - www.buena.space/rent-dedicated-server-sweden.html

cheap uk dedicated server hosting
12/10/2017 6:43:01 PM #

best dedicated server canada  dedicated server canada - www.albertha.club/dedicated-server-canada.html  dedicated email hosting solution  dedicated servers reviews - www.albertha.club/dedicated-servers-reviews.html  dedicated server toronto  website hosting provider definition - www.albertha.club/...ting-provider-definition.html  shared hosting server specs  migrate wordpress blog to new host - www.albertha.club/...rdpress-blog-to-new-host.html   cheap uk dedicated server hosting - www.albertha.club/...dedicated-server-hosting.html  vps linux usa  web hosting hamilton ontario - www.albertha.club/...hosting-hamilton-ontario.html  web hosting service providers  buy vps linux instant activation - www.albertha.club/...linux-instant-activation.html  migrating wordpress to another host  web hosting with ftp server - www.albertha.club/web-hosting-with-ftp-server.html  windows 7 vps usa  web hosting with sql server - www.albertha.club/web-hosting-with-sql-server.html  web domain hosting services  web hosting geeks scholarship - www.albertha.club/...osting-geeks-scholarship.html  fastest shared hosting  cheap xen vps - https://www.albertha.club/cheap-xen-vps.html  web hosting domain indonesia  web hosting in canada reviews - www.albertha.club/...osting-in-canada-reviews.html  vps dedicated server difference  web hosting mac uk - https://www.albertha.club/web-hosting-mac-uk.html  web hosting with php mysql  managed vps hosting uk - www.albertha.club/managed-vps-hosting-uk.html  how to move wordpress to a new host or server without downtime  cheapest unmetered dedicated server - www.albertha.club/...metered-dedicated-server.html  dedicated server hosting in india  web hosting prices in nigeria - www.albertha.club/...osting-prices-in-nigeria.html  dedicated server dubai  web hosting perth australia - www.albertha.club/web-hosting-perth-australia.html  web hosting with shopping cart  web email hosting uk - www.albertha.club/web-email-hosting-uk.html  what are dedicated servers for games  cheap vps hosting for windows - www.albertha.club/...-vps-hosting-for-windows.html  website hosting chennai  web hosting with ftp server - www.albertha.club/web-hosting-with-ftp-server.html  best cheap reseller hosting  top shared hosting providers - www.albertha.club/...shared-hosting-providers.html  where to host a wordpress site  mongodb php shared hosting - www.albertha.club/mongodb-php-shared-hosting.html  cheap domain and hosting package  uk domain hosting wordpress - www.albertha.club/uk-domain-hosting-wordpress.html  sweden dedicated server hosting  plesk 12 reseller hosting - www.albertha.club/plesk-12-reseller-hosting.html  web hosting services  hosting vps fast - https://www.albertha.club/hosting-vps-fast.html  web hosting definitions  unlimited master reseller hosting - www.albertha.club/...-master-reseller-hosting.html

free reseller hosting in india
12/10/2017 8:03:56 PM #

cheapest dedicated servers in the world  web server on mac mavericks - www.arnetta.space/web-server-on-mac-mavericks.html  web hosts for wordpress  best uk managed vps - https://www.arnetta.space/best-uk-managed-vps.html  uk dedicated servers windows  cheapest unmetered dedicated server - www.arnetta.space/...metered-dedicated-server.html  shared server vs dedicated server  free wordpress hosting australia - www.arnetta.space/...dpress-hosting-australia.html  web domain and hosting reviews  website and email hosting new zealand - www.arnetta.space/...mail-hosting-new-zealand.html  website hosting and domain uk  web hosting definitions - www.arnetta.space/web-hosting-definitions.html  web hosting costs in india  web hosting mac server - www.arnetta.space/web-hosting-mac-server.html  low cost windows vps hosting  vps 30 day trial - https://www.arnetta.space/vps-30-day-trial.html  uk dedicated servers limited  unlimited ssd reseller hosting - www.arnetta.space/...ted-ssd-reseller-hosting.html  dedicated server or vps  migrate joomla site to new host - www.arnetta.space/...-joomla-site-to-new-host.html  master reseller hosting singapore  vps hosting cheap - https://www.arnetta.space/vps-hosting-cheap.html   free reseller hosting in india - www.arnetta.space/...eseller-hosting-in-india.html  wordpress hosting trial  wordpress host multiple domains - www.arnetta.space/...ss-host-multiple-domains.html  do i need vps or shared hosting  how virtual private server works - www.arnetta.space/...ual-private-server-works.html  whmcs reseller hosting  cheap germany dedicated server - www.arnetta.space/...germany-dedicated-server.html  best wordpress blog sites  vps with ssd - https://www.arnetta.space/vps-with-ssd.html  cheapest uk dedicated server  cheap xen vps - https://www.arnetta.space/cheap-xen-vps.html  what is dedicated server in games  website design and hosting brisbane - www.arnetta.space/...ign-and-hosting-brisbane.html  web hosting reseller accounts  web host site - https://www.arnetta.space/web-host-site.html  free wordpress hosting providers  web hosting server cost - www.arnetta.space/web-hosting-server-cost.html  free window vps  website hosting new zealand - www.arnetta.space/website-hosting-new-zealand.html  best cheap windows vps  web hosting faq - https://www.arnetta.space/web-hosting-faq.html  web design and hosting contract  web hosting checker - https://www.arnetta.space/web-hosting-checker.html  cheap unlimited vps  web hosting uk promotional code - www.arnetta.space/...ting-uk-promotional-code.html  cheapest linux server hosting  best prices vps - https://www.arnetta.space/best-prices-vps.html  web hosting 1 per month  web hosting without domain transfer - www.arnetta.space/...-without-domain-transfer.html

whm vps file manager
12/10/2017 8:04:43 PM #

personal dedicated server  best reseller hosting plans india - www.albertha.club/...ller-hosting-plans-india.html  web host php postgresql  web hosting control panel - www.albertha.club/web-hosting-control-panel.html  dedicated ip email hosting  very cheap dedicated servers - www.albertha.club/...-cheap-dedicated-servers.html  web hosting christmas offers  buy vps linux - https://www.albertha.club/buy-vps-linux.html  moving wordpress to new domain and server  web hosting jakarta - https://www.albertha.club/web-hosting-jakarta.html  cpanel  whm vps file manager - www.albertha.club/whm-vps-file-manager.html  vps license  hosting vps fast - https://www.albertha.club/hosting-vps-fast.html  low cost vps germany  cheapest reseller hosting usa - www.albertha.club/...est-reseller-hosting-usa.html  rent dedicated server us  web hosting chile - https://www.albertha.club/web-hosting-chile.html  web server on mac mini  free hosting with wordpress support - www.albertha.club/...g-with-wordpress-support.html  cheapest vps windows  web host providers that support php and mysql - www.albertha.club/...at-support-php-and-mysql.html  free hosting with ftp no ads  vps hostings - https://www.albertha.club/vps-hostings.html  vps server price in india  web hosting platforms - www.albertha.club/web-hosting-platforms.html  web hosting testimonials  web hosting philippines - www.albertha.club/web-hosting-philippines.html  migrate drupal site to new host  fastest wordpress hosting europe - www.albertha.club/...wordpress-hosting-europe.html  web hosting and email hosting separately  unmanaged dedicated server hosting - www.albertha.club/...dedicated-server-hosting.html  how to move wordpress to new domain and server  window vps cheap - https://www.albertha.club/window-vps-cheap.html  free asp domain hosting  enterprise wordpress hosting - www.albertha.club/...rprise-wordpress-hosting.html  vps server provider in india  cheap xen vps - https://www.albertha.club/cheap-xen-vps.html  web hosting coupon codes  best reseller hosting plans india - www.albertha.club/...ller-hosting-plans-india.html  web hosting charges in kolkata  best hosting wordpress - www.albertha.club/best-hosting-wordpress.html  managed vps australia  ssd vps hosting uk - https://www.albertha.club/ssd-vps-hosting-uk.html  web hosting with sql server database  web page hosting and design - www.albertha.club/web-page-hosting-and-design.html  vps servers in china  best vps server usa - https://www.albertha.club/best-vps-server-usa.html  virtual dedicated server hosting uk  private ssl on shared hosting - www.albertha.club/...te-ssl-on-shared-hosting.html  website hosting fees  hosting with dedicated ip - www.albertha.club/hosting-with-dedicated-ip.html

dedicated server quad core
12/10/2017 9:14:46 PM #

move wordpress site to new domain on same server  web host domain - https://www.alona.space/web-host-domain.html  video hosting for wordpress  free reseller hosting business - www.alona.space/...-reseller-hosting-business.html  web hosting sql server  switzerland dedicated server - www.alona.space/switzerland-dedicated-server.html  wordpress buy domain and hosting  windows vps low cost - https://www.alona.space/windows-vps-low-cost.html  web hosting html only  free html hosting site no ads - www.alona.space/free-html-hosting-site-no-ads.html  very cheap dedicated server hosting  virtual private servers - www.alona.space/virtual-private-servers.html  fast wordpress hosting  fastest uk shared hosting - www.alona.space/fastest-uk-shared-hosting.html  canada  dedicated server quad core - www.alona.space/dedicated-server-quad-core.html  hosting  web hosting control panel centos 7 - www.alona.space/...ing-control-panel-centos-7.html  what does shared hosting mean  vps server lowest price - www.alona.space/vps-server-lowest-price.html  how to host site on iis 8  cheapest vps hosting with cpanel - www.alona.space/...st-vps-hosting-with-cpanel.html  best shared hosting account  best vps australia - https://www.alona.space/best-vps-australia.html  web hosting provider manchester  free server vps - https://www.alona.space/free-server-vps.html  cost of dedicated server  cheapest ddos protected vps - www.alona.space/cheapest-ddos-protected-vps.html  top 10 wordpress hosting services  cheap vps servers unlimited bandwidth - www.alona.space/...ervers-unlimited-bandwidth.html  web hosting uk  pay monthly domain hosting - www.alona.space/pay-monthly-domain-hosting.html  web hosting with mongodb  best shared hosting service - www.alona.space/best-shared-hosting-service.html  web hosting reviews consumer reports  top vps hosting europe - www.alona.space/top-vps-hosting-europe.html  vps hosting for wordpress  cheapest vps hosting australia - www.alona.space/...pest-vps-hosting-australia.html  web hosting domain jakarta  linux reseller hosting plan - www.alona.space/linux-reseller-hosting-plan.html  what is reseller hosting india  ubuntu-based dedicated servers - www.alona.space/...tu-based-dedicated-servers.html  cheap us vps  web hosting edinburgh - https://www.alona.space/web-hosting-edinburgh.html  windows dedicated server buy  web hosting in navi mumbai - www.alona.space/web-hosting-in-navi-mumbai.html  web hosting with iis  dota 2 dedicated servers custom games - www.alona.space/...cated-servers-custom-games.html  web hosting services nz  best vps hosting with cpanel - www.alona.space/best-vps-hosting-with-cpanel.html  dedicated server hosting india  best indian dedicated server - www.alona.space/best-indian-dedicated-server.html

web hosting database support
12/10/2017 10:27:26 PM #

difference between virtual server and dedicated server  web hosting open source - www.cassey.space/web-hosting-open-source.html  cheap vps germany  gaming dedicated server - www.cassey.space/gaming-dedicated-server.html   web hosting database support - www.cassey.space/web-hosting-database-support.html  hosting design  dedicated server offers forum - www.cassey.space/...cated-server-offers-forum.html  web hosting panel debian  web hosting providers uae - www.cassey.space/web-hosting-providers-uae.html  website hosting server cost  free vps hosting server - www.cassey.space/free-vps-hosting-server.html  cheap dedicated server cpanel  web hosting list malaysia - www.cassey.space/web-hosting-list-malaysia.html  web hosting solution logistics provider and a crm tool  virtual private server (vps) hosting - www.cassey.space/...rivate-server-vps-hosting.html  best dedicated server plans  unlimited master reseller hosting india - www.cassey.space/...er-reseller-hosting-india.html  managed vps cpanel europe  shared server vs dedicated server in oracle - www.cassey.space/...edicated-server-in-oracle.html  best reseller hosting services  dedicated server hosting for mmorpg - www.cassey.space/...server-hosting-for-mmorpg.html  dedicated mysql server machine  top 10 dedicated hosting - www.cassey.space/top-10-dedicated-hosting.html  cpanel vps optimized system requirements  best unmanaged vps hosting - www.cassey.space/best-unmanaged-vps-hosting.html  best vps hosting reviews  free vps hosting trial windows - www.cassey.space/...vps-hosting-trial-windows.html  web host email accounts  difference between shared server and dedicated server in oracle - www.cassey.space/...edicated-server-in-oracle.html  free hosting sites with wordpress  cheapest dedicated server uk - www.cassey.space/cheapest-dedicated-server-uk.html  virtual private servers australia  cheap high storage vps - www.cassey.space/cheap-high-storage-vps.html  web hosting ssl cert  best dedicated server in usa - www.cassey.space/best-dedicated-server-in-usa.html  dedicated root server germany  most cheap vps - https://www.cassey.space/most-cheap-vps.html  intel core i7-3930k dedicated server  web hosting file manager - www.cassey.space/web-hosting-file-manager.html  web hosting server cost  web hosting and domain name services - www.cassey.space/...-and-domain-name-services.html  website hosting plan  managed wordpress hosting options - www.cassey.space/...wordpress-hosting-options.html  best vps servers  wordpress hosted ssl - https://www.cassey.space/wordpress-hosted-ssl.html  plesk reseller hosting  vps hosting ubuntu server - www.cassey.space/vps-hosting-ubuntu-server.html  shared hosting vs vps hosting  wordpress hosting reseller - www.cassey.space/wordpress-hosting-reseller.html  free video hosting wordpress  windows vps instant setup - www.cassey.space/windows-vps-instant-setup.html

web domain hosting bangladesh
12/10/2017 11:46:31 PM #

web hosting storage costs  best vps low cost - https://www.cassey.space/best-vps-low-cost.html  website creation and hosting cost  cheapest dedicated linux server hosting - www.cassey.space/...ated-linux-server-hosting.html  free reseller hosting uk  move wordpress site to new domain name - www.cassey.space/...s-site-to-new-domain-name.html  ruby on rails hosting server  hongkong dedicated server - www.cassey.space/hongkong-dedicated-server.html  websites hosted in china  affordable dedicated servers - www.cassey.space/affordable-dedicated-servers.html   web domain hosting bangladesh - www.cassey.space/...domain-hosting-bangladesh.html  hosting charges in kenya  can i move my wordpress site to another host - www.cassey.space/...ress-site-to-another-host.html  web hosting india java support  vps hosting windows 2008 - www.cassey.space/vps-hosting-windows-2008.html  web hosting in uk review  web hosting store online - www.cassey.space/web-hosting-store-online.html  dedicated server ip  uk dedicated server hosting - www.cassey.space/uk-dedicated-server-hosting.html  magento slow on shared hosting  web design and hosting contract - www.cassey.space/...sign-and-hosting-contract.html  cheap hosting dedicated server  website with hosting - https://www.cassey.space/website-with-hosting.html  whm reseller hosting cheap  free vps server lifetime - www.cassey.space/free-vps-server-lifetime.html  cheapest vps windows hosting  how to transfer typo3 site to a new host - www.cassey.space/...-typo3-site-to-a-new-host.html  linux master reseller hosting  web hosting plan in malaysia - www.cassey.space/web-hosting-plan-in-malaysia.html  buy vps windows  best affordable dedicated server hosting - www.cassey.space/...-dedicated-server-hosting.html  web hosting html  hongkong dedicated server - www.cassey.space/hongkong-dedicated-server.html  web hosting control panel wordpress  virtual private server (vps) - www.cassey.space/virtual-private-server-vps.html  web hosting in singapore  hosting shared vs dedicated - www.cassey.space/hosting-shared-vs-dedicated.html  free window vps  dedicated server - https://www.cassey.space/dedicated-server.html  domain name and email hosting australia  iis site hosting - https://www.cassey.space/iis-site-hosting.html  web hosting services user reviews  cheap managed vps hosting - www.cassey.space/cheap-managed-vps-hosting.html  how to move wordpress site to another host  website hosting and maintenance uk - www.cassey.space/...osting-and-maintenance-uk.html  managed vps cpanel europe  move wordpress to new server same domain - www.cassey.space/...to-new-server-same-domain.html  shared hosting account  best windows shared hosting - www.cassey.space/best-windows-shared-hosting.html  web hosting site list  netherlands dedicated server 1gbps - www.cassey.space/...ds-dedicated-server-1gbps.html

http://Plancul.win /sitemap26.php
12/11/2017 12:16:17 PM #

ECU Circuits
12/11/2017 7:44:41 PM #

No matter if some one searches for his vital thing, therefore he/she needs to be available that in detail, therefore that thing is maintained over here.

online payday loans no credit check
12/12/2017 7:42:25 PM #

payday loans no credit check  payday loans for bad credit - https://smajloans.com/  payday loans no credit check  loans for bad credit - https://smajloans.com/  payday loans for bad credit

Elisabeth
12/14/2017 12:05:04 PM #

Teremos mais alto agrado em analisar destinado a si.

online casino games
12/15/2017 7:44:41 AM #

free casino slots  casino games free - http://real777money.com/  casino slots  casino slots - http://real777money.com/  online casino games

Add comment