Silverlight 1.0 full Javascript Intellisense

1 באוגוסט 2007

6 תגובות

Everything we do here today is recorded in a 40 minute Webcast available at:


Let's create a new Silverlight 1.0 project in Expression Blend 2 August preview, change the background color of our first page to "LightGreen" and draw a small rectangle. This is how our XAML file looks like right now:




    Width="640" Height="480"

    Background="#FF90EE90" <– LightGreen

    x:Name="Page" <– Name of Canvas



    <Rectangle x:Name="myRectangle" Width="240" Height="144" Stroke="#FF000000" Canvas.Left="200" Canvas.Top="144"> <– Small Rectangle



This basic XAML file has a Canvas and a rectangle on it. Let's change the rectangle so it will look like this:


    <Rectangle x:Name="myRectangle" Width="240" Height="144" Stroke="#FF000000" Canvas.Left="200" Canvas.Top="144">


            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">

                <GradientStop Color="#FF1F4AB5" Offset="0.053"/>

                <GradientStop Color="#FFD97F38" Offset="0.779"/>




And a Starboard so the rectangle changes background colors over a period of two seconds.


        <Storyboard x:Name="changeBackground">

            <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="myRectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">

                <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFD97F38"/>

                <SplineColorKeyFrame KeyTime="00:00:02.1000000" Value="#FF6BD938"/>


            <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="myRectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">

                <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF1F4AB5"/>

                <SplineColorKeyFrame KeyTime="00:00:02.1000000" Value="#FF5B0E54"/>




Finally we want a Javascript function called "CanvasLoaded" to fire when the canvas is loaded.




    Width="640" Height="480"








<Rectangle x:Name="myRectangle" Width="240" Height="144" Stroke="#FF000000" Canvas.Left="200" Canvas.Top="144">




Let's see how this screen looks like in Expression Blend 2 August Preview:


Pretty straight forward. Now let's see our "CanvasLoaded" function that's located in our "Default_html.js" file using Visual Studio 2008 Beta2.


Well, this is the canvas loaded event so the sender must be of type Canvas!
We are sure to get intellisense for Canvas.


Wait, What??? No intellisense for Canvas?

Well, I'd like to print out the background color of our Canvas.
So what will we write?

hmm.. well, I guess I can work without intellisense and write something up.


Ok, We need Silverlight Javascript Intellisense!

How to setup Silverlight 1.0 Javascript Intellisense in Visual Studio 2008 Beta 2 with Visual Studio Extensions for Silverlight:

 1. Go to and download the latest "Javascript Silverlight Intellisense" release.

 2. Open the zip file. And we get two files:


3. Drag & Drop these two files into Visual Studio 2008 Beta 2 project.

4. Add a script reference at the top of our JS file.

/// <reference path="intellisense.js" />


5. Add a script src to intellisense.js in our HTML page.

<script type="text/javascript" src="intellisense.js"></script>



That's It!
We're done.
You now have Javascript Intellisense for Silverlight 1.0.


First thing we have to do is convert our "sender" to a strongly-typed Canvas object.


Now let's see what we got from this strange Convert.ToCanvas function.


image_thumb11 image_thumb12 image_thumb13 image_thumb14

We get Full intellisense for Silverlight objects in our Javascript code!

We get properties, we get Events, We get methods, we get collections, we get indexers, and it's all strongly typed!


Working with Properties

So let's print out the background of our Canvas.


We even get SDK comments inside our Javascript!


But what's this… This background property gives us a "Brush"? What's a brush?


Wait, We used a SolidColorBrush, so what's the relation between that and This Brush thing?


Ok, So let's Convert our Brush to SolidColorBrush.


And we got the new Color property!
Let's print it out.


On our screen we get:


We got -7278960 which is an aRGB value that stand for LightGreen.

So let's do something a little more tricky, let's change the background for out Canvas.
We'll create a new SolidColorBrush.






And our background color has changed!



Working with Methods


