Silverlight Password Strength Checker – Part 1 of 3

Introduction

In this 3 part series, we are going to learn how to create a custom control, the parts and states of custom control and skinning. We will create a simple password strength checker, which will tell how strong your password is. In part 1, we will see how to create a fully usable custom control.

Overview

A Custom Control is same as any other User Control except the fact that it comes with the power of editable Styles and Templates. For more details, see Control Customization on MSDN.

You Will Learn
  • What is a Silverlight Class Library
  • How to create a Custom Control using a Class Library
  • How to create properties that can be accessed both from Xaml and code-behind

Before going further, let’s have a look at what we are going to create.

Install Microsoft Silverlight
Creating The Solution

1. Open Visual Studio and create a new Silverlight Application, name it SilverlightPasswordStrength.

2. In MainPage.xaml, add the following row definitions to the Grid,

<Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>

3. Add a TextBlock to the first row,

<TextBlock Text="Silverlight Password Strength Demo" HorizontalAlignment="Center" Margin="0,15,0,0" FontSize="16" FontWeight="Bold"/>

4. And add a StackPanel with another TextBlock and a PasswordBox to the second row,


<StackPanel Orientation="Horizontal" VerticalAlignment="Top"
HorizontalAlignment="Center" Grid.Row="1" Margin="0,50,0,0">

<TextBlock Text="Password" VerticalAlignment="Center" FontWeight="Normal" Foreground="#FF2E2E2E" FontFamily="Portable User Interface"
 FontSize="13" TextAlignment="Left"/>

<PasswordBox x:Name="pwdPassword" Width="200" Height="35" Margin="5,0,0,0"/>

</StackPanel>

By now, your UI should look like this,

image

Creating The Custom Control

1. Add a new Silverlight Class Library to the solution, name it PasswordStrengthChecker.

2. Rename the Class1.cs to PasswordStrengthChecker.cs, and derive it from Control.

public class PasswordStrengthChecker : Control
{

//...

}

3. Right-click on the project and select add new folder. Name it Themes.

4. Right-click on the Themes folder and select ‘Add New Item’. Add a new Xml File and name it generic.xaml.

Now, your Solution Explorer should look like this,

image

A Custom Control requires a control class and the default control template. You can place the control class in any code file template in your Silverlight class library. The control template must be placed in a file named generic.xaml. If your class library contains multiple controls, all of their default templates must be placed in the same generic.xaml file.

Creating the Control Template

The generic.xaml file holds a resource dictionary with a style for each custom control. The style must set the Template property of the corresponding control to apply the default control template.

1. In the generic.xaml file, declare a resource dictionary and Map the project namespace to an XML namespace prefix, so you can access your custom control in your markup.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:PasswordStrengthChecker"> 
<!--Resource Dictionary Content-->
</ResourceDictionary>

2. Inside the ResourceDictionary, define the style for the control.


<Style TargetType="local:PasswordStrengthChecker">

<Setter Property="Template">

	 <Setter.Value>

	 <ControlTemplate TargetType="local:PasswordStrengthChecker">

				<!--Template Content-->

	 </ControlTemplate>

 </Setter.Value>

</Setter>

</Style>

3. For now let’s define a simple template with a Border and ContentControl.


<Style TargetType="local:PasswordStrengthChecker">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="local:PasswordStrengthChecker">

<Grid>

<Border BorderBrush="Black" BorderThickness="1">

 <ContentPresenter x:Name="ContentElement" HorizontalAlignment="Center" VerticalAlignment="Center"/>

</Border>

</Grid>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

ContentElement is our content holder where we will show the required information, in this case the password strength.

Defining The Properties

1. Go to PasswordStrengthChecker class and in the constructor set the DefaultStyleKey property.


public PasswordStrengthChecker()

{

DefaultStyleKey = typeof(PasswordStrengthChecker);

}

The DefaultStyleKey tells the control to pick up the default style from the generic.xaml file. DefaultStyleKey indicates the type that is used to look up the style.

2. The first property we need is the PasswordBox control for which we need to calculate the password strength. Add the following DependencyProperty, which can take a PasswordBox.


public static readonly DependencyProperty PasswordControlProperty =

	DependencyProperty.Register("PasswordControl", typeof(PasswordBox),

		typeof(PasswordStrengthChecker), null);

	public PasswordBox PasswordControl

{

	get		{			return (PasswordBox)base.GetValue(PasswordControlProperty);

	}

		set

	{

			base.SetValue(PasswordControlProperty, value);

	}

	}

3. Add another read-only property PasswordStrength, using which the calculated password strength can be read.

<pre>public static readonly DependencyProperty PasswordStrengthProperty =
DependencyProperty.Register("PasswordStrength", typeof(string),
typeof(PasswordStrengthChecker), new PropertyMetadata("Not Valid"));
public string PasswordStrength
{
get { return (string)base.GetValue(PasswordStrengthProperty); }
private set
{
base.SetValue(PasswordStrengthProperty, value);
NotifyPropertyChanged("PasswordStrength");
}
}

4. When the control is being initialized, the protected method OnApplyTemplate from the base Control class will be called. So, let’s override the OnApplyTemplate method to do our initialization activities.

