WPF/E Code Walkthrough

Those of you that read my earlier post or saw Joe Stegman's WPF/E talk at Mix, are probably interested in what the code looks like for the demos that we showed.  I developed many of the demos Joe presented (the Pan & Zoom app, WPF/E pad, the vector clock and the ASP.NET WPF/E wrapper control) and I'll walk you through the code for integrating XAML content into a web page.

The first step is to create the XAML.  The WinFX SDK has a great tool called XAMLPad for editing XAML.  If you've used WPF at all, I'm sure you're familar with it.  I used XAMLPad to create this simple example:

<Canvas xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
<Rectangle x:Name="myRect" Fill="orange" Width="100" Height="100" Canvas.Top="10" Canvas.Left="10"/>
</Canvas>

In XAMLPad:

The next step is to get this into a web page.  The WPF/E browser host comes in two flavors, a Netscape plug-in and an ActiveX control.  I'll just refer to it as the "plug-in" from here on out.  The plug-in can load XAML from a file, a string, or the innerHTML of an element.  Using the last option, will create a page that looks like (with the interesting bits highlighted):

<html xmlns="https://www.w3.org/1999/xhtml">
<head>

</head>
<body>
    <script type="text/xaml" id="WpfeControl1Xaml">
        <Canvas xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
       <Rectangle x:Name="myRect" Fill="orange" Width="100" Height="100" Canvas.Top="10" Canvas.Left="10"/>
        </Canvas>
    </script>

    <div>
       <embed id="WpfeControl1" height="312px" width="354px" SourceElement="WpfeControl1Xaml" BackgroundColor="White" type="application/xcp-plugin"/>
    </div>
    </body>
</html>

If the page is targeting IE instead of FireFox, Netscape or Safari, the page will look like:

<html xmlns="https://www.w3.org/1999/xhtml">
<head>

</head>
<body>
<script type="text/xaml" id="WpfeControl1Xaml">
<Canvas xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
<Rectangle x:Name="myRect" Fill="orange" Width="100" Height="100" Canvas.Top="10" Canvas.Left="10"/>
</Canvas>
</script>

<div>
<object id="WpfeControl1" height="312px" width="354px" codebase="xcpctrl.cab#version=0,0,3,0" classid="CLSID:32C73088-76AE-40F7-AC40-81F62CB2C1DA">
<param name="SourceElement" value="WpfeControl1Xaml" />
<param name="BackgroundColor" value="White" />
</object>
</div>
</body>
</html>

When this page is run, it will look like:

The next step is to add some interactivity through javascript.  In order to do that, I've added a textbox and a button to the page.  I'm going to use the textbox to enter a color to set as the XAML rectangle's Fill property.  I'll also add a script block with the code to set the color.  The page now looks like:

<html xmlns="https://www.w3.org/1999/xhtml" >
<head>

</head>
<body>
<script type="text/xaml" id="WpfeControl1Xaml">
<Canvas xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
<Rectangle x:Name="myRect" Fill="orange" Width="100" Height="100" Canvas.Top="10" Canvas.Left="10"/>
</Canvas>
</script>

<script language="javascript" type="text/javascript">
function clickHandler() {
// Get text input
var textbox = document.getElementById("textbox");

// Get the WPF/E plug-in
var wpfeControl = document.getElementById("WpfeControl1");

// Get the vector path from inside the WPF/E plug-in
var myRect = wpfeControl.GetElementById("myRect");

// Set the value of a property on the path
myRect.SetValue("Fill", textbox.value);
}
</script>

<div>
<input id="textbox" type="text" value="Orange"/>
<button onclick="clickHandler()">Change Color</button><br />
<embed id="WpfeControl1" height="312px" width="354px" SourceElement="WpfeControl1Xaml" BackgroundColor="White" type="application/xcp-plugin"/>
</div>
</body>
</html>

Note the highlighted contents of the script block.  The plug-in (wpfeControl) offers the ability to access arbitrary named elements inside the XAML.  These elements allow you to get and set properties, hook events and call methods.  In this sample, I'm setting the Fill property to the value of the textbox. 

When this is run in the browser it will look like:

The cool thing about this model is that you can view source on the web page and see all the HTML, XAML and script that make up the experience.

In this post I focused on our javascript programming model and didn't talk about the .NET programming model.  We don't yet have the cross platform CLR integrated into our main builds yet so I can't show screenshots, but Joe's slide deck that I posted last week has some examples of how the model will work.

I mentioned earlier the ASP.NET WPF/E wrapper control I wrote for Joe's demo.  I'll go into more details on this and ASP.NET integration in general in a future post.