C#

【WPF】ウィンドウの一部背景を透明にする方法

ブログでアプリケーションの実行画面の説明をする時、GIF アニメーションをよく使います。

パソコンの画面を撮影して GIF アニメーションを簡単に保存できる無料ツールの「ScreenToGif」という神アプリをよく利用しています。

このアプリの画面中央部分は透明になっていて、背面が見えるようになっています。この透明な部分が録画されるという仕組みになっています。画面のサイズも自由自在に調整可能で、好きなサイズで録画ができるので使い勝手が良く重宝しています。

このアプリのように「Windowの背景の一部を透明にするのってどうやってするんだろう?」という好奇心から、ScreenToGif と同じような画面構成のアプリを WPF で作成してみました。

この記事では、ウィンドウの特定の部分の背景を透過させる方法について記述しています。ぜひ参考にしてみて下さい。

ウィンドウの一部背景を透明にする

まず、WPF には特定の部分だけを透過するプロパティはありませんが、ウィンドウの全体を透明にするプロパティは存在します。

そこで、透明にしたいウィンドウの背景以外は何かしら色が付いた Grid などで隙間を埋めるという方法で実現しようと思います。

イメージとして次のような感じです。

色付きの Grid はウィンドウの左端・右端・下端にそれぞれ配置します。

背景を透明にする

WPF で Window の背景を透過するには3つのプロパティを次のように設定をします。

Background プロパティを”Transparent”にする。
WindowStyle プロパティを”None”にする。
AllowsTransparency プロパティを”True”にする。

プロパティの説明は次の通りです。こちらの公式サイトを参照しています。

プロパティ説明
Backgroundコントロールの背景を表すブラシを取得または設定します。
WindowStyleウィンドウの枠線のスタイルを取得または設定します。
AllowsTransparency ウィンドウのクライアント領域が透過性をサポートするかどうかを示す値を取得または設定します。

Window の背景を透明にするには、AllowsTransparency プロパティを”True”にして、透明を許可する設定に変更する必要があります。

また、AllowsTransparency プロパティを”True”にする場合は、WindowStyle プロパティを”None”にしなければなりません。

WindowStyle プロパティを”None”にするということは、タイトルバーや枠線、最大化・最小化ボタン、閉じるボタンが存在しないウィンドウになります。つまりタイトルバーや枠線、ボタンを自作してウィンドウへ配置する必要があります。

ということで先ほど示したイメージを修正します。

色付きの Grid を上端に配置し、ラベル(タイトル)とボタンを追加しました。それとウィンドウの周りを囲む枠線も追加しました。

タイトルバーや枠線、ボタンを配置する

Window の枠線を Border コントロールで作ります。

続いて Border の子要素として Grid を配置して、Label コントロールと Button コントロールをいい感じに調整してタイトルバーを作ります。

<Window
    x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WindowTransparent"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="450"
    Height="350"
    AllowsTransparency="True"
    Background="Transparent"
    WindowStyle="None"
    mc:Ignorable="d">
    <Border BorderBrush="#c6c6c6" BorderThickness="2">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="32" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid Background="#ffffff">
                <Label
                    Margin="5,0,0,0"
                    Content="Sample Window"
                    FontSize="14" />
                <Button
                    Name="btnClose"
                    Width="32"
                    Margin="0,0,5,0"
                    Padding="0,-5,0,0"
                    HorizontalAlignment="Right"
                    Background="Transparent"
                    BorderThickness="0"
                    Content="×"
                    FontSize="26" />
            </Grid>
        </Grid>
    </Border>
</Window>

window.xaml.cs のコンストラクタで、左クリックのイベントハンドラに DragMove 関数を記述します。これでドラッグ&ドロップした時に Window を動かすことができるようになります。

また、ボタンをクリックした時に Window が閉じるように、ボタンのクリックイベントに Close 関数を記述します。

public MainWindow()
{
    InitializeComponent();

    // ドラッグ&ドロップで移動する処理
    MouseLeftButtonDown += (s, e) => { DragMove(); };

    // ウィンドウを閉じる処理
    btnClose.Click += (s, e) => { Close(); };
}

この状態で実行すると次の画面になります。

ウィンドウの背景が透明になっていることが分かるように、アプリの背面にメモ帳を配置しています。それっぽい画面にはなっていますが、更に仕上げていきます。

枠を配置する

今のままだとウィンドウの枠線が細く、アプリの境界が分かりづらいので左右と下に枠(Grid)を配置します。

HorizontalAlignment プロパティ、Width プロパティなどで配置する位置や幅を調整します。

<Window
    x:Class="WindowTransparent.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WindowTransparent"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="450"
    Height="350"
    AllowsTransparency="True"
    Background="Transparent"
    WindowStyle="None"
    mc:Ignorable="d">
    <Border BorderBrush="#c6c6c6" BorderThickness="2">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="32" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid Background="#ffffff">
                <Label
                    Margin="5,0,0,0"
                    Content="Sample Window"
                    FontSize="14" />
                <Button
                    Name="btnClose"
                    Width="32"
                    Margin="0,0,5,0"
                    Padding="0,-5,0,0"
                    HorizontalAlignment="Right"
                    Background="Transparent"
                    BorderThickness="0"
                    Content="×"
                    FontSize="26" />
            </Grid>
            <Grid Grid.Row="1">
                <Border
                    Margin="5,0,5,32"
                    BorderBrush="#c6c6c6"
                    BorderThickness="1" />
                <Grid
                    Width="5"
                    HorizontalAlignment="Left"
                    Background="#ffffff" />
                <Grid
                    Width="5"
                    HorizontalAlignment="Right"
                    Background="#ffffff" />
                <Grid
                    Height="32"
                    VerticalAlignment="Bottom"
                    Background="#ffffff">
                    <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
                        <Button
                            Width="50"
                            Background="Transparent"
                            BorderThickness="0"
                            Content="設定" />
                        <Separator
                            Margin="5,2,5,2"
                            BorderBrush="#c6c6c6"
                            BorderThickness="0.5"
                            Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
                        <Button
                            Width="50"
                            Margin="0,0,5,0"
                            Background="Transparent"
                            BorderThickness="0"
                            Content="録画" />
                    </StackPanel>
                </Grid>
            </Grid>
        </Grid>
    </Border>
</Window>

ここまで記述して実行すると次の画面になります。

最初にイメージしていた状態にまでUI画面を仕上げることが出来ました。

リサイズを設定する

アプリのサイズを変更できるように、window.xaml で ResizaMode プロパティの設定を行います。ResizaMode プロパティは”CanResizeWithGrip”を指定すれば、グリップを使ったリサイズが可能になります。

ResizeMode="CanResizeWithGrip"

最終的には次の画面になります。

アプリの画面右下にサイズを変更するグリップが表示されます。このグリップをドラッグ&ドロップすることで任意のサイズに調整することができます。

まとめ

WPFではウィンドウの特定の部分の背景を透明にする為に、3つのプロパティの設定を行い、背景を透明にしない箇所には色付きのGridを配置しました。

Background プロパティを”Transparent”にする。
WindowStyle プロパティを”None”にする。
AllowsTransparency プロパティを”True”にする。

ウィンドウ全体を透過した時に、タイトルバーや枠線などが消えてしまうデメリットはあるものの、やりたいことは実現することができました。

今回作成したアプリにスクリーンショット機能を追加した記事を作成しました。スクショした画面を画像ファイルとして自動で保存することもできるので、興味がある方は確認してみて下さい。

【WPF】画面をスクリーンショット(キャプチャ)して保存するアプリを作成WPFでパソコンの画面をスクリーンショットした画像を自動で保存するアプリを作りました。画面のスクリーンショットと保存はSystem.DrawingのBitmapクラスを使えば簡単に実装ができます。System.Drawingを.NET Coreの環境で使う場合はNuGetからSystem.Drawing.Commonを別途インストールしましょう。...

以上、最後まで読んで頂きありがとうございました。

プログラミングを学習したいなら…

プログラミングスキルを身に付けるなら、プログラミングを効率良く学べる
プログラミングスクール」がオススメです。

特にこんな方にオススメ!!
これからエンジニアを目指したい
プログラミングの専門性を高めたい
プログラミングを学んで副業をしたい
エンジニアに転職して年収をアップさせたい

プログラミングを触ったことがない未経験からでも、プログラミングスクールで学習すれば、エンジニアへ就職・転職することも可能です。

あなたの「行動力」と「やる気」で、あなたの人生を大きく変えるチャンスになることでしょう。

プログラミングスクールに興味がある方は是非チェックしてみてください。

> プログラミングを学ぶ <

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA