Client-side HTML controls for Silverlight 2

What if you could use and create ASP.NET-like web controls that are 100% client-side, powered by the Silverlight 2 runtime? What if ViewState was a thing of the past? Would you like to cut your web application's load on your servers from 50 pageviews down to 0? Wouldn't your users love it if your application was always instantly responsive?

This "managed HTML controls" concept is a neat idea: something that might whet your appetite to explore the interoperability features and consider using the feature to build sophisticated applications. However, key hurdles leave this as a conversation piece more than a new application platform. At the end of the day, the Silverlight presentation framework as it stands if going to be your best bet for a majority of your applications.

Exploring and thinking about changing the boundaries and status quo of web apps is something that's fun and challenging. A client-side implementation of ASP.NET, enabling rich browser apps written in C#, was totally my dream a few years ago. Nikhil's Script# actually can get you some of the way by letting you write client apps in .NET.

Today, a client-side ASP.NET HtmlControl is interesting, but not a game-changer, given the maturity of JavaScript platform and the richer app platforms out there like Silverlight (that is based on WPF) and Flex.

What's the HtmlControls concept look like?

Here's a look at a few of the types.

By exposing strongly typed properties, methods, and events, your .NET HTML application code will be cleaner, easier to maintain, enable you to use static analysis tools, and even perform unit testing.

Although the HtmlControlBase exposes a lot of the sample string-based properties as the standard Silverlight HtmlElement, it adds overloads with enumeration-based parameters (cut down on spelling errors), and stop having to duplicate strings through your app:

You can set Font properties like you would in ASP.NET, without worrying so much about CSS at the end of the day:

The same goes for standard HTML properties defined by the W3C - helpful HtmlProperty enum:

No need for your controls to POST-back to the server or worry about ViewState ~ these are stateful, since they are in memory

Integrate with Silverlight 2 applications, and all the richness it provides in its framework and class libraries

You could move an application like 37signals' Backpack out of a server farm, store the .Xap on a CDN, and use occassional cross-domain web service calls to store and retrieve data... imagine, some types of apps could serve a billion application users with only 1 billion .Xap downloads from your CDN, instead of generating tens of billions of web pages on an expensive web farm

Why build effectively an HTML-based AJAX app using Silverlight, and yet require your users to have the Silverlight 2 runtime on their machines?

The memory performance of this concept is probably quite bad: each element is already in the browser; there's a pointer to that from the native platform in Silverlight; there's the Silverlight HtmlElement object instance; and then there's the HtmlControl type. That's a lot of duplicated stuff!

The performance of the concept in general isn't going to be too awesome: there's a lot of interop here between the web browser, JavaScript, the browser's plugin APIs (NPAPI or ActiveX), the managed CLR, and back again

There's no type checking: you won't know about spelling errors or other problems until runtime, and if you do any CSS manipulation, your code will get very difficult to maintain. Here's the same code, with a managed HTML control (using a few different ways of setting the value):

// Set the width and height of the control
control.Width = 50;
control.Height = new Unit(450, UnitType.Pixel);

Same # of lines of code, but a little more "attractive" API.

You can also wrap existing HtmlElements with a managed control in some cases: either standard parts of your web page, existing AJAX applications. This is possible when the constructor exposes a HtmlElement parameter.

Creating a composite control

Here's a simple "user control" that has a link and a button inside of it:

To hook it up to the application, here is a simple class that shrinks the Silverlight plugin to not occupy any space on the page, that creates a new instance of the MyUserControl type and appends it to the web page body.

The HideSilverlightPlugin function is important because it lets you press F5 while working in a standard Silverlight application project.

You can call the Run() method from anywhere in your Silverlight application - both can co-exist without issue. However, I've just replaced the RootVisual call in the Application_Startup method to demonstrate this example:

Here is this simple HTML application (powered by Silverlight) running on OS X 10.5 in the Safari web browser:

Appending a managed control tree to HtmlElements

Thanks to an extension method, you can append a managed HTML control (that inherits from HtmlControlBase) to the standard HtmlElement inside Silverlight as if the control is an HtmlElement:

The managed control wrapper actually tracks any changes (styles, properties, child controls) to the control and waits until it is inserted into the live web page tree to apply the properties and create the child elements.

At the end of the day there are a lot of types involved here, bridging several layers of abstraction. This is definitely not a "lightweight" solution.

These bits are in use today

One of the key features of the in-browser Silverlight unit test framework is that it exposes an interactive log inside the browser, using the HTML interoperability feature.

If you've used the Silverlight unit test framework, then you've used this managed HTML controls implementation without knowing it: to move away from "spaghetti-code", we setup the log to use simple custom controls built on top of this framework.

Here's a few screenshots of components, including a ProgressBar control:

Clicking on a test method name expands a details drill-down full of stats and information, including links that can be clicked to retry tests and display easy-to-copy details:

Download the bits

Since this is only a concept, and not something you would want to use in a production application, the bits are currently only available as part of the Silverlight unit test framework download for the Silverlight 2 Release Candidate 0.

The implementation is not a complete framework, but rather a minimal set that enables basic functionality: links, buttons, and displaying and creating HTML elements. It does not contain a rich web forms implementation, cool validation controls, or anything like that.

In the future I may make the concept available as a download separate from the test framework, but today I want to make it clear that it isn't something that is ready to really be used in everyday web applications... so hopefully the total size of the test framework assembly will discourage that [81kb]!

It is totally unsupported, to be considered prototype code.

Here's the set of types and enums in the namespace today. You'll see that it is a minimal set, and isn't including a lot of the typical HTML controls like check boxes, forms, or web form controls. There's room to innovate, but the value may not be there:

Do let me know if you like it, or build anything noteworthy, in the comments, and I will post a follow up in the future.

Other ideas

There is potential for the concept in some apps, and I'm sure some really brilliant folks out there could do any of the following things that've come across my mind: