January 2008 - Posts
If you are testing your code, or going to other pages with Silverlight running and seeing this error:
It is not your fault!
This is the result of a recently discovered bug that we know how to fix. We are working hard to get that fix out so that you won't run into this problem.
For now, the work around is this: if you try the page again, you'll usually find that it will load just fine (or the second or third time <smile>.)
I will post as soon as we have more information, and I apologize for the inconvenience this may be causing.
I've received the following question (in various forms) three times in the past two weeks, so I'm going to take the opportunity to post it and my response (such as it is) here.
"... I read that if Microsoft had supported SVG, this there would have been no need for Silverlight and that Silverlight is just a reinvention of SVG to protect Internet Explorer."
"The blogs say that Silverlight is just SVG reinvented to be owned by Microsoft"
My attempt at a reply usually boils down to something like this...
I never know how to begin to answer questions like this. If Silverlight and SVG were equivalent technologies, this might be a debate that some would benefit from, but I believe they are really quite different, serving different purposes. Silverlight is an emerging technology in the spectrum of .NET tools for developing applications and I think you'll find that the appeal of Silverlight, strong as it is, will be an order of magnitude stronger when we unwrap Silverlight 2 in a few weeks.
I don’t mean to dismiss your question; it is just not what I do; I’m best at helping folks learn and use Silverlight, not defending it in comparisons to putative alternative technologies.
Technorati Profile
Can't resist posting this here too...
Chris Sells asked for geek limericks here, so I tried my hand....

Thank you if you were able to join our Webcast Silverlight For Total Novices. (If you were unable to attend, please keep an eye on the events page for the Recording.)
In the time we had, we could only scratch the surface, but a number of resources were mentioned and I wanted to make sure that I posted links to them so that you can find them easily. While I'm at it I'll add a few other valuable resoruces that were not mentioned.
In imperfect order they include:
1. The best starting point is the Silverlight Site
2. You may want to read my post Silverlight For Total Novices that reviews the steps for downloading what you need and recommends which videos to watch and in what order (This post by Tim Heuer explains why you need the Silverlight tools for Visual Studio 2008 even though you are building 1.0 applications and the tool says it is for 1.1!)
3. A great next stop is the Fire Starter tutorials.
4. The "How Do I" videos on creating shapes, fill, transforms, drag and drop and streaming are all here.
5. If you are interested in what is coming in Silverlight 2.0, Scott Guthrie's announcement is the third item in this blog entry.
6. Questions and Answers can be found on our forum
Thanks again and best of luck!
Technorati Profile
In a great blog listing today, Tim Sneath discusses Infragistics just released NetAdvantage control set for WPF. In his excellent write up, Tim links to this incredible screenshot from Infragistics of an app that they "very quickly" build with WPF and their controls
Yowza!
This is great news, but being a total Silverlight Geek, I was immediately jealous: hey, where's ours?
<slap!> One company, one team. <slap!>
Yeah, but awww....
Well, <whew> I was glad to see that Infragistics is on on the case! Turns out that they are already building some prerelease 2.0 control prototypes, including this cool gauge,
I'll try to give some exposure to other companies that are also working on control sets for Silverlight 2.0 from time to time. There are a lot of exciting things cooking.
<corny>
Could be!
Who knows?
There's something due any day;
I will know right away,
Soon as it shows...
Could it be? Yes, it could.
Something's coming, something good,
If I can wait!
Something's coming, I don't know what it is,
But it is
Gonna be great!
lyrics by Stephen Sondheim.
© 1956, 1957 Amberson Holdings LLC and Stephen Sondheim. Copyright renewed.
Leonard Bernstein Music Publishing Company LLC, Publisher.
</corny>
Adam Kinney has worked with Dave Campbell to feed Silverlight Cream to Twitter.
You can subscribe here. In addition, Adam has created a script for placing this news into his (or your!) web log and formatting it.
You can download the script here, along and read full details on how to use it on your own site as well. Once in place, its all automagic.
More on this to come!
Technorati Profile
 | The Tip of The Day is moving its release schedule to be more predictable.... Starting today, the Tip of the Day will be published at 1PM Eastern (GMT -5) seven days a week (except when it isn't). |
I will work hard that the majority of the Tips of the Day per week contain code and are substantive mini-lessons, while other Tips are about using the tools well, best practices and lessons learned.
In addition to the Tip of the Day, I will continue to post ad-hoc entries as information arises, events happen, or the mood strikes.
If you have suggestions for Tips of the Day (especially if your suggestions come with small example code) please send them my way; if I use your Tip of the Day I'll be happy to credit you (complete with a link to your blog or web site).
Thanks.
-jesse
Technorati Profile
A reader wrote and asked: "A quick question: how did you set your VS to format the XAML in the way that it does?"
Here's how to do it:
In Visual Studio click on Tools -> Options
When the Options window opens, make sure Show All Settings is clicked, and then click on the triangle next to Text Editor to expand that section
Scroll down to XAML and expand it. Click on each sub-category (General, Tabs, and expand Formatting) to set the options for formatting XAML the way you want. When you are done click OK.
Once all of your options are set the way you want them, you may want to back up your options by selecting Tools -> Import and Export Settings (a topic for another Tip of the Day)
Technorati Profile
Three are many details to creating a Silverlight Streaming application, but in this post I'm going to try to boil them down to a recipe for fast success.
1. Create an account for yourself on the Silverlight Wiidows Live (alpaha) site. 4GB hosting is free, but read the fine print at the bottom of the page.
Once you are set, ignore that for a while and create a simple Silverlight application that does something (e.g., drag and drop). If you don't want to bother, just steal mine.
First Get It Working As A Normal Silverlight Control
Scene.xaml
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Ellipse x:Name="myEllipse"
Canvas.Left="10"
Canvas.Top ="150"
Height="100"
Width="100"
Fill="Red"
Stroke="Black"
StrokeThickness="3" />
<Rectangle x:Name="mySquare"
Height="100"
Canvas.Left="150"
Canvas.Top="150"
Width="100"
Fill="Blue"
Stroke="Black"
StrokeThickness="3" />
</Canvas>
Scene.xaml.js
if (!window.Streaming)
window.Streaming = {};
Streaming.Scene = function()
{
}
Streaming.Scene.prototype =
{
handleLoad: function(plugIn, userContext, rootElement)
{
this.plugIn = plugIn;
this.beginX;
this.beginY;
this.trackingMouseMove = false;
this.ellipse = this.plugIn.content.FindName("myEllipse");
this.rect = this.plugIn.content.FindName("mySquare");
this.ellipse.addEventListener("MouseLeftButtonDown",
Silverlight.createDelegate(this, this.handleMouseDown));
this.ellipse.addEventListener("MouseLeftButtonUp",
Silverlight.createDelegate(this, this.handleMouseUp));
this.ellipse.addEventListener("MouseMove",
Silverlight.createDelegate(this, this.handleMouseMove));
this.rect.addEventListener("MouseLeftButtonDown",
Silverlight.createDelegate(this, this.handleMouseDown));
this.rect.addEventListener("MouseLeftButtonUp",
Silverlight.createDelegate(this, this.handleMouseUp));
this.rect.addEventListener("MouseMove",
Silverlight.createDelegate(this, this.handleMouseMove));
},
handleMouseDown: function(sender, mouseEventArgs)
{
this.beginX = mouseEventArgs.getPosition(null).x;
this.beginY = mouseEventArgs.getPosition(null).y;
this.trackingMouseMove = true;
sender.captureMouse();
},
handleMouseUp: function(sender, eventArgs)
{
this.trackingMouseMove = false;
sender.releaseMouseCapture();
},
handleMouseMove: function(sender, mouseEventArgs)
{
if ( this.trackingMouseMove == true )
{
var currentX = mouseEventArgs.getPosition(null).x;
var currentY = mouseEventArgs.getPosition(null).y;
sender["Canvas.Left"] += currentX - this.beginX;
sender["Canvas.Top"] += currentY - this.beginY;
this.beginX = currentX;
this.beginY = currentY;
}
}
}
Make It A Streaming Control
Once your code is working and debugged, here are the steps to move it to a streaming application:
-
Change the event-handling wire-up from the .js file to the XAML file. [I believe this is a bug, and I've filed a query about it] .
Scene.xaml
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Ellipse x:Name="myEllipse"
Canvas.Left="10"
Canvas.Top="150"
Height="100"
Width="100"
Fill="Red"
Stroke="Black"
StrokeThickness="3"
MouseLeftButtonDown="onMouseDown"
MouseLeftButtonUp="onMouseUp"
MouseMove="onMouseMove" />
<Rectangle x:Name="mySquare"
Height="100"
Canvas.Left="150"
Canvas.Top="150"
Width="100"
Fill="Blue"
Stroke="Black"
StrokeThickness="3"
MouseLeftButtonDown="onMouseDown"
MouseLeftButtonUp="onMouseUp"
MouseMove="onMouseMove" />
</Canvas>
Scene.xaml.js
Streaming.Scene.prototype =
{
handleLoad: function(plugIn, userContext, rootElement)
{
}
}
var beginX;
var beginY;
var trackingMouseMove = false;
function onMouseDown(sender, mouseEventArgs)
{
beginX = mouseEventArgs.getPosition(null).x;
beginY = mouseEventArgs.getPosition(null).y;
trackingMouseMove = true;
sender.captureMouse();
}
function onMouseUp(sender, mouseEventArgs)
{
trackingMouseMove = false;
sender.releaseMouseCapture();
}
function onMouseMove(sender, mouseEventArgs)
{
if ( trackingMouseMove == true )
{
var currentX = mouseEventArgs.getPosition(null).x;
var currentY = mouseEventArgs.getPosition(null).y;
sender["Canvas.Left"] += currentX - beginX;
sender["Canvas.Top"] += currentY - beginY;
beginX = currentX;
beginY = currentY;
}
}
2. Change the Silverligh.js script statement in Default.html
<script type="text/javascript" src="http://agappdom.net/h/silverlight.js"></script>
3. Modify the div in Default.html adding a varaible for the parent id (that points to the div that holds the script, and change the first letter of createSilverlight to uppercase (we'll be adding that method in a moment)
<div id="mySilverlightControlHost">
<script type="text/javascript">
var parentElement = document.getElementById("mySilverlightControlHost");
CreateSilverlight();
</script>
</div>
4. Replace the function createSilverlight() with the new function CreateSilverlight()
function CreateSilverlight()
{
Silverlight.createHostedObjectEx(
{
source: "streaming:/[AccountID]/[ApplicationName]",
parentElement: document.getElementById(["mySilverlightControlHost"])
});
}
There are three elements here to replace (I've placed them in square brackets)
- AccountID - Assigned to you when you receive your Streaming Account (see picture below)
The Application Name
The ID of the Div (in the example shown above, mySilverlightControlHost
5. Create a Manifest File that describes the app. Note that you need to designate the xaml file, the method to call on load, and the js files.It must be called Manifest.xml
<?xml version="1.0" encoding="utf-8" ?>
<SilverlightApp>
<source>Scene.xaml</source>
<onLoad>CreateSilverlight()</onLoad>
<version>1.0</version>
<width>600</width>
<height>400</height>
<jsOrder>
<js>http://agappdom.net/h/silverlight.js</js>
<js>Default.html.js</js>
<js>Scene.xaml.js</js>
</jsOrder>
</SilverlightApp>
6. Right click on the Solution and click on "Open Folder in Explorer" In the File explorer select Scene.xaml, Scene.xaml.js and Manifest.xml and right click to create a zip file, which will allow you to craete a zip file with the name of your application, which is just what you want.
7. Return to the streaming application (remember the streaming application?) and click on Manage Applications
8. Click on Upload a Silverlight Application and fill in the Application Name and then click on the Browse button to find the zip file you created. Once the name of the Zip file is in the window, click upload.
9. Once the application is uploaded you can quickly test that it is working by clicking on Launch Application Test Page
10 Assuming your Streaming Silverlight application works fine in the test page, there are now two ways for you to deploy. The Manage Applications page that you are returned to provides you with three explicit steps and the needed code to add your application to any Web Page
Finally, you can also add the streaming application to your page by using an IFrame,
<iframe src=http://silverlight.services.live.com/invoke/20712/StreamingDragAndDrop/iframe.html
frameborder="1" width="400" scrolling="no" height="180"></iframe>
You can drop this IFrame into virtually any web page or blog and it "just works"
We are working on making it work in this blog, in fact, but for now, you can see it working here
Technorati Profile
This is, as you may have guessed, the follow up to the previous Tip of the Day on Animation.In today's Tip of the Day I'd like to distinguish between three types of KeyFrame Animation:
- Lineear
- Discrete
- Spline
Keyframe Vs "From,To"
The main feature that distinguishes all three of these from the "From-To" animation considered previously is that previously we identified a target property and changed it from one value to a new value over a specific duration.
With KeyFrame animation you have far greater control, because you name each discrete time and the value to correspond to that time for the selected value. You can have as many discrete value/time combinations as you like, and you do not have to distribute them evenly.
Linear
Let's start with the most directly comparable keyframe animation: Linear. This is defined by filling your storyboard with a DoubleAnimationUsingKeyFrames, which you name and to which you assign both a TargetName (the object you wish to animate) and a TargetProperty, much as you do with From,To. Within this element, however, you may put as many LinearDoubleKeyFrame sub-elements as you choose. Each one has its own KeyTime property along with a value, and the animation will move from one KeyTime to the next, spreading the animation evenly between sequential keytimes (thus the name Linear). As a first attempt, let's add four times, making the distribution of time and distance equal,
We are temporarily unable to have streaming applications work from within my blog. To see this working, please click here
Of course, if you change the relative time between KeyTimes, you will see the box move at a varying rate as it adjusts to the demands to arrive at a particular value at a particular time, but the speeed between each specific LinearDoubleKeyFrame and the next will be evently distributed,
Discrete Key Frames
With Discrete key frames, the value is not changed at all until the time for the next key frame is reached. In the case of animation, the box will not move from its current position to its next position until the time of the next keyframe.
Spline
Spline animations are based on piecewise polynomial parametric curves, most notably the Bezier curve.
The SplineDoubleKeyFrame has a KeySpline property that specifies the cubic Bezier curve that defines the progress of the key frame. A cubic Bezier curve is defined by a start point, an end point and two control points. The coordinates in the KeySpline define the two control points. The curve controls the rate of change in the animation over the time allowed.
The net effect is that by specifying the start, end and control points of the curve, you actually specify the "acceleration" or "decelration" of the animation; providing the ability to crate much more "real world" realistic animation, as demonstrated (feebly) below.
Technorati Profile
The Tip of the Day is usually posted at 10 AM Eastern Time (GMT -5).
Updated: 11:30 EST - Well, truth be told I'm trying to demonstrate keyframe animation in a new and inteteresting way and rather than giving up on my idea, I've chosen to keep at it and delay the Tip of the Day until tomorrow. I very much appreciate your patience,and I hope it will be worth it.
Confession: like many programmers, once I get that "just another few minutes and I'll have this working" sense, I tend to keep at it long past where it makes any sense at all; after everyone else has lost interest and gone home, and I'm left quite alone with the wind blowing through an empty stadium, bits of debris floating by, and a scraggly cat staring at me wistfuly from under a nearby chair waiting for someone responsible to come and lead me away for a nice meal and a nap.
Update 10AM 1/25/08: After spending too much time on this, I have found what I think may be a small bug in how the streaming service handles some events (if it is a bug, I'll blog it here) and am now ready to finish my Tip of the Day, which I will not have by 10 (since it is now 10) but which I will post later today, with apologies.
Update: 11:50 1/25/08 - Finally! Published.
I must admit that I was at first skeptical about books on Silverlight 1.0 Programming for a number of reasons:
- Silverlight 1.0 is not all that "deep" - there isn't that much to cover
- The online documentation and supplemental information available here on Silverlight.net is extensive
- Cognitive Dissonance: My editor and I had decided to hold off on publishing Programming Silverlight until Silverlight 2.0, strongly convinced that would be the time when there would be a need to tell a story that transcended the documentation.
Did we get it wrong? Perhaps, considering the quality of some of these books, and how well they bring together the learning experience.
Since I work with these folks, and more important, since my own book will no doubt compete with their next edition, I won't critique these in any detail; I urge you to read the reviews on line and to take a long look at each to make sure you find the ones that best meet your own specific needs; but I will say that each of these is worth a look:
Adam's book is notable for its methodical coverage, and its incredibly useful sidebars which include "Digging Deeper" and "Tip" and "Warning" sprinkled liberally throughout. Full color. See Adam's presentation at Fire Starter
This full color book is the only book I've found that has a quality chapter on using Expression Blend for coding Silverlight applications.
This is an extremely readable book by a very knowledgeable member of the team who gave a great talk on Silverlight XAML at Fire Starter.
Other Books You Might Want To Consider
Here are a few other books that I think belong on the shelf of every Silverlight Programmer. If you're interested in my total list of recommendations, please see my complete recommendations page (you may want to click on Technical & Programming to skip over the other books I review) but here are a few essentials...
This is required reading for getting ready for Silverlight 2.0, not to mention one of the best written technical books I've read. Please see my complete review here.
If you are truly serious about .NET programming, you really want this next book handy:
 |
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Microsoft .NET Development Series) by Krzysztof Cwalina, Brad Abrams
Read more about this title... |
Last, but certainly not least, every programmer coding in Silverlight, AJAX or any other technology that might in any way present a User Interface ought to be required to read David Platt's masterpiece:
Do not write another application without reading this book.
Technorati Profile
Since Silverlight 2 is around the corner, and with it Managed Code and LINQ, I'm cross posting the following to both my Silverlight blog and my O'Reilly blog. Hope that isn't too annoying.
I believe it is a major stumbling block, when learning new technology, if you can't say the syntax "out loud in your head." -- that is if you can't read the code to yourself in a way that you can then translate into a meaningful sentence. For example, when learning C#, if you see
int result = employees.Add(237, new Employee("John Doe", theAddressRecord);
If you don't speak C# you can't really read this to yourself without stumbling. What do you do with the dot between employees and Add? What do you do with the commas? the parenthesis? Do you pronounce them (employee dot add?)
if you "speak" C# you can read this to yourself quite easily; perhaps without noticing: "Call the Add method on the Employees object, and pass in a new Employee object, initialized with two parameters, a string and an object and return a value that you will assign to the local integer variable result."
In fact, you'd go much further, based on your knowledge of C# and you'd read it complete with the logical inferences: "add to the Employees dictionary a new Employee object, keyed to the integer value 237. The new Employee's constructor takes two parameters: the Employee's name as a string, and the Employee's address as a AddressRecord. The Add Method of the Dictionary returns an integer indicating success or failure which is assigned to a local variable named result."
Now, I posed the following question to Ian Griffiths: "how do you pronounce this C# LINQ statement:
IEnumerable<Person> results = people.Where(p => p.LastName == “Liberty”);
Ian Griffiths is a consultant, developer, speaker, author, blogger, and to my great fortune, he was one of the technical editors for the fifth edition of my book Programming C# 3.0
Ian's first response to my question was "IEnumerable of Person results equals people dot where p goes to p dot last name equals Liberty .. or just people where last name equals Liberty" ... However, I’ve not spent any time trying to devise a way of saying LINQ that’s necessarily comprehensible to anyone listening who doesn’t have the source code to look at…I’m also wondering if I’m missing a trick question
[Let me note now that I'm abbreviating both Ian's comments and mine to make this readable and keep to the essence of the discussion]
I explained my reasons for wanting to teach how to pronounce it and suggested
Declare results as an instance of a collection that implements the generic interface IEnumerable of Person, and assign to results each member of the collection people (which we assume to be a collection of Person objects) that meets the condition given in the parentheses. The condition is: let p represent each member of people in turn, give me each p where p.LastName is equal to Liberty.”
Ian objected to the two parts I marked in bold.
"First, results holds an instance of a collection, and I prefer to keep the distinction between the variable and the object clear."
After some back and forth, we agreed that it is better to say that results is a reference to an instance of a collection.
Ian's' second objection was more substantive and nailed my misunderstanding. He wrote,
The language suggests that we will assign each matching Person into results, which isn't really true. It could be taken to suggest a process that looks like this:
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (p.LastName == "Liberty") { results.Add(p);
}
and while that might have the same effect, I think it's potentially misleading to think in those terms. (For one thing, the approach shown here will fail for infinite collections. But LINQ is quite happy to evaluate infinite collections lazily, so long as a) you use suitable enumerator and operators, and b) you never ask it to materialize the full results of the query.)
To that end, part of me wants to pare it right down:
"Let 'results' be all the 'Person' objects in 'people' that have a LastName of "Liberty"."
For me that captures the essence, and avoids getting bogged down in details. I like it because it doesn't make many assumptions about what 'people' is. (Specifically...very specifically and somewhat pedantically in fact...it makes the assumption that when we examine people through the standard LINQ 'Where' operator, it appears to contain a set of objects. And I chose my wording very carefully there - that does not mean that 'people' is necessarily a collection of objects. I could for example write a LINQ to SwipeCard library; 'people' might actually be a SwipeCardReader, and I may have provided a Where extension method that can be applied to a SwipeCardReader that returns an enumerator that yields an object each time someone swipes a card that matches the Where predicate. OK that'd be a slightly weird thing to do - I'm just illustrating that there are scenarios in which talking in terms of 'collections' doesn't fit. More pragmatically, in LINQ to SQL and LINQ to Entities, the Where clause ends up getting converted into SQL...so all you know is that it yields filtered output, and you can't talk about how it achieves this in object terms.)
But that doesn't explain the individual pieces. If we want to say precisely what each bit of that code does, we need a more complete explanation. And for that...well I'm still in two minds. It depends on context - how much do we really know about 'people'. Given just that line of code, people could be anything, and we might well be building a query against a database here. The pattern presented is using one of the standard LINQ operators, so it's applicable to LINQ to Objects, LINQ to SQL, and LINQ to anything else that might spit out an object that might have a LastName property. (So I don't think this particular example would work directly with LINQ to XML. However, it's still possible that person was a LINQ to XML query whose SELECT clause happened to project the results into a .NET object. But that would make this LINQ to Objects...)
But if we can assume that 'people' really is a collection objects, and that we're using LINQ to objects, then my 'no stone unturned' version might look like:
"Declare a variable 'results', which will hold an enumerable set of Person objects, calculated by invoking the 'Where' operation on 'people'. 'Where' is a standard LINQ operator that performs filtering. Since 'people' is a collection, the 'Where' operator is provided in this case by LINQ to Objects, and it is an extension method. (So we are really invoking Enumerable.Where here, even though the syntax makes 'Where' look like a member of the object referred to by 'people'.) The parameter to 'Where' is a lambda expression that will be evaluated for each Person 'p' in people. The 'Where' method includes all Person objects for which the expression evaluates to true (i.e., the ones whose LastName property is "Liberty") and excludes the rest. 'Where' returns all of the included objects as an IEnumerable<Person>, which is assigned into the 'results' variable."
Comprehensive and, I fear, unreadable...
This was particularly powerful to me, because I had exactly that foreach loop in my head. I replied acknowledging that, and also highlighting his distinction of a set vs a collection (red emphasis is mine) and I didn't much like the includes / excludes language, and asked about using
the ‘where’ method yields all Person objects for which the expression evaluates to true.
We agree that the problem with my language is that it doesn't quite make explicit that those that don't match are dropped on the floor, but on the other hand it is less ugly than saying
the ‘where’ method yields all (and only) Person objects for which the expression evaluates to true
------------
As an aside; I’m blogging this both because I thought the content itself was interesting and because this is the kind of conversation that I find makes writing about and presenting about programming interesting. Not the splitting hairs part, but the effort to convey a concept both precisely and clearly at the same time.
Technorati
Silverlight offers you four ways to move an object from here to there
From/To Animation
- Linear Key Frame Animation
- Discrete Key Frame Animation
- Spline Key Frame Animation
From - To Animations
(From there to here, from here to there, funny things are everywhere)
From/To animation is the simplest to understand and thus to implement. You create a Storyboard and within that you create a DoubleAnimation object (you use a DoubleAnimation because the value you are going to change is of type Double).
One example of a value you might set would be the location (e.g., Canvas.Left), or you might set the Opacity of an object. In either case, you start at some value (From) and you end up at some other value (To) and you get from one value to the other over a period of time (the duration).
Here are the properties you'll set for your DoubleAnimation
- Name - the name of the Animation object so that you can refer to it from your code
- Duration - the period over which you want the animation to run - make the period short and the animation will run quickly.
- From - the starting value
- To - The ending value
- Storyboard.TargetName - the name of the object to animate
- Storyboard.TargetProperty - the property in the animated object whose value will change
As an example, you can create a simple square, and then move it from its initial position across the Silverlight control using a From/To Double animation by creating a Storyboard in the Canvas.Resource and then obtaining a reference to that Storyboard in the onload event handler in the code-behind and calling Begin on the storyboard.
Scene.xaml
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas.Resources>
<Storyboard x:Name="MoveSquareStoryBoard" >
<DoubleAnimation x:Name="Animate" Duration="00:00:02.00"
From = "100" To = "400"
Storyboard.TargetName="mySquare"
Storyboard.TargetProperty="(Canvas.Left)" />
</Storyboard>
</Canvas.Resources>
<Rectangle
Name ="mySquare"
Height="100"
Width="100"
Fill="Blue"
Stroke="Black"
StrokeThickness="3"
Canvas.Left="100"
Canvas.Top ="20"/>
</Canvas>
Scene.Xaml.js
if (!window.Animations)
window.Animations = {};
Animations.Scene = function()
{
}
Animations.Scene.prototype =
{
handleLoad: function(plugIn, userContext, rootElement)
{
var storyboard = plugIn.content.FindName("MoveSquareStoryBoard");
storyboard.Begin();
}
}
All of which is pretty straight forward. You can readily see how changing the target property from Canvas.Left to opacity will cause the square to stop sliding across the control and instead cause it to fade out (it would be good programming practice to change the name of the story board to reflect its new purpose; I've intentionally not done so here to show how little must change. I've not even added an opacity property to the square!),
<Canvas.Resources>
<Storyboard x:Name="MoveSquareStoryBoard" >
<DoubleAnimation x:Name="Animate" Duration="00:00:02.00"
From = "1" To = ".25"
Storyboard.TargetName="mySquare"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</Canvas.Resources>
<Rectangle
Name ="mySquare"
Height="100"
Width="100"
Fill="Blue"
Stroke="Black"
StrokeThickness="3"
Canvas.Left="100"
Canvas.Top ="20"
/>
Note that Opacity is measured from 1 (fully opaque) to 0 (fully transparent) and we move down to .25 (1/4 opaque) which explains why we use a double and not an integer for the animation. The result is a dramatic fading away of the square,
I will describe the key-frame Animations in another Tip of the Day.
I've received email that there has been a bit less responsiveness from Microsoft employees on some of the Silverlight Forums recently.
This is an impression, but to the extent it is true, it wouldn't be terribly surprising. Speaking only for myself I know that I've been swamped with getting ready both for MIX and for the release of Silverlight 2.0 Beta (we'd like to have a number of "How Do I" Videos ready to go, along with a lot of other material, so that folks can jump right into making use of the Beta.)
The folks who have code-path responsibility for Silverlight 2.0 Beta are, of course, totally immersed, as you might expect.
I think it is fair to guess that the forums will see a bit less participation by some Silverlight Developers during what remains of the first quarter, but that doesn't mean total abandonment; it just means that human nature being what it is, many folks will find the time slipping away, and there will be things they want to get to that they just won't find the time to do (like, for example, seeing family!)
To the extent that I too will be guilty of slow response time, I apologize in advance, because like many in Dev-Div, I truly believe that the forums are incredibly valuable; providing us with important feedback on what we need to clarify and fix, while offering a way to answer questions for the Developer community.
All I can do is thank you for your patience and promise you that Silverlight 2 Beta will make up for the wait!
Next