Do you remember we added an animation so our Storyboard will change it's background colors?
Let's start that Storyboard.


        <Storyboard x:Name="changeBackground">




Let's use the findName method on our canvas.



Did you notice our FindName method returns a "DependencyObject" type class?


We need to convert our general DependencyObject back to a Storyboard.









Working with Events & Global Typed variables

Let's catch a left mouse button click and cause our canvas to change it's Opacity to 0.3.



function CanvasLoaded(sender, eventArgs)


        var someElement = Convert.ToCanvas(sender);






function OnMouseLeftButtonDown(sender, eventArgs)




We can see that our Canvas element is out of scope in the new OnMouseLeftButtonDown method, so we'll have to move someElement to a higher scope.

var someElement;

function CanvasLoaded(sender, eventArgs)


        someElement = Convert.ToCanvas(sender);





function OnMouseLeftButtonDown(sender, eventArgs)



Let's see how are we dealing intellisense wise.

image_thumb39 image_thumb40

We get intellisense for someElement in CanvasLoaded after we converted sender to Canvas, but not inside OnMouseLeftButtonDown.
We need to define someElement as a global variable of type Canvas.


Not let's change the opacity to 0.3 like we wanted.


And the end result…

Before clicking left mouse button:





Working with Inline Functions (Anonymous Delegates) & Attached Properties

Let's make our rectangle move around the Canvas as we press the arrow keys on the keyboard.



This is very similar syntax to that used by C# 2.0 Anonymous delegates.

In order to get which key was pressed we need our eventArgs.Key property, so let's convert our eventArgs.


I happen to know (because Jon Galloway told us) that "15" stand for the Up Arrow keyboard button.


Well, now we need to move our Rectangle up… So let's change it's "Canvas.Top" attached property.image_thumb49

Please note we are using "setValue" and "getValue" of DependencyObject and they aren't exclusive for Rectangle.


Let's create our "Canvas.Top" dependency property.


        someElement.add_KeyUp(function(sender, eventArgs)


                                    var e = Convert.ToKeyboardEventArgs(eventArgs);


                                    if (e.get_key() == 15)


                                        var rect = someElement.findName("myRectangle");

                                        var top = Convert.ToDependencyProperty("Canvas.Top");

                                        rect.setValue(top, rect.getValue(top) – 10);



Before we click the up arrow button:
Polymorphism and the Is/As patten
If you've ever used C# you'll be very familiar with the Is/As patterns for type conversion.
The Is Type Conversion pattern:


The As Type Conversion Pattern:


What we're seeing here is basic Polymorphism. We're getting a type of Perctangle, Changing it's reference type back to it's parent class DependencyObject and then back To Rectangle.


We have similar patterns to the C# Is/As patterns in our Javascript code.

The Javascript Is pattern:


The Javascript As pattern:



The "Convert.IsXXX" method returns a value whatever the element is convertible to XXX.
The "Convert.ToXXX" method returns null if the value is not convertible to XXX.


Working with Extension Methods

Let's say it's very common for us to change the "Canvas.Top" attached property we've seen earlier on Rectangles.
So common in fact, it should be an Extension Method.

We'd like to add it to the intellisense for Rectangle Class without changing the original class code.

The C# 3.0 Syntax looks like this:



We added a new method to our Rectangle class without even changing it's code!

Let's do the same in Javascript Silverlight objects.

We'll create a new file called "Extensions.js" (just because it's a good name):


We need to add a reference to our intellisense.js file.
I'll do that by selected the "intellisense.js" file in the Solution explorer and drag&drop into our Extensions.js file.


Let's add our Extension method to Rectangle.




We need to make sure "ChangeByHowMuch" is a known Number type so we'll add a param statement.


Now let's change the Canvas.Top of our Rectangle.



Now let's script tag reference to this Extensions.js file to our HTML page.



And we need to reference our Extensions.js file where ever need intellisense.


Please note that we not longer reference the intellisense.js file directly as our extensions.js reference it so we don't need to.



