What is Silverlight?

Microsoft silverlight

courtesy

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:

  • Install silverlight using WPI
  • Install Expression blend for designing purposes
  • Install XNA Game studio for working with 3D

We also need to install the Silverlight SDK.

Creating a Silverlight project

  • Create a new project in VS under C# -> Silverlight

Creating a Silverlight project

  • Make sure to check Host the Silverlight application in a new website

Running the project

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

developer runtime for Silverlight is not installed

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

Running Silverlight in Chrome

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

  • For All languages: enable word warp and line number under General node
  • Set Tab and indent size to 2 under Tabs node. Also keep tabs

Assemblies

There are two types of Microsoft Silverlight assemblies:

The core Silverlight assemblies

  • mscorlib.dll
  • System.Core.dll
  • system.dll
  • System.Net.dll
  • System.Windows.dll

SDK assemblies, which are used for additional functionalities.

Structure of a Silverlight project

  • App.xaml file contains Global settings and global events
  • MainPage.xaml is the main Silverlight UI

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

  • The application AppManifest file - contains the application information
  • The application .dll file - the actual code which will be loaded by the Silverlight runtime when executing the project
  • The application .pdb file - the portable debug file for the project
  • The application .xap file - the zipped bundle of AppManifest and the application .dlls. This is useful in cases when the application uses SDK assemblies. The zip bundle will help the client download the SDK .dlls
  • The application test .html file - the application test file generated by the Properties -> Debug -> Start Action set to Dynamically generate a test page

Deployment

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

  • Select the application in concern from Sites node
  • Double click Mime Types and the entries as shown below:

.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

  • string
  • passed through a TypeConverter (and the conversion happens at the compile time)

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:

  • Binding: binding by Data source
  • Template: get value from control template and assign it to property
  • StaticResource: Lookup resource defined in ResourceDictionary
  • Null: Assing null value to preperty
  • Element to element binding:

<!-- 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}' />
  • Self binding:

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

<!-- 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 binding:

<!-- Null MarkupExtension -->
<TextBox Text='Null MarkupExtension' Background='{x:Null}' />
  • Custom markup extension binding:

<!-- 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 100
      if (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:

  • Dependency properties
  • Attached properties

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.

  • First, create a dependency property to work with the Silverlight services like data binding
  • Second, create a .NET property to set and read property values in code

Value resolution priorities

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

Case:

  • If the local value for a property is set to 20 and the control in concern is getting animated changing property value from 40 to 80
  • When we query the value of the property, the value set by the current animation step will be returned, as per the above priority list

Setting dependency properties using code:

  • In XAML file

<Button x:Name='sampleButton' Content='Set the Properties in Code' Click='sampleButton_Click' />
  • In code behind

		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();
	}

	//declaring
	public static readonly DependencyProperty PointsProperty;

		//registering
		static StarShape()
		{

			// 2. Register with the DP system
			PointsProperty = 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:

  • Attached property value is stored in DPS
  • Value is assigned with element assigning the value
  • The owning class will query the value from the DPs

Photos