</pre>
<pre class="alt"><span class="lnum">
<pre>  public override void OnApplyTemplate()
  {
       base.OnApplyTemplate();
       //Get the template item named 'ContentElement' and set default value
       (this.GetTemplateChild("ContentElement") as ContentPresenter).Content =
                                                              PasswordStrength;
      //If the PasswordBox Control is not null, wire-up the PasswordChanged event
      //where we will calculate the password strength
       if(PasswordControl != null)
       {
            PasswordControl.PasswordChanged += new RoutedEventHandler
                                              (PasswordControl_PasswordChanged);
       }
}</pre>
</span></pre>
<pre class="alt"><span class="lnum">


The GetTemplatedChild method is used to find an element from the template with specific name.

5. Write the following code, to calculate the password strength and update the content in the template with the calculated value.

</pre>
<pre class="alt">Regex rgLowerCase = new Regex(@"[^a-z]");</pre>
<pre class="alt">Regex rgUpperCase = new Regex(@"[^A-Z]");</pre>
<pre class="alt">Regex rgNumeric = new Regex(@"[^0-9]");</pre>
<pre class="alt">Regex rgSpecialChar = new Regex(@"[/\|_!@#$%^&*()=+.-]");</pre>
<pre class="alt">private void CalculatePasswordStrength(string p)</pre>
<pre class="alt">{</pre>
<pre class="alt">string[] strengths = new string[6] {</pre>
<pre class="alt">                               "Very Weak",</pre>
<pre class="alt">                               "Weak",</pre>
<pre class="alt">                               "Better",</pre>
<pre class="alt">                               "Medium",</pre>
<pre class="alt">                               "Strong",</pre>
<pre class="alt">                               "Very Strong"};</pre>
<pre class="alt">    int strength = 0;</pre>
<pre class="alt">    if (p.Length > 8 )</pre>
<pre class="alt">    {</pre>
<pre class="alt">       strength++;</pre>
<pre class="alt">         if (rgLowerCase.IsMatch(p) && rgUpperCase.IsMatch(p))</pre>
<pre class="alt">            strength++;</pre>
<pre class="alt">            if (rgNumeric.IsMatch(p))</pre>
<pre class="alt">                 strength++;</pre>
<pre class="alt">                 if (rgSpecialChar.IsMatch(p))</pre>
<pre class="alt">                     strength++;</pre>
<pre class="alt">                  if (p.Length > 14)</pre>
<pre class="alt">                      strength++;</pre>
<pre class="alt">    }</pre>
<pre class="alt">      PasswordStrengthValue = strength * 20;</pre>
<pre class="alt">    PasswordStrength = strengths[strength];</pre>
<pre class="alt">      if (string.IsNullOrWhiteSpace(p))</pre>
<pre class="alt">        PasswordStrength = "Not Valid";</pre>
<pre class="alt">      //Set new strength value to the ContentElement</pre>
<pre class="alt">    (this.GetTemplateChild("ContentElement") as ContentPresenter).Content =</pre>
<pre class="alt">                                                           PasswordStrength;</pre>
<pre class="alt">   }</pre>
<pre class="alt">

Using The Custom Control

Now our Custom Control is ready. Let’s go back to our SilverlightPasswordStrength project and see how we can use this.

1. Right-click on the project and select ‘Add Reference…’. Under Projects tab, select PasswordStrengthChecker.

image

2. In MainPage.xaml, add a new namespace declaration to access the Custom Control.

</pre>
<pre class="alt">
<pre>xmlns:tools="clr-namespace:PasswordStrengthChecker;assembly=PasswordStrengthChecker"

3. Create the Custom Control in the StackPanel and set the PasswordControl property,

</span></pre>
<pre class="alt"><span class="lnum">
<pre><StackPanel Orientation="Horizontal" VerticalAlignment="Top"
              HorizontalAlignment="Center" Grid.Row="1"
              Margin="0,50,0,0">
    <TextBlock Text="Password" VerticalAlignment="Center" FontWeight="Normal"
               Foreground="#FF2E2E2E" FontSize="13" TextAlignment="Left"/>
    <PasswordBox x:Name="pwdPassword" Width="200" Height="35" Margin="5,0,0,0"/>
    <tools:PasswordStrengthChecker x:Name="pwdChecker" Margin="10,0,0,0"
             PasswordControl="{Binding ElementName='pwdPassword'}" Width="100"/>
</StackPanel></pre>
</span></pre>
<pre class="alt"><span class="lnum">

As the PasswordControl property takes a PasswordBox control, I used Element Binding to provide the control. If you want to set the same property from the code-behind, it should be as follows,

</pre>
<pre class="alt">
<pre>pwdChecker.PasswordControl = pwdPassword;</pre>
</pre>
<pre class="alt">

Run the application and type something in the password box, to see how our custom control behaves.

Download:

SL_PasswordStrength (SourceCode)

Summary

In Part 1, we learned how to create and use a custom control. In next part, we will see how to add States and Template Parts to the custom control.

Thank you for reading, please share your thoughts and suggestions in the Comments section.

3 thoughts on Silverlight Password Strength Checker – Part 1 of 3

  1. Hi,

    I found a problem with your code. The checker no longer works if you put the control in a DataField which is usually the case when we use DataForm to collect data. The PasswordControl in the Checker is always NULL.

    <

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *