やる気駆動型エンジニアの備忘録

WPF(XAML+C#)の話題を中心に.NET/Android/CI やたまに趣味に関するブログです

WindowChromeの問題点

前回WindowChromeで独自ウィンドウを作成しましたが、今回はWindowChromeを使用したうえでの問題点を見ていきます。

 

1.最大化した時にデスクトップのクライアント領域を超える。

 

通常、ウィンドウを最大化した場合、デスクトップのクライアント領域を超えてウィンドウが表示されることはありません。

しかし、WindowChromeを適応した独自ウィンドウは下図のように最大化した際に非クライアント領域にまでウィンドウが侵入してきます。

 

f:id:iyemon018:20150919170506p:plain

↑タスクバーに若干かぶっているのがわかるでしょうか?

f:id:iyemon018:20150919171006p:plain

↑通常のウィンドウはこんな感じ

 

この現象が発生する原因は、WindowChrome.GlassFrameThicknessが設定されているためです。

このGlassFrameThicknessとは何か?

Windows7のAeroテーマを使用しているとウィンドウの外枠がグラスのような外観になるあれです。

更に詳しい情報はこの辺りを見てください。

 参考:WindowChrome クラス

 

単純にこの値を"0"に設定することでタスクバーへの侵入を防ぎます。

f:id:iyemon018:20150919173607p:plain

↑できました~

でもちょっと待って下さい。

よく見るとタイトルの文字がクライアント領域ギリギリの位置に設定されています。

これはウィンドウの状態変化イベントからContentのMarginに余裕を持たせて対応できます。

 

<MainWindow.xaml.cs>

private void window_StateChanged(object sender, EventArgs e)
{
    switch (WindowState)
    {
        case WindowState.Maximized:
            LayoutRoot.Margin = new Thickness(9);
            break;
        default:
            LayoutRoot.Margin = new Thickness(0);
            break;
    }
}

 

さて、これでひとまず見た目は対応できました。

 

2.SizeToContent=WidthAndHeight にすると現れる謎の黒い領域

 

SizeToContentはContentのサイズによって動的にウィンドウサイズを変更するためのプロパティです。

MessageBoxを独自に作成したい場合や、画面の表示項目によってウィンドウサイズを変えた場合に使用します。

WindowCheomeを使用してSizeToContentを設定すると謎の黒い領域が出現します。

この現象は説明だけではわかりにくいですから下図を見てください。

f:id:iyemon018:20150919180024p:plain

おわかり頂けただろうか?

これはどうもWindowChromeのバグのようで、以下でも対策が議論されています。

Gradient style issue when SizeToContent=HeightAndWidth with CustomChrome

stackoverflow.com

ただ、もうちょいお手軽に対応できる方法もあります。

WindowのAllowsTransparencyプロパティをTrueにすることです。

f:id:iyemon018:20150919180806p:plain

↑これでひとまず対応できました。

この動作から察するに、おそらく配下にデフォルトのWindowフレームがいるため、サイズ計算に失敗しているのではないでしょうか?

AllowsTransparencyを"True"に設定することで、その計算が不要になったと。

 

サンプルはこちら

github.com