WPF Vista Gadgets - Part 1: Using XBAP and IFRAME

If you are following Vista, you are probably aware of the Sidebar, real estate on the desktop that can be used to host gadgets.  And, if you are aware of Sidebar, you might be aware that the platform for gadgets is DHTML + Javascript.  And, if you are a WPF designer/developer, you might be asking yourself if there are any ways to get WPF content into a gadget.  It turns out that there are some workarounds that will allow you to get WPF into the Sidebar.  However, there are drawbacks and limitations with using WPF in the Sidebar as the Sidebar does not officially support WPF for gadgets.  In this post, I'm going to enumerate one way you could host WPF in a gadget which is to use XBAP and IFRAMEs. In a later post, I will talk about the other option, which is to use ActiveX controls.

Before even going down the path of writing a WPF gadget, it is to decide if the cost is worth it.  Can you achieve the visual effect you are seeking without WPF?  If the answer is no, read on and find out what you are getting yourself into if you choose to use an unsupported gadget technology.

One of the big limitations with WPF gadgets is that WPF doesn't "play nicely" with the rules of being a gadget, because it swallows mouse events and doesn't propagate them back up to the UI.  As such, by default, WPF gadgets won't show the default gadget UI on right click.  And, also by default, WPF gadgets won't display the gadget thumb and close icons which are displayed on mouse over.  There are work arounds to these problems that I will discuss below, but you can already see that the Sidebar wasn't designed for WPF.

Another limitataion is that a WPF gadget can't get at any of the Sidebar specific APIs,. So, there is going to be some clunkiness to do things like getting the flyout window to display.   Now, some of the system APIs have a .NET equivalent, although they require a certain permission level.  When using loose XAML or XBAPs in an IFRAME, you will be sandboxed. 

Another limitation has to do with performance and working set implications.  The user is going to pay a start up cost for loading the WPF engine the first time the sidebar is instantiated, assuming that WPF hasn't been instantiated yet on the system, which is most likely the case since the Sidebar, by default, loads when a user logs in.  Additionally, because of the working set required by WPF and the CLR, the working set of the sidebar itself is also going to creep up.  Lastly, when the sidebar closes, either at log off or when closed by the user, it has to unload WPF and the CLR.  I've seen some unsavory behavior here if your WPF has opened resources that the sidebar has trouble unloading, the result making for an icky user experience when the sidebar unloads.  At this point, I haven't isolated exactly what the behaviors are that cause this problem, but I've seen it. Now, all of these problems are tractable, but they are costs that need to be known up front. You certainly don't want to write a gadget that causes problems or makes for a crummy experience.

With these problems in mind, let's look at the first technique: using IFRAMEs

All three of the gadgets pictured above are available w/ source.  To install the gadgets, just double click the .gadget files. 

Gadgets support the IFRAME tag, which means that you can reference loose xaml or XBAPs from within a gadget.  There are a few downsides to this techniques. First, IE has to install the XBAP (or, in the case of loose XAML, the XAMLReader) into the IE application cache.  There is no way to preload your XBAP and no way to override the default load UI.  So, the user experience is a little funky.  Second, if for some reason the IE application cache gets cleared, the XBAP will have to be reloaded the next time the gadget is run.  The more likely scenario here is that the gadget's XBAP could be bumped out of the cache due to space limitataions by another XBAP getting installed.  The moral of the story being that when using this technique you lose some control over the experience as a whole. 

Here's a gadget that hosts a loose XAML file of a rotating 3D cube displaying different images:

<html>

<head>

<style>

body {

width:130;

height:130;

padding:5;

margin:0;

background:black;

}

</style>

</head>

<body>

<iframe height="130"

width="130"

src="3d_animation.xaml" />

</body>

</html>

To use an XBAP, you simply replace the .xaml file with an .xbap file. The main difference between an XBAP and loose XAML is functionality.  You'll notice that the XBAP supports a trackball control, allowing the user to rotate the cube and scale it with the mouse wheel.  This was made possible by writing C# code, as can be seen in the source.

Remember early I mentioned some workarounds for the mouse propagation problem.  You can see the workaround to the mouse hover problem where I set the padding of the gadget to 5 pixels.  Another technique would be to put the IFRAME in an html table. I then make the background color of the padding identical to the background color of the WPF airspace.  I lose some screen real estate, but at least I get the thumb and minimize UI to show up on the gadget, although if you move the mouse really fast, it doesn't work.  I haven't figured out a workaround to the righ click problem yet.  (If anyone does, let me know!)

One interesting technique that you could do is reference your loose XAML or XBAP on a server.  However, this ties the gadget to the internet, which means you'd have to do some checking from Javascript to make sure the user was online before even showing the IFRAME.  This is certainly doable: many of the gadgets that ship with Vista do this already.  The appeal of this option is that the gadget could be auto-updated on a server and automatically the client would get the new version.  Also, XBAPs deployed from a server are allowed to get back to that server for new data, incremental downloads, etc.

