WPF tutorial: Image reflection effect in WPF with Expression Blend

Dear visitor: Please keep in mind that this post is originally from Vibor Cipan's personal blog, the name of which we eventually adopted as our company name together with its conveniently-named URL. We're keeping the posts on our official company blog for all the subscribers to Vibor's blog who have read and commented on his previous posts. Please be aware that this post represents Vibor's personal thinking few years ago and doesn't necessarily represent the opinions of the UX Passion as a company today. 

It is easy to create reflection effect in WPF using the Expression Blend – and in this tutorial I will show you how to achieve WPF / XAML reflection effect. Number of different controls can be used for this effect – images, controls like buttons or even video. In this tutorial, I will use simple image and create its reflection. Simple as that!

Image reflections are stylish effects often seen around – while there is a number of tutorials explaining how to create reflection (also called „mirror“ effect) in tools like Adobe Photoshop, there isn’t much resources when it comes to Expression Blend and WPF / XAML. So, that seemed as a reason good enough for creating this tutorial. Besides, I am using this effect every once in a while so it’s nice to have it documented here at UXPassion.com blog.

And here is little announcement: From now on, tutorials on UXPassion.com will be slightly different than earlier – they will be more structured and better organized – this was based on our user research, usability study and your suggestions so I hope you will benefit from these changes.

Before we begin

Make sure that you have Expression Blend 2 with SP 1 or Expression Blend 3 installed. This tutorial is targeting WPF (Windows Presentation Foundation).

Step by step

1. Start your Expression Blend and create a new WPF project. Under Objects and Timeline pane you will notice our root grid element called LayoutRoot. Select it and change its background colour to black. You can do that by selecting LayoutRoot and then by setting Background to black (under Properties pane).

2. Go to Assets Library (you can use shortcut: CTRL + .) and find StackPanel control. Select it and draw it on top of your LayoutRoot control. Size and dimensions are not really important for now.

3. Now, we need to add image to our project so we can use it to create our reflection effect. Click on Projects tab and then right-click on your project name. From the drop-down menu select Add Existing Item… New dialog will appear and there you can select image from your hard drive to add it into project.

Adding new image to project

4. Drag the image from Project tab and drop it on top of the StackPanel that you have previously added. While image is selected, click on Properties tab and on the top of it change the name of your image to imgOriginalImage. Giving a name is necessary step since we will be referencing this image later and using it during the process.

5. Right-click on image and from the drop-down menu select Group Into and then Border. This will create Border around our Image control.

Grouping Image into Border control

6. Now, select StackPanel (you can do it by clicking on it on your artboard or by clicking on it under Objects and Timeline pane). With StackPanel selected draw another Border control. You can go to Assets Library or locate it on Toolbox (Fourth icon from bottom, then click on little triangle and select StackPanel from drop-down menu). Try to make this new Border control approximately the same size like Image control you have added.

7. If everything was done right, you should have your Border positioned right bellow other Border containing Image control. Basically, under Objects and Timeline you should have something that looks like this:

Structure as seen under Objects and Timeline pane

8. Now comes the most important part – we need to create a VisualBrush. Basically, VisualBrush is a brush, pretty much like DrawingBrush but VisualBrush can paint the contents of any other visual element that derives from Visual in WPF. Good news is that Visual is the base class for all UI elements (Button, Image…) in WPF so you can use it and paint with it. How cool is that? Remember the second Border control we have added in step 6.? We are going to apply our VisualBrush to it (it is not necessary to be Border Rectangle is also okay…).

9. Let’s go into XAML. You can hit F11 in Blend 3 to switch between Design, XAML and Split view. As long as you get to XAML code so you can edit it – I don’t care which view you have selected.

10. Locate the following piece of XAML code:

<Grid x:Name="LayoutRoot" Background="#FF000000">
<StackPanel Margin="147,19,170,52">
<Border Margin="107.025,0,0,0" Height="125.318">
<Image x:Name="imgOriginalImage" Source="expression_blend_logo.png" Stretch="Fill"/>
</Border>
<Border Margin="107.025,0,0,0" Height="110" BorderBrush="#FF000000" />
</StackPanel>
</Grid>

11. Your code might differ a bit from this one – but idea is to locate piece of XAML describing our second Border control and in my case that is:

<Border Margin="107.025,0,0,0" Height="110" BorderBrush="#FF000000" />

12. We need to define our VisualBrush now. Change the line from Step 11. to this:

<Border Margin="107.025,0,0,0" Height="110" BorderBrush="#FF000000" >
<Border.Background>
<VisualBrush Visual="{Binding ElementName=imgOriginalImage}"/>
</Border.Background>
</Border>

