IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Silverlight Controls and Objects

Saturday 7 July, 2007, 04:58 PM

Silverlight lets you use XAML content in an HTML world. XAML elements are accessible to browser script as objects. Since these objects have much in common with WPF’s programming model, they work differently from the HTML DOM.

The tree of objects representing XAML content is disjoint from the tree of objects representing HTML content. Until recently, I’ve had only a fuzzy understanding of how Silverlight ties these two worlds together. This has caused me a series of minor problems, with things not working quite how I expected. So I decided it was time to investigate.

Note: this is based on the Beta 1 release of Silverlight 1.0, released in May 2007.

The Map Is Not the Terrain

At a first glance, the Silverlight SDK documentation seems to cover the ground well enough. The “Silverlight Object Models” topic provides a reasonably extensive description of these issues, and the page that follows, “Using a Silverlight Control”, goes into further depth.

Unfortunately, the documentation confuses things somewhat by using the term “Silverlight Control” to refer to four distinct objects. The “Using a Silverlight Control” page is the least bad, because it does make it clear that the properties associated with a control are spread across three objects. And while it doesn’t exactly make it clear that there’s a fourth distinct object representing the control in the DOM, the information is buried in there for the determined to uncover.

The “Silverlight Object Models” page is slightly better on that front—it’s has a ‘note’ section that highlights the distinction between the object that represents the control in the DOM, and the object returned by the getHost() method, which also represents the control. Unfortunately, the diagrams on that page fail to make this clear. They show the distinction between the DOM tree and the XAML tree well, but it’s really not clear that there are four objects representing various aspects of the control, three of which don’t belong to either tree. Moreover, the diagrams drag in a fifth object, the so-called “SilverlightControlHost”, without mentioning that this is wholly different from the object returned by getHost().

Sadly, it gets worse. Confusing though the coverage of the distinction between the multiple ‘control’ objects is on these two pages, the distinction appears to be lost entirely elsewhere. The “Silverlight Control Object” page in the reference section is particularly egregious—it presents a set of properties, methods, and events as though they all belong to one object, where in fact they belong to four; the page itself starts with an HTML example that shows how to create just one of the objects! (To be fair, creating this particular object will cause the other three to be created. But I don’t see how anyone reading the page could be expected to infer that.)

Would The Real Silverlight Control Please Stand Up?

I want to paint a clear and complete picture of what all these objects do and how they fit together. In order to do this, I need to invent new names, for two reasons. First, Microsoft have only introduced two terms: “host” and “Silverlight Control”, which is insufficient to describe five objects, hence the present ambiguity. Second, in order not to confuse matter further, I need to avoid the existing names entirely—otherwise any description of how the objects relate to Microsoft’s original names will be unreadable.

To understand fully the objects involved with a Silverlight control, there’s a sixth object we need to consider: the root object, which represents the root of the XAML tree. There is no confusion around this object in the documentation. I’m mentioning it here because this discussion would otherwise be incomplete.

Here are the six objects, with some new and, I hope, clearer names I just made up.

ObjectTypeCreationTypical ID or source
Placeholder elementHTML <div> (DOM object)Statically placed in HTML sourceSilverlightControlHost
Silverlight DOM elementHTML <object> (DOM object)Dynamically created by Silverlight.js and added as InnerHTML to DOM placeholderSilverlightControl; also pass as 1st parameter to onLoad handler
Silverlight script object (SSO)Scriptable Silverlight object with type infoCreated by Silverlight during initializationNo ID; returned by calling getHost() on any XAML object
Settings objectScriptable Silverlight objectCreated by Silverlight during initialization, based on the parameters passed during creationNo ID; returned as the Silverlight script object’s Settings property.
Content objectScriptable Silverlight objectCreated by Silverlight during initializationNo ID; returned as the Silverlight script object’s Content property.
Root objectScriptable Silverlight objectCreated by Silverlight when it parses our XAMLNo ID; passed to event handlers (3rd parameter to onLoad; 1st parameter to mouse event handlers)

This figure shows where these objects fit into a page containing both Silverlight XAML and HTML:

http://www.interact-sw.co.uk/images/SilverlightOM.png

The blue ellipse contains the four objects that the documentation ambiguously describes as the “Silverlight control”. Two of these objects overlap, to reflect that despite being distinct objects, they share many properties, so the two are sometimes interchangeable. The arrow with a dotted line signifies that although the content object nominally contains the XAML, this relationship is not represented directly by a property.

The following sections describe the role of the six objects listed in the table above.

Placeholder Element

The placeholder element is part of the DOM, and it indicates where we would like the Silverlight plug-in to be added. The placeholder is normally a <div> tag in the HTML:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Silverlight Example</title>
  <script type="text/javascript" src="Silverlight.js"></script>
  <script type="text/javascript" src="MyPage.html.js"></script>
</head>

<body>
  <div id="SilverlightControlPlaceholder">
    <script type="text/javascript">
      createSilverlight();
    </script>
  </div>
</body>
</html>

Notice the slight difference from the canonical Silverlight example: I’ve called my placeholder tag SilverlightControlPlaceholder, in keeping with my naming scheme. It’s normally called SilverlightControlHost, and the documentation sometimes refers to this object as the ‘host’. I think this is confusing, because it’s different from the object getHost() returns.

You normally pass this placeholder element to the Sys.Silverlight.createObjectEx method, which lives in the Microsoft-supplied Silverlight.js file. By convention, this call is wrapped by a createSilverlight method, defined in MyPage.html.js (not shown here). The Sys.Silverlight.createObjectEx method generates some HTML and put it inside the placeholder.

In other words, the placeholder determines where the Silverlight content will appear in your web page.

