Introduction
In WPF, one of the best know effects is the "reflection" effect, where a scene reflects itself dynamically. It's a very cool feature, because it's really easy to realize, and it allows to reflect images, but also videos or other User Interface scenes. The key to this is to use a VisualBrush. Silverlight is not exactly as powerful as WPF, and doesn't have VisualBrush, but it has ImageBrush and VideoBrush, both of them allowing cool media reflection effects (these brushes can also be used for other things!).
The key to making a reflection is placing a picture (or a video), and underneath it, an element (typically a Border). Then, you set the background of this element (Border.Background) to an ImageBrush (or a VideoBrush) pointing to the source that you want to reflect. To make the reflection look more lifelike, however, you want to skew it (because the surface you reflect is forming an angle with the reflecting element); also, you typically use an OpacityMask and make it look as if the reflection was progressively disappearing on a non-perfect surface. Life is not perfect, people, so a perfect reflection doesn't look lifelike.
The issue
However, when creating such an effect, I noticed an issue causing skewed elements with an OpacityMask to disappear completely. The following code shows the problem:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
Grid.RowDefinitions>
<Border Background="Red">
<Border.OpacityMask>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="1"/>
LinearGradientBrush>
Border.OpacityMask>
<Border.RenderTransform>
<SkewTransform AngleX="30" AngleY="0"/>
Border.RenderTransform>
Border>
Grid>
Skewed Border, OpacityMask, Silverlight
Skewed Border, OpacityMask, WPF
Notes
Here are a couple of notes about this:
-
I simplified the code as much as possible to display the issue. Obviously this is not a reflection anymore, but I stumbled upon the issue when creating a reflection.
-
The issue is visible in Blend and also if you run the application.
-
This issue is not limited to Borders. It also occurs if you replace the Border with a Grid, for example.
-
The issue also occurs with other Transforms. Replacing the SkewTransform with a RotateTransform will reproduce the issue.
-
If you don't transform the element, the issue does not occur.
-
If you remove the OpacityMask, the problem does not occur.
-
If you give a Width and a Height to the element, the problem does not occur.
-
The same code in WPF runs correctly.