Recently, I was learning about Silverlight for a project. Here is what I’m keeping for future reference:

Silverlight 5

A Microsoft platform for developing and deploying Rich internet applications. Right now, it’s a depreceated technology. Runs as a browser plugin. Supports .NET languages like C# and VB.NET, IronPython and IronRuby using DLR (Dynamic Language Runtime).

Installation:

There’re 3 options:

We also need to install the Silverlight SDK.

Creating a Silverlight project

Running the project

If the developer runtime for Silverlight is not installed, the following popup will be shown

When running the project, in case the Silverlight is not installed in the browser, the following browser notification will be shown:

Clicking the install link will take us to the Microsoft website for downloading and installing the plugin

Visual studio settings

From the VS main menu’s Tools -> Options

Assemblies

There are two types of Microsoft Silverlight assemblies:

The core Silverlight assemblies

SDK assemblies, which are used for additional functionalities.

Structure of a Silverlight project

Path in web setting specifies where to put the output .xap files. In the image shown, it’s ClientBin folder.

The initial / startup control can be set from App.xaml.cs.

The Silverlight application is compiled into a .dll which is then used by the Silverlight runtime.

The .csproj file contains the build instructions. During build, VS executes the build instructions contained in the .csproj file. One of the instructions calls the language compiler such as csc.exe for C#, vbc.exe for VB.NET

Although the process is build, a lot of devs call it compiling.

With Solution configuration set to Debug, the Visual studio will create a Debug folder inside the Bin folder of the project. In general cases, there will be 5 files

Deployment

When doing the deployment, the mime types need to be mapped in IIS by following the below steps:

.xap -> application/x-silverlight - For Silverlight 1 and later .xap -> application/x-silverlight-2 (-2 means the second implementation of the mime type) - For Silverlight 2 to 5 .xaml -> ‘application/xaml+xml’

When the application starts up, the Test HTML page (generated inside the Bin folder) asks the browser to load the Silverlight plugin which is specified in the following tag:

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">

The browser plugin then later asks for the .xap file. Which is basically a .zip folder containing application and other .dlls with information inside the application manifest file.

To not allow browser to load the default error page when the Silverlight plugin isn’t available, set the object tag’s autoUpgrade parameter to false

<param name="autoUpgrade" value="false" />

with url set to the download link of the required Silverlight plugin. The javascript onSilverlightError needs to be used. The ErrorCode to watch for is 8001:

function onSilverlightError(sender, args) {

if (args.ErrorCode == 8001) {//code to run when correct Silverlight plugin version isn't available}}

The Silverlight code behind files are in partial classes (one holding the event handling, another for the UI handling). Using a XAML element is equal to instantiating a .NET class. The XML elements are validated against xml namespaces.

Binding

To assign run time calculation of value and assing to a property we need to use Markup extensions. These classes do binding and resource lookup.

When we assign a property in XAML, we’re passing a

Passing values at compile time

<TextBox Text='abc' Background='Orange' />

Passing values at run time

<TextBox Text='{local:LatinWords}' Background='{StaticResource warning}' />

Types of data binding in XAML are:

<!-- Make this element idenfiable by name --><TextBox Text='Hello' x:Name='textHello' Background='Goldenrod' /><!-- Assign value from the above textHello to this element --><TextBox Text='Goodbye' Background='{Binding ElementName=textHello, Path=Background}' />

<!-- Read value red from Text property and assign it to Background property --><TextBox Text='Red' Background='{Binding Text, RelativeSource={RelativeSource Self }}' />

<!-- Define a static resource --><LinearGradientBrush x:Key='seaBrush'><LinearGradientBrush.GradientStops><GradientStop Offset="0" Color="Yellow" /><GradientStop Offset="0.5" Color="Orange" /><GradientStop Offset="0.8" Color="LightCoral" /></LinearGradientBrush.GradientStops></LinearGradientBrush>

<!-- use the seaBrush static resource for the Background property --><TextBox Text='StaticResource' Background='{StaticResource seaBrush}' />

<!-- Null MarkupExtension --><TextBox Text='Null MarkupExtension' Background='{x:Null}' />

<!-- The XML namespace abc is defined which refers to abcLib in UserControl --><UserControl xmlns:abc='clr-namespace:abcLib;assembly=abcLib' >

... rest of the code ...

<!-- use our custom markup extension--><TextBox Text='{abc:LatinWords WordCount=5}' Background='{x:Null}' /></UserControl>

and the implementation of custom markup extension is:

namespace abcLib{public class LatinWords : IMarkupExtension<string>{

public bool RandomStartPoint { get; set; }public int WordCount { get; set; }

private Int32 _numberOfWords;private static Random ran = new Random();private string[] _words;

public void SetupWords(){// for demo limit the number of words to 100if (WordCount <= 1){_numberOfWords = 1;}if (_numberOfWords > 100){_numberOfWords = 100;}else{_numberOfWords = WordCount;}

_words = _sourceString.Split(' ');

}public string ProvideValue(IServiceProvider serviceProvider){SetupWords();int skipCount = 0;if (this.RandomStartPoint){skipCount = ran.Next(3, 20);}return string.Join(" ", _words.Skip(skipCount).Take(_numberOfWords).ToArray());}

private string _sourceString = "Lorem ipsum. ";

}}

Dependency property system — DPS

Silverlight uses a unique property system which was invented by WPF team. This provides services for UI like Animation, Templates, Styles and reduces critical resource usage (e.g. memory). It has two parts:

When creating own user controls, dependency property (e.g. on Button element: FontSize) and .NET property both are correct ways to expose a property on them.

Value resolution priorities

  1. Active animation
  2. Local value
  3. Templated properties
  4. Style setters
  5. Property value inheritance
  6. Default

Case:

Setting dependency properties using code:

private void sampleButton_Click(object sender, RoutedEventArgs e){sampleButton.FontSize = 40; // using a .NET wrapper to set value

double size = sampleButton.FontSize; // use the .NET wrapper to read value

// use the DP system directly

sampleButton.SetValue(FontSizeProperty, 30);size = (double)sampleButton.GetValue(FontSizeProperty);

}

Silverlight elements and controls (default or custom) have lots of dependency properties. This system provides services such as animation, data binding, control templates and styles to the Silverlight elements.To get these services a developer needs to write ‘ugly’ registration code.

An example of declaring and registering a dependency property is:

public partial class StarShape : UserControl {

public StarShape(){InitializeComponent();}

//declaringpublic static readonly DependencyProperty PointsProperty;

//registeringstatic StarShape(){

// 2. Register with the DP systemPointsProperty = DependencyProperty.Register("Points", typeof(double), typeof(StarShape), null);

}}

Notice that the property is declared readonly, which means it can only be instantiated in it’s static constructor.

Attached dependency property

They are a special dependency property to provide decoupled extensible model. We can think of it as a ‘global property’ meaning it is available to all controls in Silverlight runtime.

It is owned and registered by a Type. The method for the same is DependencyProperty.RegisterAttached. It uses the dotted syntax TypeName.AttachedProperty. These properties are mostly used in layout panels Canvas, Grid, DockPanel.

Key points:

Photos

Originally published at xameeramir.github.io.