Where the Wild Things Are: an Adventure in Silverlight (Act II)

This is the second in a four part article on understanding Silverlight by a Flex developer.

Act II: Sailing across the ocean

In the first Act, we barely scratched the surface of Silverlight. Now, in Act II, we delve deeper, building on from what we’ve learnt. We’ll cover graphic primitives, effects, animations and events.

wildthings_sail.jpg
From Where the Wild Things Are by Maurice Sendak

Creating Your Own Controls

Creating your own controls in Silverlight is fairly trivial. However, there are a couple of hurdles for Flex developers:

  1. You have to compile a project in Blend before you can see and use your controls in the rest of your app; and
  2. Use the Asset Manager tool in Blend to import the namespace.

Both of these are significantly different from the Flex Builder paradigm we all know and love, and can be confusing as many Silverlight developers accept these simple Blend quirks.

Here is an example Blend workflow of creating and adding a user control to your application.

  1. Go Project > Add New Item;
  2. Choose UserControl, and name it “MyUserControl” (for example);
  3. Work on the control to your heart’s content;
  4. Compile the project;
  5. Go to your main control (MainPage.xaml), or any XAML page you want to use your control in;
  6. Select the Asset Library tool (looks like a double arrow »), and search for “MyUserControl”;
  7. Draw your control into the XAML page.

Fig 1: Finding your control in Blend’s Asset Library (once you’ve compiled the project)

act2-fig1.png

You’ll notice the imported control’s namespace has been added to the container’s XAML, as it would with Flex.

Ex 1: MainPage.xaml

[/code]

However, in Flex, we expect Eclipse to simply load in both the class and namespace as soon as we’ve created the control. It’s a fairly simple behaviour change in a developer’s workflow, but it’s easy to miss.

Graphics, Paths & Brushes

As mentioned in Act I, Silverlight has many graphic primitives it inherited from WPF. These include:

  • Lines;
  • Ellipses;
  • Polylines (a collection of lines);
  • Rectangles; and
  • Polygons.

The strokes and fills on these shapes are created and reused as Brushes. Brushes are objects that store values such as solid colour, gradients and fills. Until recently, these primitives gave Silverlight a strong advantage over Flex. Spark (the standard Flex 4 theme) uses similar primitives as well as fills and strokes that complement Flash Catalyst.

However Blend really has the upper hand with the visual tooling. If we take a look at this simple gradient filling of a rectangle, we see how seamless it is to construct.

Fig 2: Simple gradient fill in Blend. By drawing a rectangle, and selecting the Gradient tool, I get a fairly intuitive way of creating a gradient fill.

act2-fig2.png

This then creates the following XAML:

[/code]

Silverlight also handles Paths nicely in Blend. A path draws a line or a shape around certain points in space. In fact, all the shapes mentioned above are simply shortcuts to complex paths - as you’d expect. While Flex 4 has introduced paths in Spark, Silverlight has been using them since the inception of WPF. Unfortunately, Flash Catalyst is still a long way behind Blend on this one - creating a path in Blend is a simple as either getting out the pen or pencil, familiar tools for Photoshop and Illustrator users.

Fig 3: A simple treble clef.

act2-fig3.png
[/code]

The "Data" property uses what is called Path Mini-Language - a kind of shorthand for describing a path.

Transformations

Something we touched on in Act I was the use of render transformations. Each visual component - or UIElement - can be manipulated using any number of the transformations provided. These are fairly trivial to do in Blend, though, as always, result in a non-trivial amount of XAML. However, I understand that the Blend team are constantly working on reducing the markup with each iteration of the software.

Fig 4: Transform a rectangle by Scale, Skew, Rotation and Translation. Note: Blend shows you the original, pre-transformed rectangle superimposed in light blue on top.

act2-fig4.png
[/code]

Flash Catalyst is a little behind the 8-ball on this one. Beta 2 currently only has tooling for rotation transforms. The Flex 4 SDK has the capabilities; it’s just a matter of getting the tooling right.

Like Gumbo, Silverlight 3 implements perspective transformations, which mimic 3D transformations.

Fig 5: A simple ellipse, and a 3D projection of one, rotated 55 degrees around the X axis, and 55 degrees around the Y.

act2-fig5.png

Fig 6: The corresponding Blend transformation and projection panel.

act2-fig6.png
[/code]

Popups

Just like Flex, Silverlight supports various handy popup elements, including

  • ToolTips;
  • Popups; and
  • ChildWindows (modal dialog boxes).

ToolTips are about as simple as they are with Flex. You just use the ToolTipService class to add one in.

Fig 7: Basic ToolTip in Silverlight

