WPF で Zune のようなウィンドウを作る

Visual Studio 2012 にも慣れてきた今日この頃。

Windows Azure や Windows Store apps の開発が流行る中、デスクトップ WPF アプリケーション開発を貫く私かっこいい!かっこわるい。仕事だから仕方ない。

ということで、デスクトップの WPF ネタを 1 つ。

最近、Zune Software にはじまり、MetroTwit や GitHub for Windows、そして Visual Studio 2012 など、従来の Windows のウィンドウっぽくないかっこいいウィンドウのアプリケーションがいくつも出ています (上: Zune Software / 下: Visual Studio 2012)。


(こういうウィンドウの総称ってあるんでしょうか? 「Metro ライク」などという表記は見かけますが、正式名称っぽいものを私は聞いたことがない… 誰か教えてください。。。)

で、自分のアプリケーションもこんな感じにできたらかっこいいよね、なんて思いまして。作ってみました。

Zune ライクなウィンドウ

Zune ライクと言っていますが、Zune のウィンドウについているでっかい影は見なかったことにして、とりあえずウィンドウ本体の外観のみを対象とします。Zune というよりは MetroTwit や GitHub for Windows に近いかも。

この Zune ライクなウィンドウの実装は比較的簡単、WindowChrome クラスを使えばいいのです。
WindowChrome クラス (System.Windows.Shell)

使い方の前に一点だけ注意を。WindowChrome クラスが .NET Framework 標準ライブラリに入ったのは、v4.5 からです。v4.0 までのプロジェクトで WindowChrome クラスを使いたい場合、Microsoft.Windows.Shell.dll という別のアセンブリが必要になります。
WindowChrome クラス (Microsoft.Windows.Shell)

このアセンブリは、WPF Shell Integration Library をダウンロードして入手しましょう。
ちなみに、Microsoft Ribbon for WPF などにも同梱されているので、そちらをインストール済みの方は既にアセンブリを参照できるようになっていると思います。
WPF Shell Integration Library

もちろん、.NET Framework 4.5 プロジェクトの場合は、これらのアセンブリを入手したり参照を追加したりする必要はありません。

さて使い方ですが、マークアップで Window の中に仕込むだけ。

.NET Framework 4.0 以前の場合は以下になります (Microsoft.Windows.Shell.dll への参照を追加している前提です)。

これで、以下のような真っ黒の背景 (+ グレーの縁つき) のウィンドウが出来上がります。

上記の例では、CaptionHeight プロパティと ResizeBorderThickness にシステム設定値 (SystemParameters クラスの値) を使用しましたが、もちろん自分で好きに設定して構いません。ただし、CaptionHeight プロパティ (タイトル バーの高さ) を 0 にするとウィンドウの上部を掴んでドラッグによるウィンドウ移動はできなくなりますし、ResizeBorderThickness プロパティを 0 にするとウィンドウの端を掴んでリサイズすることができなくなります。

また、GlassFrameThickness プロパティは Aero Glass 効果つきのウィンドウで非クライアント領域を広げる (= ガラス効果部分を広げる) ものです。ちなみに四辺すべてに -1 を設定すると、ウィンドウ全体がガラス効果で透明になったウィンドウができるはずですので、Windows 7 を使っていて興味のある方は試してみてください (手元に Windows 7 がないので、私は試しておりません…)。

キャプション バーを作る

このままではダメなので、最小化、最大化、閉じるボタンなど最低限のボタンを乗せてみます。

横方向の StackPanel にボタンを 4 つ並べています。上から 最小化、最大化、元のサイズに戻す、閉じる のボタンです。実行するとこんな感じに。

ボタンの Content に 0 とか 1 とかを設定しているのは、ボタンの FontFamily に Marlett というフォントを指定しているためです。もちろん Path や画像を使って実装しても構いませんが、手っ取り早くシステムのボタンを実装したいときは、このフォントを使うとよいでしょう。

