Using Windowless Silverlight Controls To Blend HTML and Silverlight Elements

Silverlight 1.0 has no intrinsic controls. Forget about dropdowns and sliders, Silverlight 1.0 doesn't have textboxes or buttons. That doesn't mean you can't build and deploy advanced Silverlight 1.0 applications today, though. [Sheesh, that sounded like marketing-speak - sorry about that.]

There are three ways to go about getting controls for Silverlight 1.0 applications:

  • Build your own controls from scratch
  • Grab some controls from published Silverlight projects (license permitting, of course)
  • Layering transparent HTML and Silverlight controls

We'll mostly be looking at the layering approach here - looking at the following questions:

  1. How to logically split a control into HTML and Silverlight regions
  2. How to overlay tranparent HTML and Silverlight sections in a single control area
  3. Performance considerations

Just a second, I have to deal with some deserters...

Wait, This Applies For Silverlight 2.0, Too!

Oh, and I heard those restless mice scurrying for the "next post" link. "Jon", you say, "that's great, but I'm just going to ride it out. I heard Silverlight 2.0 will include controls." You do have a point there. The publicly announced Silverlight roadmap indicates that Silverlight 2.0 will "add support for core form controls (textbox, checkbox, radiobutton, etc), built-in layout management controls (StackPanel, Grid, etc), common functionality controls (TabControl, Slider, ScrollViewer, ProgressBar, etc) and data manipulation controls (DataGrid, etc)." But I think you should still read this, for two reasons:

  1. Silverlight 2.0 will have a bunch of new controls. Will it have every webby control possible? Time will tell, but I'd guess that there may be controls you'd like to have in a Silverlight 2.0 application that aren't in the box.
  2. Even if Silverlight 2.0 includes the control you want, you may want to use an HTML based control. Maybe you've got an existing site and you'd like to integrate Silverlight functionality without a full rewrite. Or, you've got a complex control or HTML structure which would be pretty difficult to rebuild in Silverlight. Or, maybe you've got some AJAX interactions in your page which are easier to wire up in HTML and JavaScript - sure, you can communicate with JavaScript and the DOM even in Silverlight 1.0, but you're still crossing domain boundaries, and if you've got functioning JavaScript and AJAX code, it might not make sense to move that interaction code to Silverlight 2.0 managed code. Finally, maybe you want to take advantage of control toolkits like the AJAX Control Toolkit, rather than duplicating these controls in Silverlight.

Composite Controls Using Transparent HTML and Silverlight Elements

The Video.Show player interface is a good example. Video.Show is a Silverlight 1.0 based "video site in a box" project which is available on CodePlex - see my previous post for more information. We made heavy use of the Silverlight / HTML layering approach to get the best of both. Take a look at the following control and take a guess at how it's constructed:

Video.Show Player interface

Here's the breakdown we went with:

Silverlight / HTML Composite

Header Section

It made sense to build the header section in HTML, since it's pretty simple and mapped to HTML controls pretty well. The owner of the video ("Jon" in the above screenshot) is hyperlinked to my member page, and the blue buttons at the top of the page make simple AJAX calls to ASMX webservices.

Lower Section

The lower section is one big Silverlight control. The media player window had to be a Silverlight, of course. The right section (with the comment form) could have been HTML, but notice the slider bar above the comment box? That's part of the player control. When you're not in "comment mode", that slider is located below the video, as seen below:

Video.Show Player Controls

When you click the "Add Comment" button, we switch into "comment mode" - hiding the playback controls and moving the slider above the comment area. Because of that, it's simplest to keep the entire lower section as a silverlight control and layer HTML controls over the top. We've done that by using CSS absolute positioning for the comment area:

div#commentForm {
display:none;
position:absolute;
height:100px;
left:500px;
top:110px;
width:500px;
}

You'll notice that display is set to "none" so the comment form isn't displayed when the page first loads. The position is set to absolute so we can position it over the Silverlight control. The Add Comment button calls showCommentForm():

