// 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
Trang 1// 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 thehttp://schemas
.microsoft.com/winfx/2007namespace tohttp://schemas.microsoft.com/winfx/2006/xaml/
presentationin 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
Trang 2Microsoft 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
Trang 3Adding 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
Trang 4Editing 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:Nameattribute: 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 Silverlightdivadded manually
Trang 5Figure 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
athttp://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? Theasp:Silverlightand improvedasp:ScriptManagercontrols
will likely make that process easier
Trang 6An update of Listing C-1 using these controls looks like Listing C-4, with some repetition removed
for brevity Pay special attention to theScriptReferencesin theScriptManager One usesName=
and onePath= 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 thescripttag
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>
Trang 7</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’’ calledpersonElementswith each of the dots They are
initially set to null because you find them in theinitializeComponentmethod that acts as your
con-structor Notice howslhostis passed intoinitializeComponent.Then you access itscontentnode
and usefindNameto 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
Trang 8this.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.SLPerson’, Sys.UI.Silverlight.Control);
After finding those parts, you hook up to themouseLeftButtonUpevent and attach it to_onPersonClick
That method will get called each time you click a dot
Trang 9Within_onPersonClickyou call a new methodtoggleVisibilitythat 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 itscheckedproperty
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()is a shortcut forSys.Application.findComponent, whereas$get()is an alias for the
getElementByIdmethod 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 thetoggleVisbility
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
Trang 10Figure C-12
Summar y
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