One of the WPF features that I miss in Silverlight is VisualBrush. Among other things, VisualBrush makes it easy to generate simulated reflections. To create reflections in Silverlight, we typically declare a copy of all the XAML we want to reflect, use a ScaleTransform to flip the copy upside-down, and apply an Opacity or OpacityMask to complete the illusion.
In Silverlight 3, you can use the new WriteableBitmap class to generate reflections without duplicating any XAML. In addition to letting you create bitmapped images from scratch, WriteableBitmap features a Render method that you can use to render all or part of the visual tree to a bitmap. To generate a reflection, you simply declare an Image in the scene and position it where you want the reflection to appear, and then use WriteableBitmap.Render to render everything you want reflected into the Image.
To demonstrate, I built a sample whose XAML is structured like this:
<Grid x:Name=”LayoutRoot” Background=”White”>
<StackPanel Orientation=”Vertical” VerticalAlignment=”Center”>
<!– XAML to be reflected –>
<Canvas x:Name=”Penguin” Width=”340″ Height=”322″>
<!– Reflection –>
<Image x:Name=”Reflection” Stretch=”None”>
<TranslateTransform Y=”-322″ />
<ScaleTransform ScaleY=”-1″ />
<LinearGradientBrush StartPoint=”0.0,0.0″ EndPoint=”0.0,1.0″>
<GradientStop Offset=”1.0″ Color=”#80000000″ />
<GradientStop Offset=”0.5″ Color=”#00000000″ />
Then I added the following statements to MainPage’s constructor:
WriteableBitmap bitmap = new WriteableBitmap ((int)Penguin.Width,
bitmap.Render(Penguin, new TranslateTransform());
Reflection.Source = bitmap;
And here’s the result:
I could have built the transforms for the reflected image into the code, but I reasoned that it’s better to apply the transforms declaratively so you can control where and how the reflection is positioned. If you wanted to reflect around the Y-axis instead of the X, for example, you could simply change ScaleY=”-1″ to ScaleX=”-1″ in the ScaleTransform.