Silverlight is often dubbed as the would-be better platform for creating Rich Internet Applications. But to date, I’ve seen only applications sitting duck in the browser. Well, I’m not saying that those are not great RIA, but for goodness sake, I want to see something different like a Silverlight application flying around in the browser among HTML elements, or at least a window in Silverlight that could be dragged around. This motivates me to create a proof of concept.

This tutorial basically demonstrates how to create and overlay a draggable window on HTML body in Silverlight, using managed code and DOM. For simplicity, this sample uses an alpha-blended background PNG image to cast the shadows and make the ‘see-through glass’ effect on the LCD screen.

 

View Online Demo - Silverlight 2.0 Project (209.73 kb)

 

Notes: This tutorial was written for Silverlight 1.1 Alpha; however, you can find a working sample project for Silverlight 2.0 at the end of this article.

Make Background Transparent

The background of Silverlight host element and root canvas is by default in opaque color. To make the whole background transparent, firstly set the the root canvas’s Background to Transparent. (See screenshot below)

 
 

Secondly we need to modify the arguments of the Silverlight.createObjectEx(), setting isWindowless: ’true’ and background: '#00FFFFFF'.  Windowless mode allows host element to overlay on HTML elements, and vice-versa (more on this later). Notice the first two digits ‘00’ in the background property. This is alpha-blend opacity value in HEX format. E.g. ‘00’ makes it completely transparent; ‘7F’ is 50% transparent. And ‘FF’ is completely opaque. See the screenshot after the changes:

 
 

By now Silverlight application is completely transparent. Just a quick note, if you can’t reproduce this transparency, double check the code, look especially for typos and missing quote ‘  or “ sign.

Create a Draggable Window

We want to create a window that could be dragged around in the browser, on top of HTML elements. In this case, we treat the host element as window. Now the very first thing to do is to absolutely position the host element to allow overlaying on other HTML elements. We simply add some CSS (highlighted below):

 
 

Add a ‘Title Bar’

What we need now is the ‘Title Bar’ area  where user can drag the window. In this case, we add a big transparent ellipse as the ‘Title Bar’. Name it “ellipseDrag”. Remember, you’re not limited to ellipse. You can just create ‘Title Bar’ out of any Silverlight element.

<Ellipse x:Name="ellipseDrag" Canvas.Left="0" Canvas.Top="0" Width="500" Height="300" Fill="Transparent"></Ellipse>

Define the Dragging Stages

I view Window dragging as a three-stage process. First, user holds down the mouse left button on the title bar. Second, the pointer moves from point A to point B, then the Window is spontaneously moved along with the mouse pointer. Third, the mouse left button is released. Therefore, we model this in MouseDraggingState enumeration:

Public Enum MouseDraggingState As Integer
    Down = 1
    Dragging
    Normal
End Enum

First Stage of Dragging: Mouse Button is Hold Down

To detect when user holds down mouse button on the ellipse, we handle the MouseLeftButtonDown() event then set the dragging state to ‘Down’.

Dim _draggingState As MouseDraggingState

Private Sub ellipseDrag_MouseLeftButtonDown(…) Handles ellipseDrag.MouseLeftButtonDown
        ' Setdragging state to 'Down'
        _ draggingState = MouseButtonState.Down
End Sub

Second Stage of Dragging: Mouse Pointer is Moving

In second stage, while mouse pointer is moving, the host element is moved along to create dragging effect. But we don’t handle the ellipse MouseMove() event here as you can see in screenshot below, since the mouse pointer is always fixed to the same position on ellipse during dragging.  

 
 

Instead, we handle the document OnMouseMove() event which fires every time mouse pointer moves across the document. To handle it, HtmlPage.Document.AttachEvent() method is called to subscribe “Document_OnMouseMove” as an event handler. You can see we also handle the document OnMouseUp() event which fires when mouse button is released.

Now the Document_OnMouseMove() is fired every time mouse pointer is moved.

 
 

You can see that at the very beginning of dragging (see Block #1 in above screenshot), the position of the host element as well as the position of mouse pointer are noted down for later use, and the dragging state is changed from ‘Down’ to ‘Dragging’. While the ellipse is being dragged (see Block #2), the host element is moved along with the mouse pointer. Remember that, position of the host element is relative to the document since we absolutely positioned it. To help you with the positioning calculations, take a look at this model:

 
 

You can see I included an extra condition: e.ClientY >= -1000 AndAlso e.ClientX >= -1000. It’s because in FireFox, Silverlight 1.1 Alpha sometimes return e.ClientY and e.ClientX in weird negative values when mouse pointer is moved out of document to the far left or top.

Third Stage of Dragging: Mouse Pointer is Released

What we need to do now is handle the document OnMouseUp() event in Document_OnMouseUp() method. When mouse button is released, simply change the dragging state to normal to stop moving the host element.

 
 

This is it, folks. We now have a window in Silverlight that could be dragged around.

Spice it up with PNG background image

I just want to demonstrate this sneaky use of alpha-blended PNG image as background. In Page_Load() event, set the “window-back.png” image as the background of the root canvas. In the full source codes, you’ll see I added an animated ellipse just to show off the alpha-blending effect.

 

For Silverlight 2.0 RTW:

Online Demo

Silverlight 2.0 Project (209.73 kb)