Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1607 Silverlight Silverlight is a lightweight browser plug-in from Microsoft that runs not only on all major browsers on Windows, but also on the Mac. Silverlight 1.0 was released in September of 2007. Many books have been written already on the subject. And now, Silverlight 2.0 is fast on the heels of version 1.0. Microsoft also announced ‘‘Moonlight,’’ a partnership with Novell and the Open Source Mono Project to bring Silverlight-like technology to Linux — you already know this, don’t you? It is outside the scope of this book to give more than an introduction to Silverlight. Rather than just offering the standard ‘‘Hello World’’ example, however, we thought we’d try something more pragmatic. As this is a book on Professional ASP.NET, why not explore the scenario that a typical ASP.NET programmer (not a designer or an artist) would find herself in? Along the way you’ll learn about Silverlight and its capabilities, and perhaps it will inspire you to include Silverlight in your applications. You should read books such as Silverlight 1.0 (Wiley Publishing, Inc., 2007) to familiarize yourself with this deceptively deep new technology. Thank you to Eilon Lipton for his help with this application! Extending ASP.NET Apps with Silverlight Let’s begin with a theoretical application for patients signing into a chiropractic clinic. They need to sign in and indicate to the doctor what part of their body hurts as seen in Figure C-1. This is a very typical application using Web Controls to present a form and collect the feedback via a Form POST. The page uses conventional ASP.NET techniques including validation controls. One interesting thing to note is that this page’s Submit button sends its data back to another page using a Cross Page PostBack. The page that receives the Form POST is seen in Figure C-2. Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1608 Appendix C: Silverlight Figure C-1 Figure C-2 1608 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1609 Appendix C: Silverlight Step 1: A Basic ASP.NET Application Figure C-1 shows our generic Patient Form for our Chiropractic Clinic. The code for the patient form as seen in Listing C-1 has an empty code-behind class. We’ve removed some minor markup for the sake of brevity. You see applications like this every day that are created by composing basic HTML input elements into more and more complicated forms. What can be done with a simple application like this to make it not only a more compelling user experience, but ultimately more usable? Listing C-1: Patient Form ASPX <%@ Page Language="C#" AutoEventWireup="true" CodeBehind= "PatientForm.aspx.cs" Inherits="SLPersonProject.PatientForm" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>ACME Chiropratic Patient Form</title> </head> <body> <form id="form1" runat="server"> <h1>ACME Chiropratic Patient Form</h1> <div> <table border="1"> <tr> <td>First name:</td> <td> <asp:TextBox ID="FirstName" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="FirstName" ErrorMessage="*"></asp:RequiredFieldValidator> </td> </tr> <tr> <td>Last name:</td> <td> <asp:TextBox ID="LastName" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="LastName" ErrorMessage="*"></asp:RequiredFieldValidator> </td> </tr> <tr><td colspan="2">Where does it hurt? </td></tr> <tr> <td style="width: 125px"> <asp:CheckBox ID="headCheckBox" runat="server" Text="Head" /><br /> <asp:CheckBox ID="leftarmCheckBox" runat="server" Text="Left arm" /><br /> Continued 1609 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1610 Appendix C: Silverlight <asp:CheckBox ID="rightarmCheckBox" runat="server" Text="Right arm" /> <br /> <asp:CheckBox ID="torsoCheckBox" runat="server" Text="Torso" /><br /> <asp:CheckBox ID="leftlegCheckBox" runat="server" Text="Left leg" /> <br /> <asp:CheckBox ID="rightlegCheckBox" runat="server" Text="Right leg" /> </td> <td>What goes here?</td> </tr> <tr> <td colspan="2" align="right"> <asp:Button ID="SubmitButton" runat="server" Text="Submit Doctor Request" PostBackUrl="~/Complete.aspx" /> </td> </tr> </table> </div> </form> </body> </html> Finding Vector-Based Content A professional ASP.NET programmer will often find themselves adding an ‘‘active element’’ to an existing application to make the end user experience richer. Let’s add a picture of a human body that users can click on to indicate their areas of pain, but you’ll add the constraint that the picture should interact with the existing checkboxes so that server-side code won’t need to change. You may not be an artist, so you can start by looking for some vector- based clip art that you can leverage in the application. Bitmaps are exactly that — maps of bits. When you scale a 100 by 100 image to 400 by 400, each pixel is resampled or resized to be 4x larger, but additional information isn’t created. Small pixels simply become larger pixels. Vectors, on the other hand, are represented using mathematical equations and can scale to any size without degradation in quality. Silverlight uses XAML (eXtensible Application Markup Language) to represent vector graphics. For example, this snippet of XAML draws a gray circle: <Ellipse Width="340" Height="340" Canvas.Left="50" Canvas.Top="50" Fill="#FF000000" Opacity="0.3"/> Let’s head over to iStockPhoto.com and search for ‘‘Adult Vector Diagram’’ and download this vector image of a cartoon version of Leonardo da Vinci’s Vitruvian Man (see Figure C-3). Because it’s a vector and not a bitmap it’s in EPS (Encapsulated Postscript) format rather than the more familiar PNG, JPG, GIF, or BMP formats that you use every day. Next, let’s download a trial edition of Adobe Illustrator and open the downloaded EPS as shown in Figure C-4. 1610 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1611 Appendix C: Silverlight If you’d like a free alternative to our Cartoon Virtruvian Man, there is a Public Domain alternative at http://www.hanselman.com/book/asp.net/assets/ SilverlightMan.zip . If you’d rather not use Adobe Illustrator, try the Open Source InkScape at http://www.inkscape.org/. Figure C-3 ‘‘Leonardo man’’ copyright 2006 Miroslaw Pieprzyk, licensed by iStockphoto.com . Zooming in to 300 percent, as shown in Figure C-5, underscores the fact that vectors can be scaled to any resolution. Converting Vector Content to XAML We downloaded Mike Swanson’s excellent Illustrator to XAML Export plug-in from his site at www.mikeswanson.com/xamlexport/ . It has some limitations, and they are listed on his site, but it is an excellent tool for bringing vector content into Silverlight. 1611 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1612 Appendix C: Silverlight Figure C-4 Installation of Mike’s plug-in is simple, just drop the .AIP file into C: \ Program Files \ Adobe \ Adobe Illustrator CS3 \ Plug-ins \ Illustrator Formats and you’ll see new options appear in the File ➪ Export dialog box within Illustrator, as shown in Figure C-6. 1612 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1613 Appendix C: Silverlight Figure C-5 Figure C-6 1613 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1614 Appendix C: Silverlight There are two options, one for WPF XAML usable in a .NET 3.0 Windows Application and one using the old code-name for Silverlight, Windows Presentation Foundation/Everywhere or WPF/E. You’ll select the last one as you’re using Silverlight. The only difference in the documents is the root node of the XML. The resulting XAML document is about 256 KB and starts out like this: <! Generated by Adobe Illustrator CS -> XAML Export Plug-In Version 0.16 > <! For questions, contact Mike Swanson: http://www.mikeswanson.com/XAMLExport > <Canvas Width="612.000000" Height="792.000000" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Canvas> <! Layer 1/<Path> > <Path Data="F1 M 612.000000,792.000000 L 0.000000,792.000000 L 0.000000,0.000000 L 612.000000,0.000000 L 612.000000,792.000000 Z"> the other 255k removed How do you know if the export succeeded and our little man looks correct? There are a few ways. Tools for Viewing and Editing XAML There are a number of ways for you to view or edit our newly created XAML file. You can use Internet Explorer, Visual Studio 2008’s XAML Editor, or Microsoft Expression Blend. Internet Explorer with a Minimal Silverlight Page First, you create a minimal static HTML page to view your XAML, as shown in Figure C-7. The code is fairly simple. First, the default.html file shown in Listing C-2a includes a div to hold the Silverlight control. Listing C-2a: Helloworld.html HTML <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Hello Dude</title> <script type="text/javascript" src="Silverlight.js"></script> <script type="text/javascript" src="HelloWorld.js"></script> <script type="text/javascript" src="Dude.xaml.js"></script> <style type="text/css"> .silverlightHost { height: 792px; width: 612px; } </style> </head> <body> 1614 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1615 Appendix C: Silverlight <div id="SilverlightControlHost" class="silverlightHost"> <script type="text/javascript"> createSilverlight(); </script> </div> </body> </html> Figure C-7 The div with the ID SilverlightControlHost calls a method called createSilverlight that lives in HelloWorld.js, shown in Listing C-2b. We’ve separated the JavaScript files for the sake of tidiness, but you’re welcome to lay the files out however you like. Listing C -2b: Helloworld.js JavaScript function createSilverlight() { var scene = new HelloWorld.Page(); Continued 1615 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1616 Appendix C: Silverlight Silverlight.createObjectEx({ source: "Dude.xaml", parentElement: document.getElementById("SilverlightControlHost"), id: "SilverlightControl", properties: { width: "100%", height: "100%", version: "1.0" }, events: { onLoad: Silverlight.createDelegate(scene, scene.handleLoad) } }); } if (!window.Silverlight) window.Silverlight = {}; Silverlight.createDelegate = function(instance, method) { return function() { return method.apply(instance, arguments); } } Notice the three lines called out in Listing C-2b. The ID of the div from our HTML file is referenced in the call to getElementById above. Our XAML file is referenced in the source: property. You can hook up JavaScript events to Silverlight, as shown in Listing C-2c. A good naming convention is to put these events in a file named yourxamlfile.xaml.js ,soI’venamedmine Dude.xaml.js . Listing C-2c: Dude.xaml.js JavaScript if (!window.HelloWorld) window.HelloWorld = {}; HelloWorld.Page = function() {} HelloWorld.Page.prototype = { handleLoad: function(control, userContext, rootElement) { this.control = control; // Sample event hookup: rootElement.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown)); }, // Sample event handler handleMouseDown: function(sender, eventArgs) { // The following line of code shows how to find an Continued 1616 . Silverlight Let’s begin with a theoretical application for patients signing into a chiropractic clinic. They need to sign in and indicate to the doctor what part of their body hurts as seen in Figure C-1 application using Web Controls to present a form and collect the feedback via a Form POST. The page uses conventional ASP. NET techniques including validation controls. One interesting thing to note. offering the standard ‘‘Hello World’’ example, however, we thought we’d try something more pragmatic. As this is a book on Professional ASP. NET, why not explore the scenario that a typical ASP. NET