act2-fig7.png
[/code]

The nice thing with Silverlight is how easy it is to extend these ToolTips with an inline component. This feels a little like setting the itemRenderer in Flex 3 using mx:Component.

Fig 8: Custom Inline ToolTip

act2-fig8.png
Is this a mouse? Not sure, but it seems to resemble one. [/code]

Popups in Silverlight are similar to ToolTips, but instead are opened programmatically, and allow focus. This means they can accept and respond to mouse events that occur within them. A Popup is essentially a primitive control that acts as a basis for any overlayed element you want to create - such as a custom dialog box or a calendar dropdown.

Fig 9: Simple Popup.

act2-fig9.png

XAML

C#

public partial class MainPage : UserControl { public MainPage() { // Required to initialize variables InitializeComponent(); } private void btnClick(object sender, System.Windows.RoutedEventArgs e) { myPopup.IsOpen = !myPopup.IsOpen; } private void btnClose_Click(object sender, System.Windows.RoutedEventArgs e) { myPopup.IsOpen = false; } } [/code]

If you’re looking for Popups more along the line of Flex, think Child Windows. These are basically movable dialog boxes, which are modal - meaning you cannot access any of the underlying content while they are open. Child Windows can only be created and toggled within the code-behind, you cannot simply add them to XAML.

Fig 10: A very basic ChildWindow

act2-fig10.png

XAML (MyChildWindow.xaml)

C# (MyChildWindow.xaml.cs)

public partial class MyChildWindow : ChildWindow { public MyChildWindow() { InitializeComponent(); } private void OKButton_Click(object sender, RoutedEventArgs e) { this.DialogResult = true; } private void CancelButton_Click(object sender, RoutedEventArgs e) { this.DialogResult = false; } } [/code]

C# implementation (MainPage.xaml.cs)

... private void btnDialog_Click(object sender, System.Windows.RoutedEventArgs e) { MyChildWindow child = new MyChildWindow(); child.Title = "Dialog King"; child.Show(); } ... [/code]

Effects

Until recently, effects have had a bad run in Silverlight. WPF had a few bitmap effects, but Silverlight was left empty handed. Microsoft have addressed this with the introduction of the Pixel Shader (Bender anyone? :) in Silverlight 3. Effects such as swirls, water ripples and such are handled by the mechanism. Silverlight 3 only comes with two effects natively - Blur and Drop Shadow - although they are trying to compensate this with online collections.

Fig 11: Applying a simple dropshadow effect

act2-fig11.png
[/code]

Unfortunately, Silverlight is limited to one effect per control. The current workaround involves wrapping the control in another control, such as a Border or some such, and applying another effect to the outer control.

For more information, checkout: http://silverlight.net/learn/learnvideo.aspx?video=187303

Similarly to Pixel Bender in Flash, creations of Pixel Shaders are another beast altogether. They are written in a language called the High Level Shader Language (HLSL) , reside in DirectX, and are useful to learn if you’re into writing games in XNA.

Just like Flash 10, Silverlight 3 leverages hardware acceleration in the client's GPU.

Animations

Animations are dealt with somewhat differently in Silverlight than Flex. In Silverlight, all animations are types of timelines (they derive from the Timeline class). And, as such, they rely on storyboards. A storyboard in Silverlight is essentially a timeline that contains animations and directs them to applicable objects - very much like the Flash authoring tool. These animations are effectively property setters, varying the value applied to an object over a period of time.

Silverlight supports both the interpolated animations that we’re accustomed to in Flex (like Move and Resize) as well as key frame animation models that we’re used to in Flash Pro.

Ex 1: Simple storyboard using DoubleAnimation (simply moves an ellipse 100 pixels to the right over 3 seconds with bounce easing).

[/code]

Note: Don’t be put off by the (Canvas.Left) property. This is an Attached Property that comes from the Ellipse’s container Canvas that determines how far from the Left margin of the Canvas the Ellipse should be. These are covered in depth in Act IV.

You’ll find that animating visually with Blend (by manipulating controls with timeline recording on) will use key frame animations, and the syntax gets fairly complex quite quickly.

Fig 12: The same animation using keyframes and Blend

act2-fig12.png

XAML

[/code]

Blend also handles these storyboards with the graphic primitives (such as paths and shapes) as well as the transitions between states. In Gumbo, we’ve seen a massive upgrade of the animation engine from Flex 3. Flex 4 allows the animations of all graphical objects now, rather than just the Flex componentry. However, at this stage, Flash Catalyst can only create animations as part of state transitions, whereas Blend can create storyboards without being attached to any state.

To me, the upgrading of the Flex 4 animation model is a great example of the symbiosis between the two platforms. Adobe have been able to learn from Microsoft’s advancements in Blend. In order to support modern tooling (i.e. Catalyst), they’ve had to upgrade their SDK. Flex and Silverlight are feeding off each other, both learning and adapting from the other, and we’re the lucky recipients - regardless of our choice of platform. 

One final point of note, are the animation types available in Silverlight. Above we simply discuss Double animations, which essentially are property setters for numeric values. Silverlight also supports setting colour, point and object values. Meaning you can animate the colour (as in Gumbo), point geometry and even object values (typically brushes).

Useful Links

Further Reading

Events

Just like Java, Javascript and AS3, .NET has event handling. To deal with the RIA model however, it needed something more. WPF introduced Routed Events. There are three types - bubbling, direct and tunnelling. The former is analogous to bubbled events in Flex, the latter is the opposite - events start in some parent and tunnel through the children (allowing a parent to intercept an event before it reaches the child). Silverlight currently only supports bubbling events. Unfortunately however, you cannot currently create your own bubbling events.

As for normal component events, the syntax and terminology is slightly different, but essentially both Silverlight and Flex have similar event definition, calling and responding mechanisms.

Ex 2: Custom event in Silverlight (C#).
This is simply a login control, with two text inputs and a submit button.

Login.xaml

Login.xaml.cs

namespace JustinJMoses.Silverlight.Examples.SL_Events { //this is a delegate - it depicts the type of a method that can respond to events public delegate void LoginEventHandler(Object sender, LoginEventArgs e); public partial class Login : UserControl { //this is the event, that will excete public event LoginEventHandler LoginAttempt; public Login() { // Required to initialize variables InitializeComponent(); } //When the submit button is called private void OnSubmit(object sender, System.Windows.RoutedEventArgs e) { //dispatch the event LoginAttempt(this, new LoginEventArgs(true)); } } //this class manages the custom event arguments public class LoginEventArgs : EventArgs { public readonly bool WasSuccessful; public LoginEventArgs(bool wasSuccessful) { this.WasSuccessful = wasSuccessful; } } } [/code]

Then in the containing control we set the listener on the imported control:

MainPage.xaml

[/code]

Finally, we define the event listener - OnLoginAttempt().

MainPage.xaml.cs

... private void OnLoginAttempt(object sender, LoginEventArgs e) { // TODO: Add event handler implementation here. } ... [/code]

Alternatively, we could added the event listener to the login control in the code-behind (like adding an event listener in AS3):

MainPage.xaml.cs

... loginControl.LoginAttempt += new LoginEventHandler(OnLoginAttempt); ... [/code]

Unlike Flex and HTML, Silverlight won’t allow code inside its markup. This means that the following XAML: <Button Click=”myPopup.IsOpen = false” /> is not allowed.

Useful Links

Journal Notes

We’ve covered a lot of designing of the View in this Act.

  • Control creation workflow
    Creating user controls is trivial, but with pitfalls for the unsuspecting Flex developer. Ensure you compile the project first and import controls using the Asset Library in Blend.
  • Graphic Primitives
    Silverlight supports all the important graphic primitives, such as Lines, Ellipses and Polygons - all of which rely on Paths. The primitives support the Stroke and Fill properties, which in turn allow Solid, Gradient and Tile Brushes. As with Flex 4, primitives can be manipulated with effects, transformations and animations.
  • Transformations
    Transformations are well supported in Blend, with GUI controls to Translate, Rotate, Skew and Scale. There is also Plane Projections to simulate 3D. 
  • Popups
    Silverlight supports ToolTips, Popups and ChildWindows. The former is similar to ToolTips in Flex but easier to customise. Popups are generic controls that are layered over the viewport and can be toggled on and off. ChildWindows are analogous to modal Flex Popups. 
  • Effects are getting there
    Silverlight 3 has stepped up effects with the Pixel Shader and is slowly coming to par with Flash.
  • Strong animation support in Blend
    Blend may not be perfect, but it does the difficult task of converting your custom timeline based animations to code.  
  • Events
    Bubbled events are supported in Silverlight, but you cannot currently create your own. Creating control-level events however, is trivial.

Keep your eye out for the third Act, where we get down and dirty with styling, templating and state management.

About this Entry

This page contains a single entry by Justin J. Moses published on March 16, 2010 8:00 AM.

6 Lessons I Learned About Customer Service from T Mobile was the previous entry in this blog.

InsideRIA FITC Conference Pass Giveaway - Now Closed is the next entry in this blog.

Find content using the provided navigation or look in the archives to find all content.

Authors

Archives

This content archive is licensed under a Creative Commons License.