And that’s the whole purpose of the placeholder—it’s to provide somewhere to add the HTML required to instantiate the Silverlight plug-in. The placeholder serves no purpose once the control has been created. In fact, the placeholder is technically optional. If you don’t supply one to createObjectEx, that method simply returns the HTML as a string, and you can choose what to do with it. But in general, it’s simplest to provide a placeholder.

Silverlight DOM element

The Silverlight DOM element is the object dynamically added inside the placeholder element. In theory, you can create the Silverlight DOM element directly—it’s just an object tag:

<object id="SilverlightDomElement"
        width="100%" height="100%"
        type="application/ag-plugin">
  <param value="Scene.xaml" name="source"/>
</object>

However, you will normally want to use the Sys.Silverlight.createObjectEx method in the Microsoft-supplied Silverlight.js file to build this HTML for you. The helper function detects when Silverlight is not present, and can offer to install it. The helper also tweaks the generated HTML for certain browsers.

The Silverlight DOM element is not optional. This is the element that loads Silverlight as an ActiveX control (on IE) or as a plug-in (on other browsers). It also provides access to the settings and content objects through its Settings and Content properties.

The Silverlight DOM element is one of the many objects referred to as the “Silverlight Control” in the documentation. This object is passed as the first parameter to the onLoad event handler. (You normally specify an onLoad handler when creating the Silverlight control. It is passed as a member of the events property of the configuration object passed to Sys.Silverlight.createObjectEx.)

The Silverlight DOM element needs to be part of the DOM in order to connect Silverlight into the world of the web browser. Consequently, it needs to support all of the usual DOM behaviour. But it seems that Microsoft found it useful to provide a second object associated with the control that is not bound to do everything a DOM object does: the object that I’m calling the Silverlight script object.

Silverlight script object (SSO)

The Silverlight script object is not a UI object: it is not part of the DOM, nor is it part of any tree of XAML objects. It represents certain aspects of the control that Microsoft apparently wanted to be available outside of the DOM. I’m not sure why they needed to do that—perhaps they wanted to disable the ‘expando’ behaviour of normal scriptable objects. Or perhaps they wanted to be able to raise events that do not participate in event bubbling. Or maybe they wanted the object to be useable in scenarios where there is no DOM.

It does not appear to be necessary to use the Silverlight script object, as all of its members seem to be offered on the Silverlight DOM object. (The opposite is not true of course—the Silverlight script object does not offer any standard DOM properties.) Even more curious is the fact that if you enumerate the properties of the Silverlight DOM object, all the properties show up including those of the SSO. But if you enumerate the properties of the Silverlight script object, it appears not to have any properties at all. (And yet Visual Studio is able to see its properties and methods in the debugger.)

The SSO is not passed to your onLoad handler, nor any other event handler. You can only retrieve the Silverlight script object by calling getHost() on any XAML object. (The root object, for example. And the root object is passed to your onLoad handler.) The SSO provides access to two of the main control-related objects: Settings and Content, both of which are discussed below.

There are some other properties that seem slightly odd, in that by the time you have access to the SSO, it’s too late for these properties to do anything useful. For example, OnLoad contains the name of the function that is called once the control has finished loading. But since your first chance to get hold of this object is when it raises that event, it’s already too late to do anything with it. You can only usefully set this property indirectly, by adding an appropriate <param> tag to the Silverlight DOM element. (Normally you let the Silverlight.js script do that for you, and it will arrange to call your onLoad handler.) The story seems to be the same with InitParams. Likewise, the IsLoaded property will always be true by the time you’ve got hold of this object.

The OnError member might be more useful—perhaps you would want to change the error handler after initialization. But in general you would set the error handler in much the same way as you specify an onLoad handler: you can pass an onError parameter to the creation helper in Silverlight.js.

So in practice, this object serves only one distinct purpose besides providing access to the Content and Settings objects. It offers a CreateObject method. (This too is available on the DOM object.) This provides access to Silverlight utility objects. Right now, it offers only one type of object: Downloader. (Presumably the intention is to add other types in the future.) A Downloader can download XAML content, images, or other assets asynchronously. Its use is beyond the scope of this article.

The Silverlight scripting object is one of the many objects referred to as the “Silverlight Control” in the existing documentation. Since it simply duplicates the Silverlight-specific members of the Silverlight DOM object, the ambiguous naming here doesn’t seem so bad. However, we’re not done yet.

Settings object

The settings object is one of the many objects referred to as the “Silverlight Control”. It is accessed via the Settings property of either the Silverlight script object, or the Silverlight DOM object. This object’s properties mostly correspond to those you can set on the object passed into the createObjectEx script function’s properties parameter. (I.e., background colour, maximum frame rate, windowless operation etc.)

It also provides a few properties you cannot set with createObjectEx. For example, setting EnableRedrawRegions to true causes Silverlight to show which areas of the screen it is repainting during updates, by colouring them in. You wouldn’t use this in production code of course—it makes things hopeless garish—but it lets you see how much repainting is happening. Another diagnostic property is EnableFrameRateCounter, which displays in the browser’s status bar the number of frames Silverlight is repainting per second.

Content object

The content object is the last of the objects referred to as the “Silverlight Control”. It is accessed via the Content property of either the Silverlight script object, or the Silverlight DOM object. It provides services related to the XAML content.

The FindName method allows you to locate named elements already in the tree of XAML objects. The CreateFromXaml and CreateFromXamlDownloader methods allow you to build new XAML objects. The FullScreen property and OnFullScreenChange event respectively let you choose and detect whether the application runs full screen.

While the content object enables you to work with and edit the tree of XAML objects, it is not a part of that tree. The object at the root of that tree is the root object.

Root object

The root object is the object at the root of the XAML tree—the object representing the top level of your XAML file. In Silverlight 1.0 this is required to be a <Canvas> element. In future versions, it may well be possible to use other element types as the root.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk