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.
Creating Your Own Controls
Creating your own controls in Silverlight is fairly trivial. However, there are a couple of hurdles for Flex developers:
- You have to compile a project in Blend before you can see and use your controls in the rest of your app; and
- 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.
- Go Project > Add New Item;
- Choose UserControl, and name it “MyUserControl” (for example);
- Work on the control to your heart’s content;
- Compile the project;
- Go to your main control (MainPage.xaml), or any XAML page you want to use your control in;
- Select the Asset Library tool (looks like a double arrow »), and search for “MyUserControl”;
- Draw your control into the XAML page.
Fig 1: Finding your control in Blend’s Asset Library (once you’ve compiled the project)
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
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:
- Polylines (a collection of lines);
- Rectangles; and
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.
This then creates the following XAML:
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.
The "Data" property uses what is called Path Mini-Language - a kind of shorthand for describing a path.
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.
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.
Fig 6: The corresponding Blend transformation and projection panel.
Just like Flex, Silverlight supports various handy popup elements, including
- 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
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
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.
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
C# implementation (MainPage.xaml.cs)
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
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.
- Pixel Shaders: http://www.wintellect.com/CS/blogs/jprosise/archive/2009/03/25/silverlight-3-s-new-pixel-shaders.aspx
Just like Flash 10, Silverlight 3 leverages hardware acceleration in the client's GPU.
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).
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
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).
- Guide to animations: http://silverlight.net/quickstarts/animations.aspx
- MSDN: http://msdn.microsoft.com/en-us/library/cc189019(VS.95).aspx
- Custom (Advanced) animations: http://www.silverlightshow.net/items/Custom-Animations-in-Silverlight.aspx
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.
Then in the containing control we set the listener on the imported control:
Finally, we define the event listener - OnLoginAttempt().
Alternatively, we could added the event listener to the login control in the code-behind (like adding an event listener in AS3):
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.
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 are well supported in Blend, with GUI controls to Translate, Rotate, Skew and Scale. There is also Plane Projections to simulate 3D.
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.
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.