[This topic is pre-release documentation and is subject to change in future releases of Microsoft Silverlight.]
Silverlight supports programming in JavaScript, which enables you to add interactivity to your content.
This document contains the following sections.
scripting and events
Silverlight enables you to run JavaScript code when an event occurs, such as when an object is loaded or the mouse enters an object. Such a script is called an "event handler".
To define an event handler, follow three steps.
-
In your XAML file, add the following attribute to the object that will trigger your function.
...where someEvent is the event to which you want to respond and myFunction is the name of the function that you want to handle the event.
- Define the function in your JavaScript file. (For information about setting up a JavaScript file, see Setting up your first files.)
Now try an example. In Silverlight, all Canvas and shape elements have an event called MouseLeftButtonDown which occurs when you (the user) pushes the left mouse button down while the mouse pointer is over that element. You will write an event handler for that event that uses the JavaScript alert function to create a dialog box.
[hide XAML]
<Canvas Height="300" Width="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="transparent"
MouseLeftButtonDown="helloworld">
<TextBlock Text="click me" FontSize="50"/>
</Canvas>
[hide JavaScript]
function helloworld() {
alert("hello world");
}
[hide]
[restart]
You do not have to specify parameters when you declare an event handler function. But
if you do specify parameters, the first parameter, sender, is the element that sends the event. The second parameter, args, is an object that contains data about the event. However, not all events will transmit specific event information in args; often the value of that parameter is null and is not useful for your event handler.
setting properties
You can set properties of Silverlight objects using JavaScript. When a property takes a value that is a string or a number, you can set it normally in JavaScript. If the property takes a Silverlight object and it has a type converter, such as a SolidColorBrush or Point, you can set the value using a string. Otherwise, you need to use the createFromXaml method to instantiate a new property value.
The following example registers for the MouseLeftButtonDown event of a Canvas. In the event handler, the sender parameter provides access to the Canvas. The example sets the Background property of the Canvas to red and displays the current value of the its Height property.
[hide XAML]
<Canvas Width="300" Height="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="changecolor">
<TextBlock Text="click me" FontSize="50"/>
</Canvas>
[hide JavaScript]
function changecolor(sender, args) {
sender.background = "red";
alert("Height is " + sender.Height);
}
[hide]
[restart]
setting attached properties
To set the value of an attached property, such as Canvas.Top, in JavaScript, you use the following syntax.
object["attachedPropertyName"] = value; |
....where attachedPropertyName is the name of the attached property you want to set.
The following example sets the Canvas.Top property of a TextBlock to 70 when the left mouse button is pressed.
[hide XAML]
<Canvas Width="300" Height="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<TextBlock Text="click me" FontSize="50"
MouseLeftButtonDown="changelocation" />
</Canvas>
[hide JavaScript]
function changelocation(sender, args) {
sender["Canvas.Top"] = 70;
}
[hide]
[restart]
common mouse events
UIElement objects provide a number of different mouse events you can handle: MouseLeftButtonDown, MouseLeftButtonUp, MouseEnter (raised when the mouse goes over the element), MouseLeave, and MouseMove (raised when the mouse is moved inside the element). Mouse events have an "args" object that provides the x and y
position of the mouse when the event occurred, which you will typically reference in handlers for mouse events.
The following example uses each of these mouse events to modify the appearance of an Ellipse.
[hide XAML]
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Ellipse x:Name="e1" MouseMove="e1Move"
MouseEnter="e1Enter" MouseLeave="e1Leave"
MouseLeftButtonDown="e1Down" MouseLeftButtonUp="e1Up"
Height="100" Width="100" Canvas.Left="80" Canvas.Top="30"
Stroke="Black" StrokeThickness="10" Fill="LightBlue"/>
</Canvas>
[hide JavaScript]
function e1Enter(sender, args) {
sender.stroke = "red";
}
function e1Leave(sender, args) {
sender.stroke = "black";
}
function e1Down(sender, args) {
sender.fill = "Green";
}
function e1Up(sender, args) {
sender.fill = "LightBlue";
}
function e1Move(sender, args) {
sender.fill = "yellow";
}
[hide]
[restart]
Another very useful event for Silverlight programming is the Loaded event. Usually you register handlers for this event with a declaration at the root element, but Loaded can
be specified on any UIElement, not just the root. The
Loaded event provides a good opportunity to apply any last changes as your Silverlight content is displayed. The following example uses a Loaded event handler to change the Fill of an Ellipse from Blue to Red.
[hide XAML]
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Ellipse Loaded="ellipse_loaded"
Height="200" Width="200"
Canvas.Left="30" Canvas.Top="30"
Stroke="Black" StrokeThickness="10" Fill="LightBlue"/>
</Canvas>
[hide JavaScript]
function ellipse_loaded(sender, args) {
sender.Fill = "Red";
}
[hide]
[restart]
naming objects and retrieving them
The preceding examples used JavaScript event handlers to modify the object
that raised the event, but what happens if you want to use methods or set properties of an object other than the sender? Silverlight elements provide a method called FindName that enables you to retrieve Silverlight objects from any frame of reference within the Silverlight content. To use FindName to retrieve an object, you must first specify the x:Name attribute (or the Name attribute/property, which is essentially equivalent) to give that object a name when
you declare it in XAML.
The following example changes the Fill property of an
Ellipse when the left mouse button is pressed over its parent Canvas. When the Canvas raises the event, the changeEllipseColor function is called with Canvas as the sender. The
function calls sender.findName() to retrieve the object named myEllipse and set its Fill
to Red.
[hide XAML]
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="changeEllipseColor">
<TextBlock Text="click me" FontSize="50"/>
<Ellipse x:Name="myEllipse"
Height="200" Width="200"
Canvas.Left="30" Canvas.Top="80"
Stroke="Black" StrokeThickness="10" Fill="LightBlue"/>
</Canvas>
[hide JavaScript]
function changeEllipseColor(sender, args) {
sender.findName("myEllipse").Fill = "red";
}
[hide]
[restart]
dynamically creating Silverlight objects
You can use the CreateFromXaml method to create new Silverlight objects in JavaScript. But before you can use the CreateFromXaml method, you must obtain a reference to a Silverlight plug-in instance.
- If you already have a reference to any Silverlight object, you can use the GetHost method to return a reference to the plug-in instance that hosts it.
- Otherwise, use the
document.getElementById method to retrieve the plug-in instance.
The following example creates a new Ellipse object and adds it to a Canvas each time the left mouse button is pressed. Note that although you are adding multiple objects if you click more than once, you will see only one ellipse. That is because all the ellipses look exactly alike, and are drawing on top of each other.
[hide XAML]
<Canvas Width="300" Height="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="createEllipse">
<TextBlock Text="click for circle" FontSize="40"/>
</Canvas>
[hide JavaScript]
function createEllipse(sender, args) {
var slControl = sender.getHost();
var e =
slControl.content.createFromXaml(
'<Ellipse Height="200" Width="200" Fill="Blue"/>');
var canvas = sender;
canvas.children.Add(e);
}
[hide]
[restart]
Note that JavaScript requires you to put strings on a single line, unless you combine multiple strings using the + operator. Also note the use of both single quotes (') and double quotes (") in the <Ellipse> XAML string. Starting and ending the JavaScript string with single quotes enables you to use
double quotes for values in the XAML string, or vice versa. Just make sure the single and double quotes balance correctly.
dynamically creating Silverlight objects, with XAML string manipulation
The previous example showed one potentially undesirable side effect of adding the same XAML to the page more than once. If you do want to add objects with XAML, it is often desirable to change that XAML in some way each time. You can do that by adjusting the XAML string immediately before each call.
The following example creates a new Ellipse object and adds it to a Canvas each time the left mouse button is pressed, but this time three properties of the Ellipse will change each time so that you can see that there really are multiple objects being added to the page.
[hide XAML]
<Canvas Width="300" Height="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="createEllipse2">
<TextBlock Text="click for Lots of circles" FontSize="20"/>
</Canvas>
[hide JavaScript]
var opacitychange = 1;
var canvastop = 0;
var canvasleft = 0;
function createEllipse2(sender, args) {
var slControl = sender.getHost();
xamlstring = '<Ellipse Height="10" Width="10" Fill="Red"';
xamlstring += " Opacity = '" + (opacitychange-=0.1) + "'";
xamlstring += " Canvas.Left = '" + (canvasleft+=15) + "'";
xamlstring += " Canvas.Top = '" + (canvastop+=15) + "'";
xamlstring += "/>";
var e = slControl.content.createFromXaml(xamlstring);
var canvas = sender;
canvas.children.Add(e);
}
[hide]
[restart]
controlling animations interactively
You can use event handlers can control animations. Assign a name to the Storyboard that you want to control and then you can use its begin, Stop, Pause, and Resume methods to control it interactively. If you do not want the Storyboard to begin automatically, declare it as a resource rather than declaring it inside an EventTrigger.
[hide XAML]
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas.Resources>
<Storyboard x:Name="animation"
Storyboard.TargetName="e1"
Storyboard.TargetProperty="(Canvas.Left)">
<DoubleAnimation RepeatBehavior="Forever" To="300"/>
</Storyboard>
</Canvas.Resources>
<Ellipse x:Name="e1"
Height="20" Width="20" Canvas.Left="30" Canvas.Top="30">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.75,0.25">
<GradientStop Color="White" Offset="0.0" />
<GradientStop Color="Black" Offset="0.5" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Canvas MouseLeftButtonDown="animation_stop" Canvas.Left="20" Canvas.Top="60">
<Rectangle Stroke="Black"
Height="40" Width="40" RadiusX="5" RadiusY="5">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="0.75,0.25">
<GradientStop Color="Orange" Offset="0.0" />
<GradientStop Color="Red" Offset="1.0" />
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Canvas.Left="5" Canvas.Top="5">stop</TextBlock>
</Canvas>
<Canvas MouseLeftButtonDown="animation_pause"
Canvas.Left="70" Canvas.Top="60">
<Rectangle Stroke="Black"
Height="40" Width="50" RadiusX="5" RadiusY="5">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="0.75,0.25">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Orange" Offset="1.0" />
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Canvas.Left="5" Canvas.Top="5">pause</TextBlock>
</Canvas>
<Canvas MouseLeftButtonDown="animation_begin" Canvas.Left="130" Canvas.Top="60">
<Rectangle Stroke="Black" RadiusX="5" RadiusY="5"
Height="40" Width="50">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="0.75,0.25">
<GradientStop Color="LimeGreen" Offset="0.0" />
<GradientStop Color="Green" Offset="1.0" />
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Canvas.Left="5" Canvas.Top="5">begin</TextBlock>
</Canvas>
</Canvas>
[hide JavaScript]
function animation_stop(sender, args) {
sender.findName("animation").stop();
}
function animation_pause(sender, args) {
sender.findName("animation").pause();
}
function animation_begin(sender, args) {
sender.findName("animation").begin();
}
[hide]
[restart]
using getElementById to retrieve or create objects
When you are writing script that is not triggered by a Silverlight event (such as an
HTML event handler), you will not have a sender parameter that can provide access to the
FindName or GetHost methods. In this case, you can use document.getElementById() to find the Silverlight plug-in, then use the Silverlight plug-in object to call the FindName method.
The following example uses the document.getElementById() method to find the Silverlight plug-in instance named sl9. It then uses FindName method to retrieve the Silverlight plug-in instance named myEllipse and changes its Fill to red.
[hide XAML]
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="changeEllipseColor2">
<TextBlock Text="click me" FontSize="50"/>
<Ellipse x:Name="myEllipse"
Height="200" Width="200"
Canvas.Left="30" Canvas.Top="80"
Stroke="Black" StrokeThickness="10" Fill="LightBlue"/>
</Canvas>
[hide JavaScript]
function changeEllipseColor2() {
var sl9 = document.getElementById("sl9");
sl9.content.findName("myEllipse").fill = "red";
}
[hide]
[restart]
In the previous example, sl9 is the HTML DOM ID of the Silverlight plug-in instance you created in your host HTML file when you called Silverlight.createObject(), as described in the part 1: create a Silverlight project document.
// Retrieve the div element you created in the previous step.
var mySilverlightPluginHost = document.getElementById("sl9Host");
createMySilverlightPlugin();
Silverlight.createObject(
"sl9.xaml",
sl9Host,
"sl9",
{
width:'300',
height:'300',
inplaceInstallPrompt:false,
background:'#D6D6D6',
isWindowless:'false',
framerate:'24',
version:'1.0'},
{onError:null, onLoad:null},
null);
what's next
The next topic, sample controls,
describes how to compose basic controls.
Copyright © 2008 Microsoft Corporation.
All rights reserved. Legal Notices.