After running this code we can see the rectangle is on the bottom of our Canvas:



Type Safety, Element hidden field & Javascript Debugging

Let's take a look at this method:


It's expecting a Number of type Double. So this argument will be acceptable:


But what about…

      canvas.set_opacity("really shiny opacity please!");

Let's first run this code directly to the "Canvas" Silverlight clr type.

We can access it by using the "Element" hidden field on our Silverlight Javascript classes.


Notice that we don't get any intellisense for our element types.

      var canvas = Convert.ToCanvas(sender);

      canvas.element.opacity = "really shiny opacity please!";

We get this somewhat cryptic error message straight for the Silverlight 1.0 CLR:


Let's try this with our Silverlight Javascript Intellisense objects.

      var canvas = Convert.ToCanvas(sender);

    // canvas.element.opacity = "really shiny opacity please!";


      canvas.set_opacity("really shiny opacity please!");

And we get:


Let's open our Call-stack window for debugging javascript.


And in the call stack we can see:


We can see it's a TypeSafety check that failed.
Let's double click on the second line:


And we can see in our editor:


Now, just for the heck of it, Let's open our Quick Watch Windows (CRTL + ALT + Q since VS2003) and evaluate "this".




We can see all the Properties, Methods and Events on our Silverlight Javascript Intellisense objects.

Let's examine "this.element" which is the normal Silverlight CLR 1.0 object.


Nothing, we get not Javascript debugging watch for native Silverlight objects.


Now, let's try to add a string to our "Canvas.Children" collection.



      var canvas = Convert.ToCanvas(sender);

      canvas.get_children().add("blue shiny rectangle");

And we get the following runtime error:


Let's try something more subtle. Remember this code?


We used polymorphism to send a SolidColorBrush which inherits from Brush as a Brush Parameter.
Let's convert the SolidColorBrush back a DependencyObject and send it to the method:


This works fine and no errors are raised.

Let's try sending a Rectangle which is referenced as a DependencyObject.


We get the following error:


We need a Brush.
We can get a SolidColorBrush since it inherits from Brush.
We can get a DependencyObject of SolidColorBrush since SolidColorBrush still inherits from Brush.
We cannot Convert a DependencyObject of Rectangle to a Brush.


Using the custom intellisense javascript syntax for development causes a deployment issue.

Do we deploy "intellisense.js" to our Client's browser? or do we Strip intellisense features from our Javascript code?
We can do which ever suits us.


Deployment with Intellisense.js file

Have a look at the file size of "intellisense.js":


It's more then 1mb! That's huge!

And most of it is essiently comments, spaces and variable names anyhow.
So with the download of the "intellisense.js" file you get a called "intellisense.compressed.js" which is a stripped down version of the "intellisense.js" file.

You can change the script tag HTML reference to this compressed JS file and your clients will only download the compressed version while you still get full intellisense.



As part of the generation of the "Intellisense.js" file we use Atif Aziz's Javascript compressor to create this compressed version.
You can see it only compresses to about 40% of the full intellisense.js file.

There are literally hundreds of javascript compressors out there and some compressed our "intellisense.js" file to a mere 100kb file.
If you want to find them just Google the phrase: "Javascript compressor" OR "Javascript shrink"

However, with the download I can only ship a compressed file from a .Net based software.
But feel free to use your own compressor on this file and deploy it as you please.

If you find a compressor with better results and It's written in .Net I'll be glad to use it.


Deployment without intellisense.js file

There two downloads the project's codeplex page  at
The first contains only the two javascript files mentioned previously.


 The second contains the code for the .Net software which generates the "intellisense.js".
Don't worry you don't need it.

Inside that software there's the following screen:


