Building a custom silverlight control (with sample code)

First time I had to build my own silverlight control, I asked myself a simple question: From where should I start?

Usually, I start by defining the control specific properties that I will implement as a dependency property, after that I specify the default look for this control.

Through this tutorial, we will build a round button control that could be easily personalized.

Now, let’s open Visual Studio, select NewProject, choose silverlightApplication, follow the wizard and you will get two projects: A webApplication and a silverlightProject.

The Next step is to create a silverlight library. To do this, select the solution explorer right click and choose add NewProject. This time choose silverlightLibary and follow the wizard.


You will end up with something like this:

Dependency Property:
To make our button round, we will use an ellipse. Its width, Height, fill color and stroke color will be specified by the user of our control.

To make that happen we have to add a class in the silverlight class library and make it inherit from Control.

In order to make this class useful we have to:

  • Write a constructor
  • Write the specific properties as Dependency properties

Achieving these two tasks is pretty straightforward, all that we have to do for constructor is to write a line like shown below :

#region Constructor
   public RoundButton()
    : base()
      {
         DefaultStyleKey = typeof(RoundButton);
      }
#endregion

For dependency property, all we have to do is to register the dependency property and implement a setter and a getter for it like the example below:

This code may look cryptic the first time; however don’t worries we will go through it step by step. First this line of code

public static readonly DependencyProperty CircleWidthProperty =
DependencyProperty.Register("CircleWidth", typeof(double), typeof(RoundButton), null);

All that we are doing is registring CircleWidth as a dependency property, this name CircleWidth is very important because it’s the name that will appear in the xaml file when we will use our control in silverlight application, so pick a meanful name.

The first "typeof" is the type of our dependencyProperty.

The second "typeof" is the type of our Control if our class was ShinyButton for example the typeof will be ShinyButton instead of RoundButton here.

For the last parameter, the one set at null it’s a PropertyChangedCallBack that we have to implement in case we want to enable our control to change it’s dependency properties values after that it has been seted, but we don’t really need it for our Control so we pass null.

The  rest of the dependency property is this:

public double CircleWidth{
 
get { return (double)GetValue(CircleWidthProperty); }
 
set { SetValue(CircleWidthProperty, value); }
 
}

This implementation is pretty simple :

For the getter, we have to cast the return to the Property type, double in our case and we have to use the GetValue method that take as parameter CircleWidthProperty that is the DependencyProperty var name.

For the setter we have to use the SetValue method with the appropriate DependencyProperty name as is shown in the picture.

We have to do the same thing for the rest of Dependency Properties and we are done with the control class.

Default Look:
The edition of the default look of our control is done in the generic.xaml file. This file has to be placed under the Themes folder that is created on the silverlight class library. The generic.xaml file has to be a resource file. The generic.xaml.cs file has to be deleted.

Inside the generic.xaml file we have to change UserControl to ResourceDictionary and to import the control namespace.

After that we can start to describe the look of our control.

The generic.xaml has to look something like that:

<resourcedictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:blogexample="clr-namespace:RoundButtonControl">
    <style targettype="blogExample:RoundButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="blogExample:RoundButton">
                    <Canvas>
                    <Grid x:Name="RootElement">
                            <Ellipse x:Name="EllipseElement" Width="{TemplateBinding CircleWidth }"
                              Height="{TemplateBinding CircleHeight}"
                              Fill="{TemplateBinding CircleFillingColor}"
                              Stroke="{TemplateBinding CircleStrokeColor}" RenderTransformOrigin="0.5,0.5" >
                                <Ellipse.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </Ellipse.RenderTransform>
                            </Ellipse>
                            <TextBlock x:Name="TextElement" Text="{TemplateBinding ButtonText}" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" >
                                <TextBlock.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </TextBlock.RenderTransform>
                            </TextBlock>
 
                    </Grid>
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </style>
</resourcedictionary>

Conclusion:

We are done with our simple Silverlight control. It’s definitely not the most useful control in the world, but it’s a good starting point for developing your own.

Keep tuned for part 2 of this Silverlight series.
Download source code: SilverlightBlogExample.rar.