本稿では、WPFアプリでウィンドウ全体を透明にして表示する方法と、そのときに注意すべき事項を取り上げる。
対象:.NET 3.0以降
Windows用のプログラムの中には、四角形以外のウィンドウのものがある。四隅とも角が丸くなっていたり、タイトルバーとウィンドウ本体が離れていたり、ウィンドウ全体が円形だったりと、いろいろだ。キャラクターの形をした不定形のものさえある。これらのプログラムはどうやって作っているのだろうか? その方法はいくつかあるが、WPFではウィンドウを透明にして自前でウィンドウを描画するのが簡単だ。
そこで本稿では、WPFでウィンドウを透明/半透明にする方法を紹介しよう。なお、本稿のサンプルは「Windows desktop code samples:.NET Tips #1117」からダウンロードできる。
XAMLコードの<Window>タグに、属性を三つ追加するだけである。実に簡単だ(次のコード)。
<Window x:Class=……省略……
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
>
AllowsTransparency属性にTrueを指定すれば、Background属性に指定した色の透明度が有効になる。注意しなければならないのは、AllowsTransparency属性をTrueに設定するときには、同時にWindowStyle属性をNoneに設定する必要があることだ。すなわち、タイトルバーやウィンドウ枠を持ったままでウィンドウを透明/半透明にすることはできないのである。
上の方法でウィンドウを透明/半透明にすると、タイトルバーやウィンドウ枠がなくなってしまう。そのままではウィンドウを移動/リサイズできない。
ウィンドウを移動できるようにするには、ウィンドウ上でマウスのボタンが押されたときのイベントハンドラーでウィンドウをドラッグさせればよい。何だか難しそうに思えるかもしれないが、次のコードのように1行追加するだけである。
public MainWindow()
{
InitializeComponent();
// ウィンドウをマウスのドラッグで移動できるようにする
this.MouseLeftButtonDown += (sender, e) => { this.DragMove(); };
}
Public Sub New()
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' ウィンドウをマウスのドラッグで移動できるようにする
AddHandler Me.MouseLeftButtonDown, Sub(sender, e) Me.DragMove()
End Sub
ウィンドウをリサイズ可能にする方法はいくつかあるが、簡単なのはウィンドウの右下にグリップハンドルを出すやり方だ(次のコードと画像)。
<Window x:Class=……省略……
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
ResizeMode="CanResizeWithGrip"
>
ウィンドウやUIコントロールを透明/半透明にするには、色指定のアルファ値を変える方法と、Opacityプロパティを設定する方法がある。前述したウィンドウの透明化ではアルファ値を使い(色のTransparentはアルファ値が0である)、Opacityプロパティは使わなかった。その違いは何だろうか?
ひと言でいうなら、Opacityプロパティは子要素に伝播(でんぱ)するのである。例えば、親要素でOpacityプロパティに0.2(=かなり透明)をセットしたとする。そして、その子要素のOpacityプロパティに0.5(=半分の透明度)をセットしたとすると、実際のopacity(不透明度)は0.2に0.5を掛けた0.1(=ほとんど透明)になってしまうのだ。ウィンドウのOpacityプロパティを0(=透明)に設定すると、その中のUIコントロールも全て見えなくなってしまうのである。対して、アルファ値を背景色に設定した場合は、子要素に伝播しない。
その違いを実際に試してみよう(次のコード)。
<Window x:Class=……省略……
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
ResizeMode="CanResizeWithGrip"
>
<Grid>
<!--
このBorderコントロール(青色の四角形)には、Opacityプロパティを設定する。
Opacityプロパティの値は、下のSliderコントロールで調整できる
-->
<Border Grid.RowSpan="2" Background="#00a2e8"
Opacity="{Binding ElementName=slider1, Path=Value}" >
<!--
このEllipseコントロール(楕円形)には透明度の指定はしていない。
しかし、親要素にはOpacityプロパティが設定されているため、
親要素と同じ透明度になる
-->
<Ellipse Fill="SkyBlue" Width="40" Height="30" Margin="16,32"
HorizontalAlignment="Left" VerticalAlignment="Top" />
</Border>
<!-- このViewboxコントロールは、上のBorderコントロールの子要素ではない -->
<Viewbox >
<Image Source="penguin.png" Margin="16" Opacity="0.85" />
</Viewbox>
<!--
このBorderコントロールも、上のBorderコントロールの子要素ではない
このBorderコントロールには、Opacityプロパティは設定していないが、
BackgroundプロパティはTransparentにしてある(アルファ値は0)
-->
<Border Background="Transparent" BorderBrush="#400000ff" BorderThickness="4"
VerticalAlignment="Bottom"
>
<!-- 親要素の背景色がアルファ値0(=透明)であっても、子要素には影響しない -->
<Slider x:Name="slider1" Background="#80a0a0a0"
Margin="24,16" VerticalAlignment="Bottom"
Value="0.5" Maximum="1.0" ……省略……
/>
</Border>
<TextBlock Text=".NET TIPS #1117" ……省略……
/>
<!-- [×](閉じる)ボタン -->
<Button Click="closeButton_Click"
Content="X" ……省略……
/>
</Grid>
</Window>
このコードは、ウィンドウの背景色を透明にしてある。しかし、ウィンドウの子要素であり、ウィンドウの全面を覆う青色のBorderコントロール(System.Windows.Controls名前空間)には、ウィンドウの背景色は伝播しない。そのため、青色のBorderコントロールのOpacityプロパティを1.0にすると、不透明になる(次の画像)。
ウィンドウ下部のSliderコントロール(System.Windows.Controls名前空間)を動かすと、青色のBorderコントロールのOpacityプロパティが変わる。ちょうど半分にした状態が次の画像だ。
青色のBorderコントロールを完全に透明にすると、次の画像のようになる。
WPFではウィンドウを透明/半透明にするのは簡単だ。マウスで移動/リサイズできるようにするのも難しくない。Opacityプロパティと背景色のアルファ値の違いには注意しよう。
利用可能バージョン:.NET Framework 3.0以降
カテゴリ:WPF/XAML 処理対象:Windowコントロール
使用ライブラリ:Windowコントロール(System.Windows名前空間)
関連TIPS:[WPF、Silverlight 2]角を丸くして画像を表示するには?[XAML]
Copyright© Digital Advantage Corp. All Rights Reserved.