Flash to Silverlight

You do Flash and now you want to add Silverlight to your skillset?
You've come to the right place.

Graphics and Images

Silverlight supports both vector and raster graphics and the ability to interact with, group, transform and layout visuals. In this section, we will cover creating vector objects, brushes, colors and loading images.

Shapes 

Shapes in Silverlight are descendants of the FrameworkElement class, as a result shapes by default are interactive, able to be positioned, transformable and more. There is no need to wrap shapes in a container class like a Sprite or MovieClip in order to gain this functionality.

Ellipse shown in Expression Blend

Expression Blend (shown to the right) provides a designer with familiar tools to draw shapes with the mouse. Once selected, the Property Panel exposes the properties of the Ellipse which can be modified with the keyboard and various input controls.

To learn more about drawing in Expression Blend, check out the Drawing an emoticon tutorial.

XAML is the markup code used behind the scenes by Expression Blend to define the Ellipse. This provides a simple way to define object graphs that can be interpreted by both humans, like yourself, and tools like Visual Studio. XAML can always be viewed and edited manually in place of design tools.

<Canvas x:Name="myCanvas">
   <Ellipse Fill="#FF1DB100" Stroke="Black"
            Width="117" Height="117"
            Canvas.Left="70" Canvas.Top="191" />
</Canvas>

C# code can be used to procedurally defines the Ellipse using an object oriented style of syntax. An Ellipse defined this way will not be displayed during design-time. The Ellipse will only be rendered once the code is executed during run-time.

Canvas myCanvas = new Canvas();
Ellipse el = new Ellipse();
el.Fill = new SolidColorBrush(Color.FromArgb(255, 29, 177, 0);
el.Stroke = new SolidColorBrush(Colors.Black);
el.Width = 117;
el.Height = 117;
Canvas.SetLeft(el, 70);
Canvas.SetTop(el, 191);
myCanvas.Children.Add(el);

Colors 

In the code samples above, you see color values defined in three different ways.

First, in XAML (and in the Blend designer) the familiar hexadecimal format used for defining colors. The #AARRGGBB pattern is the same as ActionScript, but the format is more like color definitions in CSS. Other valid patterns include 6-digits, #RRGGBB, 4-digits, #ARGB, and 3-digit, #RGB.

<Ellipse Fill="#FF1DB100" Width="117" Height="117" />

Looking at the same value set in C# code you see that the color channels are represented as byte values (0 – 255). The resulting Color is then passed as a parameter to a new Solid Color Brush which will then act as the fill for the Ellipse. This is obscured in the XAML code by a type converter that creates a SolidColorBrush when a hexadecimal string is set for the Fill property.

el.Fill = new SolidColorBrush(Color.FromArgb(255, 29, 177, 0);
To learn how to add hexadecimal parsing functionality to C#, check out this tutorial on Converting Hexadecimals to Colors.

Brushes 

Brush types in Silverlight

Brushes in Silverlight are used to define visual properties of elements. This includes properties such as Fill, Stroke, Background, Foreground and more.

There are 5 different Brush types available:

Expression Blend provides rich editors to define brushes that can be very helpful due to the level of detail available when creating a Brush. Defining a LinearGradientBrush in Blend results in the following XAML, taking advantage of the compound syntax:

<Ellipse Width="117" Height="117">
   <Ellipse.Fill>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
         <GradientStop Color="#FFF9FF01" Offset="0" />
         <GradientStop Color="#FF1300A7" Offset="1" />
         <GradientStop Color="#FFFF9B01" Offset="0.268" />
         <GradientStop Color="#FF9D014A" Offset="0.748" />
         <GradientStop Color="#FFFF1500" Offset="0.516" />
      <LinearGradientBrush />
   <Ellipse.Fill/>
<Ellipse/>

Similar to a class in CSS, once a Brush is defined it can be saved as a Resource. This brush can then be reused in multiple places, providing an easy way to manage the updating of color schemes. To learn more about Brushes and Colors as Resources, read this tutorial called Create a brush or color resource.

Images 

Bitmap images can be loaded from embedded resources or external locations.

Like the [Embed] metadata tag, images can be added to a project and marked with a build action of Resource (the default in Blend). The image can then be referenced relatively (like HTML) or absolutely using the Component syntax. Absolute references are especially useful when working with multiple projects.

<Image Source="images/myImage.jpg" Width="300" Height="150" />

<Image Source="="/MyClassLibrary;Component/myImage.jpg" Width="300" Height="150" />

To display images from external locations both relative (to the location of the .XAP file) and absolute URLs work directly in XAML.

<Image Source="../images/myImage.jpg" Width="300" Height="150" />

<Image Source="="http://company.com/image/logo.jpg" Width="300" Height="150" />

The syntax for loading an external image in code is as follows:

img.Source = new BitmapImage(new Uri("http://mycompany.com/image/logo.jpg"));

Now that we have existing images loading, what about creating an image from scratch? The class most similar to BitmapData in Silverlight is the WriteableBitmap class. Currently the class is very useful when modifying existing images or printing and saving states of elements, but does not provide a strong drawing API. The code below shows pixel-level creation of a new bitmap:

int imgWidth = 300;
int imgHeight = 150;
byte a = 255, r, g, b;
WritableBitmap wb = new WritableBitmap(imgWidth, imgHeight);
for (int x = 0; x < imgWidth; x++)
{
   for (int y = 0; y < imgHeight; y++)
   {
      r = (byte)(x % 255);
      g = (byte)(y % 255);
      b = (byte)(x * y % 255);
      wb.Pixels[y * imgWidth + x] = (a << 24) | (r << 16) | (g << 8) | b;
   }
}
For a drawing and blitting library, check out the open source WritableBitmapEx project which provides many familiar methods like: DrawLine, DrawRectangle and more.
blog comments powered by Disqus