(What you're probably thinking right now is: "so, this is the guy that's telling me how to use Silverlight? that has to be the ugliest screen ever!")

Let's take the following javascript code we've written today:

var someElement = Convert.ToCanvas(null);

function CanvasLoaded(sender, eventArgs)


    someElement = Convert.ToCanvas(sender);


    var brush = Convert.ToSolidColorBrush(someElement.get_background());




    var newBrush = SolidColorBrush.createFromXaml(sender.getHost());


    var newBrushAsDependencYObject = Convert.ToDependencyObject(newBrush);










    someElement.add_KeyUp(function(sender, eventArgs)


                                var e = Convert.ToKeyboardEventArgs(eventArgs);


                                if (e.get_key() == 15)


                                    var rect = someElement.findName("myRectangle");

                                    var top = Convert.ToDependencyProperty("Canvas.Top");

                                    rect.setValue(top, rect.getValue(top) – 10);




And copy it into the "Javascript with intellisense" TextBox.


We get the same javascript code but without any of the intellisense features.

It uses the plain Silverlight CLR objects.

Here's the full translated code:

var someElement = null;

function CanvasLoaded(sender, eventArgs)


    someElement = sender;


    var brush = someElement.background;




    var newBrush = sender.getHost().content.createFromXaml("<SolidColorBrush />");

    newBrush.color = "Aqua";

    someElement.background = newBrush;




    someElement.addEventListener("MouseLeftButtonDown", OnMouseLeftButtonDown);  


    someElement.addEventListener("KeyUp", function(sender, eventArgs)


                            var e = eventArgs;


                            if (e.key == 15)


                                var rect = someElement.findName("myRectangle");

                                var top = "Canvas.Top";

                                rect.setValue(top, rect.getValue(top) – 10);





So we don't even need to include any JS file in our deployment scenario.


This little tool is only a small example of removing intellisense code from javascript.
We can use the same mechanism for a Visual Studio 2008 Add-in the translates code back & forth between intellisense code and non-intellisensed code.
We can create a small .Net IHttpHandler which will automatically serve to a browser request only javascript files after they have been stripped of intellisense code.

So regarding deployment, it's up to you.
If you need any help from me, you've got it.


Questions, follow-up and suggestions


You will find bugs with this intellisense.
Seriously, I'm not that smart I can build a Type-system in 10 hours and it will work perfectly.

Please go to the project's codeplex page at and Create a new Issue.
Write what error you received, add the appropriate Minimal & Relevant code.
If something isn't working as you expect it to, tell me what you expect and what actually happens.

Attach a print screen if possible.


Feature requests

Additionally, you might want additional features like the HttpHandler I talked about or more things to be strongly typed (DependencyProperties or Keys come to mind).
Same goes, open a new issue and I'll do my best.


Check for updates

This project will surely undergo constant changes in the first 30-60 days after publishing.
If you're using this project, please signup to our RSS feed so you get notices.
RSS feed can be found at:



Here are my personal details just in case you feel the codeplex page isn't sufficient:
Email: J@JustinAngel.Net
Phone: +972 546 567789

I'm serious about this, don't hesitate to contact me.


Well, that's about it.


Justin-Josef Angel,

Senior .Net consultant, Microsoft C# MVP


הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

6 תגובות

  1. Perry Stathopoulos2 באוגוסט 2007 ב 1:42

    Holy crap!!

    That is just sick! Unfortunately, I won't be using it because I'm concentrating on SL 1.1.

    Still, awesome job.

  2. Marco2 באוגוסט 2007 ב 18:00

    You come to the rescue to all the 3-seconds-cached brain memory programmers.

    You intellisense addition makes the 1.0 release of silverlight very attractive.

    Well done!

  3. chief710 בספטמבר 2007 ב 20:45

    What is the preferred method for creating a canvas from a downloaded XAML file using this plugin?


    How can you create create an object from XAML text using this plugin?

  4. Justin-Josef Angel [MVP]17 באוקטובר 2007 ב 16:45

    Jeremy & Spotlight,

    If you're still expriencing any problems – please contact me by email at J@JustinAngel.Net and I'll try and help you.

  5. anils sahu27 באוגוסט 2008 ב 3:24

    it's very good