参考までに、Marlett フォントと割り当てられている英数字の一覧を。

ボタンのスタイルのサンプルも載せておきます。長いので後半は読み飛ばして頂いて構いません。重要なのはハイライトした部分 (4 行目、10 行目) です。Window のリソースに張り付ければ、そのまま動くはず。

4 行目は先ほどの Marlett フォントの指定ですが、10 行目は特に重要です。
通常、ウィンドウの非クライアント領域 (キャプション バーやウィンドウのふちの部分) に要素を置いても、ヒット テストが発生しません。今回の例では、ウィンドウの上端から WindowChrome.CaptionHeight プロパティで指定した高さの領域は非クライアント領域であり、その領域に置かれたボタンに対してヒット テストが発生しないので、押すことができません。

WindowChrome.IsHitTestVisibleInChrome 添付プロパティで true を指定すると、その要素は非クライアント領域上でもヒット テストが発生するようになります。ですので、最小化、最大化、閉じるボタンなど、キャプション バー上に配置し、ユーザーのクリック操作などに反応する必要がある要素では、IsHitTestVisibleInChrome 添付プロパティを true に設定しておきましょう。

これらのボタンのクリック処理については簡単なので書きませんが、ひとつだけ。
Microsoft.Windows.Shell.dll から WindowChrome クラスが .NET Framework 標準ライブラリ入りしたのと同時に、SystemCommands クラスも標準ライブラリに入っています。
SystemCommands クラス (System.Windows)

.NET 4.0 以前の場合はこちら。
SystemCommands クラス (Microsoft.Windows.Shell)

ウィンドウの最小化、最大化、復元、閉じるなどの各操作の RoutedCommand と、ウィンドウを操作する静的メソッドが提供されていますので、ご参考までに。

ウィンドウ全体でドラッグ可能に

GitHub for Windows だと、ウィンドウのどこ掴んでもドラッグできますよね。簡単です。ウィンドウの MouseLeftButtonDown イベントで DragMove メソッドを呼ぶだけ。

こうしてしまえば、キャプション バー以外でもドラッグできるようになるので、WindowChrome.CaptionHeight プロパティは 0 にしても問題ないかも。

まとめ

ということで、Zune ライクなウィンドウの作り方でした。WindowChrome クラスを使ってウィンドウの外観を自由に作れます。非クライアント領域の部分に要素を配置する際は、IsHitTestVisibleInChrome 添付プロパティの設定をお忘れなきよう。

ぶっちゃけてしまうと Window.WindowStyle を None にして Window.AllowsTransparency を true にすれば、WindowChrome クラスを使わなくても似たような UI を作れるはずです。ですがですが、WindowStyle=”None” にすると、ウィンドウを最大化したときにタスク バーすら覆っちゃったりとか、ウィンドウの端を掴んでリサイズする部分を自作しなきゃいけなかったりとか、いろいろ面倒なことになったりならなかったり。特殊なウィンドウを除いて、ふつうのアプリケーションのメイン ウィンドウで WindowStyle=”None” にするのってあまりやりたくないんですよね… あくまで個人的にですが。

また、次は Visual Studio 2012 のような光るウィンドウを作った記録を投稿する予定で、今書いてるところです。
今回のサンプルで作ったコードは、この続きの記事のサンプルとまとめて GitHub か何かに上げるつもりですので、少々お待ちください。。。


4 thoughts on “WPF で Zune のようなウィンドウを作る

  1. Pingback: WPF で Visual Studio 2012 のような光るウィンドウを作る | grabacr.net

  2. Pingback: Acer のスレート PC 「ICONIA W700」 買ってみた! | grabacr.net

  3. Pingback: Visual Studio 2012 のような光るウィンドウを作る (再)、そして WPF での高 DPI 対応 | grabacr.nét

  4. Pingback: ItemsControl 攻略 ~ 外観のカスタマイズ | grabacr.nét

コメントを残す

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