13. As you can notice – we have used our imgOriginalImage as a VisualBrush for second Border. If you now take a look at your artboard, it should look somewhat like this:

VisualBrush applied to Border control

14. Top image is real image from Image control and bottom one is just VisualBrush applied to Border control. Now, to achieve reflection effect we need to change some properties. First of all, since we want to mimic the reflection we should mirror the bottom Border control. To do that, select the Border control, go to Properties pane, scroll down to the Transform section and locate the Scale property. Set the Y value to “-1”. It should look like this:

"Mirroring effect"

15. Now, let’s create one interesting effect – mimicking the fade-out for our reflected image. Select the second Border and under Brushes section create an OpacityMask with gradient. Set the transparency for the first gradient stop to 0% and for the second stop to 65%. Move a first stop a little bit so it looks like on the following picture:

Fading out in distance...

16. And final step is tweaking some properties so we can achieve pseudo 3D look. Make sure that you have Selection tool selected (shortcut: V). Select the Border and position your cursor above the bottom handler and you will see that cursor changes its appearance suggesting that you can skew your border. Skew it a bit and after that grab it by the same handler and pull it up (so it shrinks a bit). If you have done it correctly, your reflection should look like this:

Skewing and scaling for some pseudo 3D effects

17. Now hit F5 to start your project and enjoy!

More information

In this example we have used Image as our source object but we can use virtually any other UI control – Button, for example… Since we were mapping it’s visuals with VisualBrush, all the changes on Button (for example, changing the colour when we position our mouse cursor on top of it) will be reflected on its reflection in real-time. This effect looks very nice especially with videos.

Unfortunately, VisualBrush is missing from Silverlight 2 and from Silverlight 3 as well. But then again, luckily my MVP colleague from Hungary and guy who really cares about UX – András Velvárt (aka VBandi) has created really nice workaround. So, if you need VisualBrush in your Silverlight projects, go and check his blog post Discovering Silverlight 3 – Poor Man’s Visualbrush Behavior – I’m sure you will find it useful.

Comments (12)

  1. nice nice nice

  2. good and nice

  3. That last step with the skewing of the reflection, while a good thing to know, actually ruins the effect. Real reflections in flat surfaces (waxed hardwood floors, glass or waxed wood tables, etc.) don’t skew since they appear to be UNDER the surface, not ON it.

    Cast shadows (as opposed to drop shadows), on the other hand, would appear skewed since they appear ON the surface.

    One way to improve the effect would be to apply Blur to the reflection, but it would be best to have a gradient or ramp applied to the Blur Radius, if that’s possible. It should NOT be blurred much “close to the surface” where it’s bright, but should be blurred more as it gets further “into / under the surface” where it’s dimmer. This simulates the dispersion effect of the imperfectly smooth reflecting surface.

    I’m still new to Expression, so I don’t know if that’s possible (applying ramps to Blur Radius) short of making a custom Effect, but I do know how 3D modeling / rendering works, and for truly realistic reflections, that’s what’s needed.

  4. Very nice. Thank You

  5. Very nice explanation and simple to understand…. Keep up the good work…

    • hi,
      Very nice explanation
      can i use the image with the reflection effect as SplashScreen ???

      • You should be able. What specific scenario you have in mind? Maybe we can help you!

  6. hi,
    Very very nice explain

    • I am developing a webitse were i need to connect two branches using a free ip concept.so i need to know how would i use the ip to access the database.I am using WPF as frontend and SQL Server 2008 R2 as backend.

  7. Very good article, I was wondering how to create reflection effect for window ( application itself ) ?

    Thanks in advance.

    • Not sure that is really possible or supported with WPF!

  8. thanks…
    nice tutorial

Trackbacks

  1. Pingback: Vibor Cipan

  2. Pingback: Charlotte Web Design

  3. Pingback: Vibor Cipan

  4. Pingback: Vibor Cipan ✔

  5. Pingback: Vibor Cipan

  6. Pingback: Charlotte Web Design

  7. Pingback: Charlotte Web Design

  8. Pingback: MSExpression

  9. Pingback: SilverlightDC

  10. Pingback: Frank La Vigne

  11. Pingback: silverfighter

  12. Pingback: MSExpression

  13. Pingback: SilverlightDC

  14. Pingback: Frank La Vigne

  15. Pingback: silverfighter

  16. Pingback: MSExpression

  17. Pingback: SilverlightDC

  18. Pingback: Frank La Vigne

  19. Pingback: silverfighter

  20. Pingback: Taekyun Kim

  21. Pingback: Taekyun Kim

  22. Pingback: Taekyun Kim

  23. Pingback: Sara Silva

  24. Pingback: tweet anne