Archive for May 15th, 2007
Basics of Silverlight Alpha Application
After installing everything that is needed to run/build Silverlight alpha application easily. You can launch VS Orcas and select “Silverlight Project” from the new project dialogs. I thought I would spend some time explaining what it creates…
TestPage.html: This is the page that is run when you hit F5 in VS. This page hosts the Silverlight control that runs the application. This page refers to TestPage.html.js file
<html xmlns="http://www.w3.org/1999/xhtml"> <!-- saved from url=(0014)about:internet --> <head> <title>Silverlight Project Test Page </title> <script type="text/javascript" src="Silverlight.js"></script> <script type="text/javascript" src="TestPage.html.js"></script> </head> <!-- Give the keyboard focus to the Silverlight control by default --> <body onload="document.getElementById('SilverlightControl').focus()"> <div id="SilverlightControlHost" > <script type="text/javascript"> createSilverlight(); </script> </div> </body> </html>
This page refers to TestPage.html.js and Silverlight.js files. These files create Silverlight browser plugin at runtime.
TestPage.html.js: This javascript file contains the definition of createSilverlight() function. This function calls into Sys.Silverlight.createObjectEx from Silverlight.js file. Using this function, Page.xaml is also set as the starting page for the Silverlight plugin.
Silverlight.js: this javascript file contains the definition of Sys.Silverlight.createObjectEx that actually creates the browser plugin using information that is passed in.
Page.xaml: This file contains the XAML definition of the page that will be displayed.
<Canvas x:Name="parentCanvas" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="Page_Loaded" x:Class="Basic.Page;assembly=ClientBin/Basic.dll" Width="640" Height="480" Background="White" > </Canvas>
Root of this page is Canvas class and it sets various properties such as Height/Width/Background. One different thing from Silverlight 1.0 Beta is the x:Class attribute.
This attribute defines the fully qualified name of a class. That means it includes Namespace, Classname and relative path to assembly in which this class can be found.
This information is used to hookup the events that are specified in the markup. This means when parser (at runtime) comes across line Loaded=”Page_Loaded”. it will look for Page_Loaded method on the Basic.Page class that exists in the Basic.dll. Few people have asked question about why event handler don’t work and it was because they were missing the x:Class attribute. If this method is not found then parser throws error and it shows up as follows…
Parser also uses this information to download the Basic.dll. So when parser sees the like x:Class or xmlns:Custom (for use of custom control), it asks the downloader to download the assembly required. If the assembly is already downloaded then it does not redownload it but otherwise downloader downloads the assembly and parser uses it to do the resolution. It uses Browser semantic to download the uploaded files rather than using the versioning information.
Page.xaml.cs: This is a code behind file that defines the class mentioned in x:Class attribute.
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Basic { public partial class Page : Canvas { public void Page_Loaded(object o, EventArgs e) { // Required to initialize variables InitializeComponent(); } } }
Page.g.cs: InitizalizeComponent method is a generated method in the file Page.g.cs. This file is generated when you save the XAML file associated with it.
you can look at the this file by clicking on “Show All Files” button on Solution Explorer (or Project menu) and going to Obj/Debug directory. This file is interesting when you add something like this to Page.xaml
<Canvas x:Name="myCanvas" Height="50" Width="50"/>
[Note: Just realized it does not recognize just Name attribute, it has to be x:Name]
This file generates the FindName calls for elements that have x:Name attribute and assigns them to private variables on that class. This is the way you get intellisense when you type in myCanvas in Page.xaml.cs file
//------------------------------------------------------------------------------ // auto-generated // This code was generated by a tool. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // /auto-generated //------------------------------------------------------------------------------ using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Basic { public partial class Page { // variable declarations Canvas myCanvas; private void InitializeComponent() { myCanvas= this.FindName("myCanvas") as Canvas; } } }
ListBox Clipping Issue
Last week I blogged about using ListBox control that is shipped as part of Controls sample pack in SDK for Silverlight Alpha 1.1.
Original Sample has this XAML where it used the ListBox.
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Controls="clr-namespace:Silverlight.Samples.Controls;assembly=ClientBin/Silverlight.Samples.Controls.dll" xmlns:Controls1="clr-namespace:ImageListBox;assembly=ClientBin/ImageListBox.dll" x:Name="parentCanvas" Loaded="Page_Loaded" x:Class="ImageListBox.Page;assembly=ClientBin/ImageListBox.dll" Width="640" Height="480" Background="#FF000000"> <Controls:ListBox Height="350" Width="200" Name="listbox"/> </Canvas>
I just realized when I changed by ListBox height from 350 to 500, it clipped the listbox as shown in the picture where you don’t see the bottom end of the scollbar.
The magic height was 450. Since This SDK have source code with them, I debugged through the sample control and realized that this line of code (text in red) was wrong…
protected override void UpdateLayout() { ... ... //update clipping area RectangleGeometry clip = new RectangleGeometry(); clip.Rect = new Rect(0, 0, Width, Height); Clip = clip; }
This code basically sets the clip on the listbox but the Clip needs to be set on the canvas at the root of the ListBox.xaml
So if you change this method to following code (Text in Orange) in ListBox.cs file, then it sets the clip on the containing canvas and it works correctly
protected override void UpdateLayout() { ... ... //update clipping area RectangleGeometry clip = new RectangleGeometry(); clip.Rect = new Rect(0, 0, Width, Height); //Clip = clip; ActualControl.Clip = clip; }
so now listbox renders correctly…