<div class="button">
<a onclick="player.showCommentForm()" href="#">Add Comment</a>
</div>

showCommentForm does a lot of things, including this:

showCommentForm: function() {
//lots of other stuff
$get("commentForm").style.display = "inline";
}

The Silverlight control itself is Windowless so that the gradient background shows through. That's accomplished by setting a few values in the <object> tag (although we don't set those directly, more on that in a second). Notice that we've got the background set to transparent, and the windowless property set to true.

<object id="xamlHost0" width="900" height="412" type="application/x-silverlight">
<param value="transparent" name="background"/>
<param value="true" name="windowless"/>
<!-- a bunch of other params go here -->
</object>

As I've said before, Silverlight is implemented as an HTML object, and technically doesn't need to be displayed via JavaScript. However, for reasons I mentioned in that post, it's a good idea to use the JavaScript helper functions. Here's the JavaScript call used to load the Silverlight object:

 

Just setting the background to transparent isn't enough, the control also needs to be windowless for the transparency to be applied. Once that's done, though, the control is effectively layered over the background. So the final result is three layers:

CropperCapture[106]

Silverlight.createHostedObjectEx({
source: 'Silverlight/Player/Player.xaml?v=1',
parentElement: $get(parentId || "Player_SilverlightContainer"),
id: this._hostname,
properties: {
width: '900',
height: '412',
framerate: '24',
version: '1.0',
background: 'transparent',
isWindowless: 'true'
}

Performance Considerations of Windowless Silverlight Controls

You should be aware that using a Silverlight control in Windowless mode can have performance impacts. It can cause "tearing" during animations, and can force large areas of the screen to be redrawn when in fact minor changes have been made. That's something you'll need to evaluate - in our case, there was very little animation other than the video timeline slider moving while was the video was being played, so in our testing we didn't see any problems. However, it's something to be aware of, especially before you attempt to do something crazy like create multiple layers of transparent video objects.

If you're seeing performance issues, make sure to start with EnableRedrawRegions (a debugging switch which allows you to see what areas are actually being redrawn) and to lower your framerate as necessary.

If You Are Going To Build A Complex Silverlight Control, Don't Start From Scratch

To recap: my advice is to use HTML elements to do some of the heavy lifting in your Silverlight applications, which should hopefully reduce your need to build complex controls in Silverlight. If that doesn't work for you, though, I'd like to recommend that you don't build your new Silverlight controls from the ground up.

There are several released projects which include tool suites - starting with primitives and building up to complex controls. Scott recently mentioned the Tafiti controls (licensed under MsPL), and you can also cherrypick from CodePlex projects which include Silverlight controls. The Expression Encoder templates are based on a BasePlayer, which is available for download. However, the license for the Expression Encoder templates requires an Expression Encoder license, so it's really only useful if you're extending the Expression Encoder player templates.

The bottom line on building controls is that it's hard to get them right, and if you make use of a control someone else has built and tested, you're off to a great start.

4 Comments

  • The last time I checked, windowless Silverlight 1.0 wasn't working on the Mac. I haven't had an opportunity to check 2.0 to see if the issue lingers. Setting frameRate was misbehaving, too.

    This needs to be fixed for Silverlight, because it'll block people from converting from Flash. Microsoft, don't be discouraged; Adobe has or had its windowless/frame rate issues with Flash on the Mac, too.

  • Sounds like you must want to do it in Silverlight pretty bad in order for it to make sense to use Silverlight.

  • @Richard No, not really. Silverlight 2 includes equivalents of most of the HTML controls, plus a lot more (e.g. calendar, slider, grids...).

    I used this technique a lot in Silverlight 1.0 because HTML doesn't have a working element. In Silverlight 2, I could create an entire UI in Silverlight. I'd rather not because I really like the idea of semantic HTML which leverages "islands of richness".

    Maybe you can explain your comment a bit?

  • Hey mate this was really helpful, cheers!

Comments have been disabled for this content.