Another interesting fact about XBAP gadgets is that, if they are run from the local filesystem, they can be full trust. However, if they are deployed from a server, they would have to be partial trust unless the cert that signed the XBAP is registered in the user's trusted publishers certificate store.

[Source and Gadgets]

(Note: thanks to the artistry of Maureen Lanza for the images.)

Comments

  • Anonymous
    October 04, 2006
    Christophe (encore lui) nous disait hier que l'on peut agrémenter sa page web d'un gadget. Bon c'est...

  • Anonymous
    October 04, 2006
    Karsten Januszewski has just posted a blog entry about using XAML / XBAP and IFRAMEs to host WPF in a

  • Anonymous
    October 04, 2006
    The comment has been removed

  • Anonymous
    October 05, 2006
    A great demonstration Karsten, thanks. I tried replacing the images you supplied with some containing text but the text came out reversed on the cube. Why was that?

  • Anonymous
    October 12, 2006
    Try rotating the the transforms starting on line 264 180 degrees to this:          <ModelVisual3D.Transform>            <Transform3DGroup >              <Transform3DGroup.Children>                <RotateTransform3D>                  <RotateTransform3D.Rotation>                    <AxisAngleRotation3D x:Name="myHorizontalRotation" Angle="180" Axis="0 1 0" />                  </RotateTransform3D.Rotation>                </RotateTransform3D>                <RotateTransform3D>                  <RotateTransform3D.Rotation>                    <AxisAngleRotation3D x:Name="myVerticalRotation" Angle="180" Axis="1 0 0" />                  </RotateTransform3D.Rotation>                </RotateTransform3D>                <TranslateTransform3D x:Name="myTranslateTransform"                  OffsetX="0" OffsetY="0" OffsetZ="0" />              </Transform3DGroup.Children>            </Transform3DGroup>          </ModelVisual3D.Transform>

  • Anonymous
    October 12, 2006
    Vista: Sample Sidebar Gadget

  • Anonymous
    October 12, 2006
    Vista: Sample Sidebar Gadget

  • Anonymous
    October 12, 2006
    Thanks for replying, Karsten. Your suggestion didn't work for me. I didn't make it clear that the text was a mirror image. I got it the right way round by changing the texture co-ordinates for each side. Here's the revised code: <!-- 3D Models -->    <MeshGeometry3D x:Key="CubeSide01"      ...      TextureCoordinates="1,0 0,0 0,1 0,1 1,1 1,0 "      ...  />    <MeshGeometry3D x:Key="CubeSide02"      ...      TextureCoordinates="0,0 0,1 1,1 1,1 1,0 0,0 "       ...  />    <MeshGeometry3D x:Key="CubeSide03"      ...            TextureCoordinates="0,1 1,1 1,0 1,0 0,0 0,1 "      ...  />    <MeshGeometry3D x:Key="CubeSide04"      ...      TextureCoordinates="0,1 1,1 1,0 1,0 0,0 0,1 "      ...  />    <MeshGeometry3D x:Key="CubeSide05"      ...      TextureCoordinates="0,0 0,1 1,1 1,1 1,0 0,0 1,1 1,0 0,0 0,0 0,1 1,1 "      ...  />    <MeshGeometry3D x:Key="CubeSide06"      ...      TextureCoordinates="0,1 1,1 1,0 1,0 0,0 0,1 "       ... /> Thanks again.

  • Anonymous
    October 20, 2006
    I recently faced the design challenge of getting an application and gadget to communicate. How to solve

  • Anonymous
    October 23, 2006
    >>When using loose XAML or XBAPs in an IFRAME, you will be sandboxed.<< I just created a IFRAME+XBAP gadget w/ full trust permissions and it installed and executed w/o any more prompting than another one having only internet zone permissions. Is this expected behavior?

  • Anonymous
    October 24, 2006
    Timmy G. -- This is expected behavior because your XBAP is running from the filesystem.  Were it to be installed from a server, you'd have to get the cert that signed the XBAP into the user's trusted publisher store.  But when the XBAP is local, you are good to go.  Kinda cool, no? Means you can do a lot more...

  • Anonymous
    December 03, 2006
    Do you remember my posts back from April 2006... during my prep-works for our local BigDays 2006 road

  • Anonymous
    December 19, 2006
    I find the Sidebar gadgets in Windows Vista appealing. I never thought this would happen. I've looked...

  • Anonymous
    December 19, 2006
    I find the Sidebar gadgets in Windows Vista appealing. I never thought this would happen. I've looked

  • Anonymous
    January 04, 2007
    With Windows Vista Business Edition now available on MSDN AA (see elsewhere in this article for more

  • Anonymous
    February 05, 2007
    Toms and a couple of others asked the same question - hence I thought I would raise this to its own post.

  • Anonymous
    April 19, 2007
    The comment has been removed

  • Anonymous
    May 29, 2007
    Här är Powerpoint-presentationen från Johans och mitt Gadget/Popfly-seminarie på REMIX/Developer Summit-konferensen