Click here to Skip to main content
13,092,725 members (71,742 online)
Click here to Skip to main content
Add your own
alternative version


17 bookmarked
Posted 19 Dec 2007

Silverlight 1.0 Full JavaScript Intellisense

Rate this:
Please Sign up or sign in to vote.
An article about Silverlight 1.0 full JavaScript Intellisense

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

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 Storyboard so the rectangle changes background colors over a period of two seconds.

    <Storyboard x:Name="changeBackground">
        <ColorAnimationUsingKeyFrames BeginTime="00:00:00"
            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFD97F38"/>
            <SplineColorKeyFrame KeyTime="00:00:02.1000000" Value="#FF6BD938"/>
        <ColorAnimationUsingKeyFrames BeginTime="00:00:00"
            <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 here and download the latest "JavaScript Silverlight Intellisense" release.
  2. Open the zip file. 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.

The 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_thumb12image_thumb13image_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 they are 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 RGB value that stand for LightGreen.

So let's do something a little more tricky, let's change the background for our 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 Storyb<code>oard.






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 the Left Mouse Button




Working with Inline Functions (Anonymous Delegates) and 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" stands 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 Pattern

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 the 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 selecting 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 this Extensions.js file to our HTML page.



And we need to reference our Extensions.js file wherever we need intellisense.


Please note that we no longer reference the intellisense.js file directly. Our extensions.js references it so we don't need to.



After running this code we can see the rectangle is at 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 no 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 to 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 whichever suits us.

Deployment with Intellisense.js File

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


It's more than 1 MB! That's huge!

And most of it is essentially 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 JavaScript 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 that 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 100 KB 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 are two downloads on the project's codeplex page here.
The first contains only the two JavaScript files mentioned previously.


The second download 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 JavaScript 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 that translates code back and forth between intellisense code and non-intellisensed code.
We can create a small .NET IHttpHandler which will automatically serve to a browser request only the 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 that I can build a Type-system in 10 hours and it will work perfectly.

Please go to the project's Codeplex page here and Create a new Issue.
Write what error you received, add the appropriate minimal and 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 here.

Here are my personal details just in case you feel the Codeplex page isn't sufficient:
Justin-Josef Angel,
Senior .NET consultant, Microsoft C# MVP
Email: J@JustinAngel.Net
Phone: +972 546 567789

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

Well, that's about it.


  • December 20, 2007: Published on The Code Project
  • August 01, 2007: Published on CodePlex


This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


About the Author

Justin-Josef Angel [MVP]
JustinAngel.Net, Senior .Net consultant
Israel Israel
Justin-Josef Angel is a C# Microsoft Most Valuable professional, a Senior .Net consultant in Israel with 4 years of .Net experience and has 8 years of Web experience.

Justin's been working this past year on two Enterprise sized Silverlight projects with his customers. During that time he's gained a real-insight into Silverlight's inner workings and how to integrate Silverlight into the real world of software development. Additionally, During that time he's developed a few well-known projects like the "Silverlight 1.0 Javascript Intellisense", "Silverlight 1.1 Hebrew & Arabic Languages support" and a few others you might know.

Justin is also a seasoned presenter with an impressive track-record of talking in front of thousands of people in Israel.

Justin owns the first .Net blog written in Hebrew - http://www.JustinAngel.Net .
And he also owns an additional blog with mixed Hebrew & English content -

A full list of his articles (all 100+ of them) can be found at: http://www.JustinAngel.Net/#index

You may also be interested in...


Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170813.1 | Last Updated 21 Dec 2007
Article Copyright 2007 by Justin-Josef Angel [MVP]
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid