Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1617 Appendix C: Silverlight // element by name and call a method on it. // this.control.content.findName("something").Begin(); } } Visual Studio 2008’s Built-in XAML Editor Visual Studio 2008 includes a XAML editor for editing WPF XAML rather than Silverlight. How- ever, it’ll let you move things around and confirm our layout if you change the http://schemas .microsoft.com/winfx/2007 namespace to http://schemas.microsoft.com/winfx/2006/xaml/ presentation in our XAML file. This isn’t recommended, but it’s an interesting exercise in explor- ing the subtle differences between WPF and Silverlight’s implementation of XAML. Figure C-8 shows our XAML file edited in Visual Studio in a split-screen. Figure C-8 1617 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1618 Appendix C: Silverlight Microsoft Expression Blend At the time of these writing, Expression Blend 2 was in Beta and not yet released. Blend is a designer focused editor for XAML files, animations, and Silverlight projects. Blend shares the same project file format as Visual Studio, so you can open CSPROJ files and SLN files and move seamlessly between Blend and VS. Figure C-9 shows our XAML file being edited in Expression Blend. Blend gives you complete con- trol over XAML files, and you’ll use it to extend the image for your application. For the application, you’ll add red dots over each of the body parts represented in the original applications by check- boxes. You’ll name them so they are accessible from JavaScript and hook up events to both the checkboxes and within Silverlight so they both stay in sync. Figure C-9 1618 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1619 Appendix C: Silverlight Adding Active Elements with Blend Open up your exported XAML file in Blend and perform the following tasks: 1. Using the basic drawing tools in the toolbox, draw a circle over the left and right arms, left and right legs, the head, and the torso. Feel free to color them any way you like. I’ve used a gradient. 2. Name each of the newly drawn circles leftLeg, rightArm, and so on, by selecting them and typing in a name in the Properties pane. You’ll notice while Blend is all black and has a different UI than you’re used to, the metaphors of object selection, properties panes, and naming are familiar from your experience using Visual Studio. Blend is almost like ‘‘Visual Studio for Designers.’’ Alternatively, if you don’t like using the visual editor in Blend as seen in Figure C-10, you can just copy and paste the XAML directly. Figure C-10 1619 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1620 Appendix C: Silverlight Editing in Notepad You can edit in your favorite XML editor or even Notepad. Each ‘‘pain dot’’ is a snippet of XAML that resembles Listing C-3: Listing C-3: A XAML Ellipse <Canvas x:Name="leftarm" Width="193" Height="60" Canvas.Left="377.762" Canvas.Top="261.857"> <Rectangle Width="193" Height="60" Fill="Transparent"></Rectangle> <Ellipse Stroke="#FF000000" Width="50" Height="50" Visibility="Collapsed" Canvas.Left="57" Canvas.Top="8"> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="#FFff0000" Offset="0"/> <GradientStop Color="#FFffddaa" Offset="1"/> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> </Canvas> Listing C-3 is an example of an ellipse with a filled gradient between red and a shade of light-gray. The only differences between the six pain dots are these: ❑ x:Name attribute: In order for a Silverlight element to be ‘‘addressable’’ from JavaScript, it should have a name. ❑ Canvas.Left="x" Canvas.Top="y" attributes: These indicate the position of the elements within the larger canvas. You can certainly edit XAML manually in Notepad and preview your changes in Internet Explorer via the very repetitive ‘‘Edit, Refresh in Browser, Edit, Refresh in Browser,’’ technique if you like, but we recommend using Blend. Notice also the Visibility attribute. You want these dots to be initially invisible, so they are marked as Visibility="Collapsed" . You will toggle the dot’s visibility in JavaScript code. Draw all the dots and position them first before you make their Visibility="Collapsed" . Just before you hit the dots, you’ll have a person that resembles Figure C-11. Integrating with Your Existing ASP.NET Site All right, now that you have our imported and edited ‘‘Chiro Dude,’’ let’s add him to the site. You have a few choices. You can copy over the Silverlight.js and the other assets and simply add them to your Visual Studio Project as content. The Javascript files can be added as standard script references on your ASPX pages and the Silverlight div added manually. 1620 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1621 Appendix C: Silverlight Figure C-11 However, Microsoft often has ‘‘Futures Releases’’ or ‘‘Previews’’ that showcase coming technologies that make things easier. The ASP.NET 3.5 Extensions Preview at the time of this writing is available at http://www.asp.net/downloads/3.5-extensions/ . It includes a preview of some new controls that will arrive around the first half of 2008 as a downloadable add-on to the .NET Framework 3.5. These controls will simply be added into the Visual Studio Toolbox and make things easier. You should be able to get these controls within a few months of the publication of this very book! Remember earlier when we created three JavaScript files and needed to check ID attributes to instan- tiate a new Silverlight Control? The asp:Silverlight and improved asp:ScriptManager controls will likely make that process easier. 1621 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1622 Appendix C: Silverlight An update of Listing C-1 using these controls looks like Listing C-4, with some repetition removed for brevity. Pay special attention to the ScriptReferences in the ScriptManager .Oneuses Name= and one Path= . That is not a typo. The Silverlight JavaScript is referred to by name and is served from an Assembly Resource. It’s compiled into a DLL and served from there by ScriptResource.axd , an HttpHandler for doing just that. The Dude.xaml.js will be served up directly from disk like any other JavaScript file, except you didn’t have to write the script tag because it’s handled for you. Listing C-4: Markup using ASP.NET 3.5 Extensions ASPX <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> <Scripts> <asp:ScriptReference Name="SilverlightControl.js" /> <asp:ScriptReference Path="Dude.xaml.js" /> </Scripts> </asp:ScriptManager> <h1>Patient Form</h1> <div> <table border="1"> OMMITED <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 /> <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> <asp:Silverlight runat="server" ID="Xaml1" Height="475" Width="367" Source="Dude.xaml" ClientType="Custom.SLPerson"></asp:Silverlight> </td> </tr> <tr> <td colspan="2" align="right"> <asp:Button ID="SubmitButton" runat="server" Text="Submit Doctor Request" PostBackUrl="~/Complete.aspx" /> </td> </tr> </table> 1622 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1623 Appendix C: Silverlight </div> </form> </body> </html> In order to get Listing C-4 to work, you’ll need the ASP.NET 3.5 Extensions from http://www.asp.net/downloads/3.5-extensions/ . The release date of this new package was not available at the time of this writing, but watch www.asp.net for all the latest details. At this point, you’ve added the control but there’s no interactivity. He’s on the page, but he doesn’t do anything. You need to expose the named dots that you created earlier. You will use JavaScript to find them within the XAML document and assign them to JavaScript variables. Silverlight is very good at being transparent. Once you’ve gotten hold of a Silverlight object within JavaScript, you can treat it just like any other JavaScript object. Notice that the ID in this case of the Silverlight object is ‘‘Xaml1.’’ Receiving Silverlight Events in JavaScript You start your JavaScript by creating a ‘‘class’’ called personElements with each of the dots. They are initially set to null because you find them in the initializeComponent method that acts as your con- structor. Notice how slhost is passed into initializeComponent. Then you access its content node and use findName to grab each of the named body part dots, storing them away in variables as seen in Listing C-5. Listing C-5: Dude.xaml.js JavaScript /// <reference name="MicrosoftAjax.js"/> /// <reference name="SilverlightControl.js"/> personElements = function() { this.leftarm = null; this.rightarm = null; this.head = null; this.leftleg = null; this.rightleg = null; this.torso = null; } personElements.prototype = { initializeComponent: function(slhost) { var host = slhost.content; this.leftarm = host.findName("leftarm"); this.rightarm = host.findName("rightarm"); this.head = host.findName("head"); Continued 1623 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1624 Appendix C: Silverlight this.leftleg = host.findName("leftleg"); this.rightleg = host.findName("rightleg"); this.torso = host.findName("torso"); } } Type.registerNamespace("Custom"); Custom.SLPerson = function(element) { Custom.SLPerson.initializeBase(this, [element]); this._designer = new personElements(); } Custom.SLPerson.prototype = { initialize : function() { Custom.SLPerson.callBaseMethod(this, ’initialize’); // Call on the component initialized to get the // specific component’s XAML element fields. this._designer.initializeComponent(this.get_element()); // Hookup event handlers as required in this custom type. var onClick = Function.createDelegate(this, this._onPersonClick); this.addEventListener(this._designer.leftarm, "mouseLeftButtonUp", onClick); this.addEventListener(this._designer.rightarm, "mouseLeftButtonUp", onClick); this.addEventListener(this._designer.head, "mouseLeftButtonUp", onClick); this.addEventListener(this._designer.leftleg, "mouseLeftButtonUp", onClick); this.addEventListener(this._designer.rightleg, "mouseLeftButtonUp", onClick); this.addEventListener(this._designer.torso, "mouseLeftButtonUp", onClick); }, _onPersonClick : function(sender, e) { var region = sender.Name; this.toggleVisibility(region); var elem = $get(region + "CheckBox"); elem.checked = !elem.checked; }, toggleVisibility : function(region) { var elem = this._designer[region]; var wasVisible = (elem.children.getItem(1).Visibility == "Visible"); elem.children.getItem(1).Visibility = wasVisible ? "Collapsed" : "Visible"; } } Custom.SLPerson.registerClass(’Custom.SL Pers on’, Sys.UI.Silverlight.Control); After finding those parts, you hook up to the mouseLeftButtonUp event and attach it to _onPersonClick . That method will get called each time you click a dot. 1624 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1625 Appendix C: Silverlight Within _onPersonClick you call a new method toggleVisibility that will not only change the visibility of the dot, but also use an ASP.NET Ajax JavaScript method $get() to grab onto a similarly named HTML checkbox and toggle its checked property. At this point, clicking on the Chiro Dude in certain spots toggles the dots and checkboxes simultaneously. However, you also need to hook event handlers up to the checkboxes themselves so that they toggle the dots within the Chiro Dude. Accessing Silverlight Elements from JavaScript Events You can use the $find() method to access our Silverlight control. What’s this? There’s $find() and $get() ? What’s the difference between these two methods? Well, $find() isashortcutfor Sys.Application.findComponent ,whereas $get() is an alias for the getElementById method. The $get() method will work on any browser, even those without support for getElementById . Generally, $find() is useful for getting a reference to a Silverlight control from within JavaScript, whereas $get() is typically used for getting references to standard HTML controls, DIVS, and SPANS. Now, let’s add these attributes to our check boxes: <asp:CheckBox ID="headCheckBox" runat="server" Text="Head" OnClick="$find(’Xaml1’).toggleVisibility(’head’)" /> <br /> <asp:CheckBox ID="leftarmCheckBox" runat="server" Text="Left arm" OnClick="$find(’Xaml1’).toggleVisibility(’leftarm’)" /> <br /> <asp:CheckBox ID="rightarmCheckBox" runat="server" Text="Right arm" OnClick="$find(’Xaml1’).toggleVisibility(’rightarm’)" /> <br /> <asp:CheckBox ID="torsoCheckBox" runat="server" Text="Torso" OnClick="$find(’Xaml1’).toggleVisibility(’torso’)" /> <br /> <asp:CheckBox ID="leftlegCheckBox" runat="server" Text="Left leg" OnClick="$find(’Xaml1’).toggleVisibility(’leftleg’)" /> <br /> <asp:CheckBox ID="rightlegCheckBox" runat="server" Text="Right leg" OnClick="$find(’Xaml1’).toggleVisibility(’rightleg’)" /> Here you’ve added a $find() call to grab your Silverlight controls. Then you call the toggleVisbility method that you added in Listing C-5. You’ve completed the cycle and now users can click the check boxes or the Chiro Dude in order to make their selection. And, because the resulting Form POST still uses the values of the check boxes, you haven’t had to change any server-side code. The completed application is shown in Figure C-12. Notice that the check boxes and Chiro Dude’s pain dots are in sync. 1625 Evjen bapp03.tex V1 - 01/28/2008 4:41pm Page 1626 Appendix C: Silverlight Figure C-12 Summary Silverlight 1.0 has a very clean, very natural programming model that feels familiar to developers who have programmed against the JavaScript DOM or worked with AJAX code of any kind. The bridge between Silverlight and JavaScript is seamless, allowing ASP.NET developers to mix and match Sil- verlight and HTML as they like. Programming with Silverlight will get even easier in the near future when a minor release adds Sil- verlight Server Controls and an improved ScriptManager to ASP.NET 3.5. 1626 . technologies that make things easier. The ASP. NET 3. 5 Extensions Preview at the time of this writing is available at http://www .asp. net/ downloads /3. 5- extensions/ . It includes a preview of some new controls that. panes, and naming are familiar from your experience using Visual Studio. Blend is almost like ‘ Visual Studio for Designers.’’ Alternatively, if you don’t like using the visual editor in Blend. Canvas.Top="y" attributes: These indicate the position of the elements within the larger canvas. You can certainly edit XAML manually in Notepad and preview your changes in Internet Explorer via the very