読者です 読者をやめる 読者になる 読者になる

SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

ウィンドウをフルスクリーン化する添付ビヘイビア

以前↓のような記事を書きましたが、このようにウィンドウをフルスクリーン化する処理を添付ビヘイビアにしてみました。
WPFでフルスクリーン表示 - SourceChord

添付ビヘイビアの実装は以下の通り。

FullScreenAttachedBehavior.cs
    public class FullScreenAttachedBehavior
    {
        class BackupState
        {
            public WindowStyle WindowStyle { get; set; }
            public WindowState WindowState { get; set; }
            public bool TopMost { get; set; }
        }

        public static bool GetIsFullScreen(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsFullScreenProperty);
        }
        public static void SetIsFullScreen(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFullScreenProperty, value);
        }
        // Using a DependencyProperty as the backing store for IsFullScreen.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsFullScreenProperty =
            DependencyProperty.RegisterAttached("IsFullScreen", typeof(bool), typeof(FullScreenAttachedBehavior), new PropertyMetadata(false, OnIsFullScreenChanged));

        private static void OnIsFullScreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Command添付プロパティに変更が加わったら、マウス左クリック時のイベントを登録する。
            var win = d as Window;
            if (win == null)
            {
                // 要素の親のWindowを取得
                win = Window.GetWindow(d);
            }

            var newValue = (bool)e.NewValue;
            if (newValue)
            {
                // フルスクリーン化する時の処理
                // 現在の設定をバックアップ
                var oldValue = new BackupState() { WindowStyle = win.WindowStyle, WindowState = win.WindowState, TopMost = win.Topmost };
                SetOldValue(d, oldValue);

                // フルスクリーン化
                win.WindowStyle = WindowStyle.None;
                win.WindowState = WindowState.Maximized;
                win.Topmost = true;
            }
            else
            {
                // フルスクリーンを解除して、元の値に戻す
                var oldValue = GetOldValue(d);
                win.WindowStyle = oldValue.WindowStyle;
                win.WindowState = oldValue.WindowState;
                win.Topmost = oldValue.TopMost;
            }
        }


        #region 添付ビヘイビアの内部で使用するprivateな添付プロパティ
        private static BackupState GetOldValue(DependencyObject obj)
        {
            return (BackupState)obj.GetValue(OldValueProperty);
        }
        private static void SetOldValue(DependencyObject obj, BackupState value)
        {
            obj.SetValue(OldValueProperty, value);
        }
        // Using a DependencyProperty as the backing store for OldValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OldValueProperty =
            DependencyProperty.RegisterAttached("OldValue", typeof(BackupState), typeof(FullScreenAttachedBehavior), new PropertyMetadata(null));
        #endregion
    }

OldValuePropertyという、privateな添付プロパティを作って、フルスクリーン化する前の状態を保持しているあたりがミソかな。


使い方

添付プロパティをウィンドウにつけるだけで、フルスクリーン化の機能を付け足すことができます。
FullScreenAttachedBehavior.IsFullScreenプロパティがTrueになると、フルスクリーン表示に切り替わります。

<Window x:Class="AttachedBehaviorTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AttachedBehaviorTest"
        Title="MainWindow"
        Width="525"
        Height="350"
        local:FullScreenAttachedBehavior.IsFullScreen="{Binding IsChecked,
                                                                ElementName=chkFull}">
    <Grid>
        <CheckBox x:Name="chkFull"
                  Margin="50"
                  HorizontalAlignment="Left"
                  VerticalAlignment="Top"
                  Content="フルスクリーン化" />
    </Grid>
</Window>