Building WP7 Custom Validation Control - Architecture & Basic Prototype
published on: 4/6/2011 | Views: N/A | Tags: CustomControls UI
by WindowsPhoneGeek
I am starting a series of 3 posts: "Building WP7 Custom Validation Control " in which I am going to talk about how to implement a fully functional, extensible and easy to use WP7 Validation Custom Control.
- Building WP7 Custom Validation Control - Architecture & Basic Prototype
- Building WP7 Custom Validation Control - Validation Logic
- Building WP7 Custom Validation Control - Custom Validation Rules
This is the first articles, so I will start with architecture and basic prototype implementation.
The idea
Basically our VaidationControl will derive from TextBox and will enable users to define different validation rules(patterns). It is actually some kind of extended TextBox that displays a customizable "ValidationContent" area (error message, icon, etc.) whenever its content does not fit the validation requirements. Once data is entered in the input area the validation is performed on LostFocus.
The final goal is to build a fully functional, extensible, stylable and easy to use validation control with custom logic that can be used in a Silverlight for Windows Phone 7 application.
ValidationControl Architecture
Here is how the basic structure of our ValidationControl should look like:
Generally the control will have three important parts:
1. Input area - this is the input text box where users will enter data to be validated.
2. Validation Symbol - this is the indication symbol that the entered text is incorrect i.e. does not fit in the requirements (the selected Validation Rule).
3. Validation Content - this is a composite content that appears whenever the entered text in no valid. It can be text description, image or entirely customized control.
If the entered Text is incorrect then "Validation Content " and "Validation Symbol" areas are visible otherwise they are collapsed.
Here are the basic UIElements that form the ControlTemplate of the ValidationControl :
As you can see it basically consists of three ContentControls that can be fully customized.
ValidationControl is a custom control that derives from TextBox and will extend its functionality with lots of custom properties and logic.
Creating the basic VaidationControl prototype
NOTE: For more information about how to create a Custom Control in Windows Phone 7 check out our previous post "Creating a WP7 Custom Control in 7 Steps". You can also may find interesting the following article:"User Control vs Custom Control in Silverlight for WP7"
To begin with lets create a Windows Phone 7 Class Library project and follow the 7 steps I described previously. We will create a control called VaidationControl which derives from TextBox. The basic steps are as follows:
Step 1 - Create the project
Step 2 - Create a VaidationControl.cs class with the following code:
public ValidationControl()
{
DefaultStyleKey = typeof(ValidationControl);
}
Step 3 , Step 4, Step 5 and Step 6 - Create a generic.xaml file and add there the following Style/ControlTemplate (We will use as a basis the default Style of the WP7 TextBox control and will add some additional elements into it).
Generic.xaml
<Style TargetType="local:ValidationControl">
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
<Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ValidationControl">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="400" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
</Border>
<Border Grid.Column="0" Grid.Row="0" x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed">
<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}" />
</Border>
<ContentControl Grid.Row="0" Grid.Column="1" Visibility="Collapsed" Foreground="Red" x:Name="validationSymbol" Content="{TemplateBinding ValidationSymbol}"/>
<ContentControl Grid.Row="1" Grid.ColumnSpan="2" Visibility="Collapsed" Foreground="Red" HorizontalAlignment="Left" x:Name="validationContent" Style="{TemplateBinding ValidationContentStyle}" Content="{TemplateBinding ValidationContent}" Background="Transparent" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
NOTE: We use "TemplateBinding" in order to bind properties of the Visual Elments to properties of the control class (i.e.use TemplateBinding in a template to bind to a value on the control the template is applied to).
NOTE: We need to add TemplateBinding to some of the elements and also some "x:Name" attributes.
Implementing Custom Properties
- We will add the following dependency properties :
- ValidationRule - This is a dependency property of type IValidationRule. It determines the validation rule(pattern) to be used. The default value in a RegEx rule.
NOTE: I will explain in details all about the implementation of the validation rules and IValidationRule interface in the next post of this series: Building WP7 Custom Validation Control - Validation Logic
- ValidationContent- This is a dependency property of type object. It gets or sets the content displayed as a ValidationContent below the input box when the text does not fit in the validation requirements.
NOTE: The ValidationContent is typically text that indicates that the entered text in the input box is not correct. For example, the ValidationContent might displays the text "Incorrect E-mail address" until the user enters a valid e-mail address. But it can be a composite object as well .Any object that derives from UIElement can be used. For example, a ValidationContent might display an Image, TextBlock with customized properties, etc.
- ValidationSymbol - This is a dependency property of type object. It gets or sets the content displayed as a Validation Symbol on the right side of the input area when the text does not fit in the validation requirements
- ValidationContentStyle- This is a dependency property of type Style. It can ne used to customize the Style of the ValidationContent element.
- IsValid - This is a dependency property of type bool. It determines whether the entered text value in the input area is valid or not.
NOTE: When creating a custom control you can set a custom dependency DependencyPropertiy default value either in code or in XAML using Style Setters.
The source code is as follows:
public static readonly DependencyProperty IsValidProperty =
DependencyProperty.Register("IsValid", typeof(bool), typeof(ValidationControl), new PropertyMetadata(true, new PropertyChangedCallback(ValidationControl.OnIsValidPropertyChanged)));
public static readonly DependencyProperty ValidationRuleProperty =
DependencyProperty.Register("ValidationRule", typeof(IValidationRule), typeof(ValidationControl), new PropertyMetadata(new PropertyChangedCallback(ValidationControl.OnValidationRulePropertyChanged)));
public static readonly DependencyProperty ValidationContentProperty =
DependencyProperty.Register("ValidationContent", typeof(object), typeof(ValidationControl), new PropertyMetadata("Incorrect Value", new PropertyChangedCallback(ValidationControl.OnValidationContentPropertyChanged)));
public static readonly DependencyProperty ValidationSymbolProperty =
DependencyProperty.Register("ValidationSymbol", typeof(object), typeof(ValidationControl), new PropertyMetadata("!", new PropertyChangedCallback(ValidationControl.OnValidationSymbolPropertyChanged)));
public static readonly DependencyProperty ValidationContentStyleProperty =
DependencyProperty.Register("ValidationContentStyle", typeof(Style), typeof(ValidationControl), null);
public bool IsValid
{
get { return (bool)base.GetValue(IsValidProperty); }
set { base.SetValue(IsValidProperty, value); }
}
public Style ValidationContentStyle
{
get { return base.GetValue(ValidationContentStyleProperty) as Style; }
set { base.SetValue(ValidationContentStyleProperty, value); }
}
public object ValidationContent
{
get { return base.GetValue(ValidationContentProperty) as object; }
set { base.SetValue(ValidationContentProperty, value); }
}
public object ValidationSymbol
{
get { return base.GetValue(ValidationSymbolProperty) as object; }
set { base.SetValue(ValidationSymbolProperty, value); }
}
Another important thing we need to mention the the PropertyChangedCallback handlers. We will use this property change call back in order to make sure that the every time when a particular property changes (including the first time when our control loads) our VaidationControl will show/hide its ValidationContent element in the right way.
private static void OnIsValidPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//later we will add some code here
}
private static void OnValidationSymbolPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//later we will add some code here
}
private static void OnValidationContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//later we will add some code here
}
private static void OnValidationRulePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//later we will add some code here
}
That is the end of the first post in this series of article: "Building WP7 Custom Validation Control - Architecture & Basic Prototype". I will publish the full source code and a demo project in the next post of this series: "Building WP7 Custom Validation Control - Validation Logic " in the upcoming article.
I hope that the article was helpful. Stay tuned with the rest of WindowsPhoneGeek.com content.
You can also follow us on Twitter @winphonegeek
Comments
Our Top Articles & Free books
- Our FREE e-book: "Windows Phone Toolkit In Depth" 2nd edition
- 400+ Windows Phone Development articles in our Article Index
- 21 WP7 Toolkit in Depth articles covering all controls
- 12 WP7 Coding4Fun Toolkit in Depth articles covering all controls
- Performance Tips when creating WP7 apps
- Creating a WP7 Custom Control in 7 Steps
- WP7 working with VisualStates: How to make a ToggleSwitch from CheckBox
- What makes a WP7 App successful
- Creating theme friendly UI in WP7 using OpacityMask
- Implementing Windows Phone 7 DataTemplateSelector and CustomDataTemplateSelector
- All about Splash Screens in WP7 – Creating animated Splash Screen
- Getting Started with Unit Testing in Silverlight for WP7
- WP7 WatermarkedTextBox custom control
Our Top Tips & Samples
- All about WP7 Isolated Storage series
- WP7 Dynamically Generating DataTemplate in code
- 5 tips for a successful WP7 Marketplace submission
- WP7: Navigating to a page in different assembly
- WP7 ContextMenu: answers to popular questions
- WP7 ListBox: answers to popular questions
- WP7 working with Images: Content vs Resource build action
- WP7 Element Binding samples
- WP7 working with XML: reading, filtering and databinding
- Drawing in WP7: #2 Drawing shapes with finger
- WP7 TextBox Light theme problems - the solution
- Changing the WP7 Panorama Background Image dynamically with Animation
