GUIの表示が地面に写り込んだようなデザインを最近良く見かける。このような効果をウェットフロアというそうだ。
今回は、以下のようなウェットフロア効果がかかったGUIをxamlで実装していくことを考える。

まずは、効果が何もかかっていない状態のxamlを示す。
MainWindow.xaml
<Window x:Class="WpfWetFloorLesson.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<!-- 適当なGUI -->
<Border BorderThickness="8" BorderBrush="AliceBlue" Background="AliceBlue" Name="inputArea" Height="72">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="4"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Background="Azure">Name</Label>
<Label Background="Beige" Grid.Row="2">Address</Label>
<TextBox Grid.Column="1"></TextBox>
<TextBox Grid.Row="2" Grid.Column="1"></TextBox>
</Grid>
</Border>
</StackPanel>
</Window>
このxamlを実行すると以下のように表示される。

このGUIに対してウェットフロア効果をかけていく。
まずは、GUIの真下に、上のイメージと全く同じものが表示されるようにVisualBrushを適用したRectangleを配置する。
そのxamlは以下のようになる。
<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=inputArea}" />
</Rectangle.Fill>
</Rectangle>
そして、ここまでの実行結果は以下のようになる。

次に、写り込み効果として追加したRectangleを180度回転させる。
<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=inputArea}" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<!-- 180度回転させる -->
<ScaleTransform ScaleY="-1" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>

このままだと、元のGUIに重なってしまうので、Rectangleを自分の高さの分だけ下に移動する必要がある。
<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=inputArea}" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<!-- 180度回転させる -->
<ScaleTransform ScaleY="-1" />
<!-- 自分の高さの分だけ下に移動する -->
<TranslateTransform Y="{Binding ElementName=inputArea,Path=Height}" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>

最後に、仕上げとしてぼかしを入れる。
<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=inputArea}" />
</Rectangle.Fill>
<!-- ぼかしを入れる -->
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#AA000000" Offset="1" />
<GradientStop Color="#00000000" Offset="0" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.RenderTransform>
<TransformGroup>
<!-- 180度回転させる -->
<ScaleTransform ScaleY="-1" />
<!-- 自分の高さの分だけ下に移動する -->
<TranslateTransform Y="{Binding ElementName=inputArea,Path=Height}" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>

こうして、ウェットフロア効果を掛けることが出来た。
最後に、これまでのxaml全体を示す。
MainWindow.xaml
<Window x:Class="WpfWetFloorLesson.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<!-- 適当なGUI -->
<Border BorderThickness="8" BorderBrush="AliceBlue" Background="AliceBlue" Name="inputArea" Height="72">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="4"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Background="Azure">Name</Label>
<Label Background="Beige" Grid.Row="2">Address</Label>
<TextBox Grid.Column="1"></TextBox>
<TextBox Grid.Row="2" Grid.Column="1"></TextBox>
</Grid>
</Border>
<!-- ウェットフロア効果 -->
<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=inputArea}" />
</Rectangle.Fill>
<!-- ぼかしを入れる -->
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#AA000000" Offset="1" />
<GradientStop Color="#00000000" Offset="0" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.RenderTransform>
<TransformGroup>
<!-- 180度回転させる -->
<ScaleTransform ScaleY="-1" />
<!-- 自分の高さの分だけ下に移動する -->
<TranslateTransform Y="{Binding ElementName=inputArea,Path=Height}" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
</Window>
このように、WPFではxamlを書いていくだけでリッチな効果を得ることができる。
WPFの表現力の可能性を感じさせる一例である。
参考サイト:
http://msdn.microsoft.com/ja-jp/magazine/cc163455.aspx