2014年7月12日土曜日

WindowChromeでWPFのRibbonWindowの枠を完璧にする

前回の記事の続きになります。
もはや永遠のテーマとも言えた.NET4.5のRibbonWindowの枠の話です。
なんとか

解 決 出 来 ま し た \(^o^)/

(´◔౪◔)۶ヨッシャ!

さて、それでは完成図をご覧いただきましょう。


前回の記事で1つ目の問題になっていた、ウィンドウの外枠とクライアント領域の間の境界線がちゃんと引けています。実はこれ、他愛のないことだったんですけどね。
ですが、何度も苦労させてきた最大化するとタイトルバーが黒くなる問題、これもバッチリ解決出来ました。


バッチリです。

とりあえず、例によってXAMLを載せます。

<RibbonWindow x:Class="WindowChromeTest.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:v="clr-namespace:WindowChromeTest.Views"
        xmlns:vm="clr-namespace:WindowChromeTest.ViewModels"
        Title="MainWindow" Height="350" Width="525" BorderThickness="5" >

    <WindowChrome.WindowChrome>
        <WindowChrome GlassFrameThickness="7,29,7,7" NonClientFrameEdges="Bottom" ResizeBorderThickness="7" />
    </WindowChrome.WindowChrome>
    
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    
    <i:Interaction.Triggers>
        <!--WindowのContentRenderedイベントのタイミングでViewModelのInitializeメソッドが呼ばれます-->
        <i:EventTrigger EventName="ContentRendered">
            <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
        </i:EventTrigger>

        <!--Windowが閉じたタイミングでViewModelのDisposeメソッドが呼ばれます-->
        <i:EventTrigger EventName="Closed">
            <l:DataContextDisposeAction/>
        </i:EventTrigger>

    </i:Interaction.Triggers>

    <DockPanel>
        <Border BorderBrush="Black" />
        <Ribbon DockPanel.Dock="Top" BorderThickness="1" >    
            <Ribbon.QuickAccessToolBar>
                <RibbonQuickAccessToolBar>
                    <RibbonButton SmallImageSource="/WindowChromeTest;component/Images/Configuration.ico" />
                    <RibbonButton SmallImageSource="/WindowChromeTest;component/Images/Information.ico" />
                </RibbonQuickAccessToolBar>
            </Ribbon.QuickAccessToolBar>
            <RibbonTab Header="Home">
                <RibbonGroup Header="Group">
                    <RibbonButton LargeImageSource="/WindowChromeTest;component/Images/Configuration.ico" Label="Config" />
                </RibbonGroup>
            </RibbonTab>
        </Ribbon>
        <TextBox Text="これはテキストボックスです" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" />
    </DockPanel>
</RibbonWindow>

まず、第1の問題点の境界線の話ですが、これは、グラスフレームの範囲を具体的な数字で指定することで解決しています。
要するに、 全体をグラスフレームにしちゃうと当然その中に描いたものとグラスフレームの境界線は引かれなくなってしまいますが、ちゃんとクライアント領域の外側だけをグラスフレームにすると、そことクライアント領域の中の間の境界線が引かれるということです。

第2の問題点の最大化ですが、これはなぜ解決できたのか実はよくわかっていません。
しかし、NonClientFrameEdgesプロパティをBottomにしたら解決できてしまいました。

WindowChrome.NonClientFrameEdges プロパティ

「ウィンドウ フレームのどの外枠がクライアントによって所有されないかを示す値」って一体どういう意味だ?
意味わかりません。機械翻訳だから意味わからないのかなと思って原文を見てみましたが、原文もほとんどそのままで、結局意味はわからずじまいです。そもそも、ウィンドウフレームがクライアントに所有されたらなぜ最大化したときに黒くなくなるのかっていうのがわかっていませんからね…。

ちなみに、挙動をいろいろ研究してみたところ、
  • Topにする→右上の閉じる、最大化、最小化のボタンが押せなくなった
  • Rightにする→右上の閉じる、最大化、最小化のボタンが若干右に寄って見栄えが悪くなった
という現象が起こりました。Leftにしたらソフトウェアのアイコンが左に寄って見栄えが悪くなるのかなーって思ったらどうもそうではない模様。ほんとよくわからないです。

どうもこのプロパティ、.NET4.5から実装されたプロパティみたいで(ていうか、WindowChrome自体が参照を追加せずとも使えるように組み込まれたのが.NET4.5から)、資料も全然出回っていないようなんですよね。
何か詳しいことを知っている人がいたらぜひ教えてください。

0 件のコメント:

コメントを投稿