Xamarin.Macでモーダルウインドウを作成する

提供: MonoBook
移動先: 案内検索

MonoMacおよびXamarin.Macモーダルウインドウを表示する。

概要[編集 | ソースを編集]

Mac OS Xでは一般的にWindows風の「モーダルウインドウ」ではなく「シート」(親ウインドウに固定されたモーダルウィンドウ)を使うらしい。シートは親ウインドウに張り付くため、どれか親ウィンドウなのか明確なのでウインドウ開きすぎなグダグダな環境では良いとされている。

しかしながらが、特定業務専用機と化しているMacでは親ウインドウを見ながら項目入力したいのとの苦情が殺到した。そのためWindows風のモーダルウインドウを実現する方法を模索した。

実装1[編集 | ソースを編集]

戻り値の準備[編集 | ソースを編集]

モーダルウインドウ戻り値用にWinFormsのDialogResult風に列挙体を用意しておくと可読性が向上する気がする。
    // モーダルウインドウの戻り値用
    public enum ModalResult
    {
        Unknown = 0,
        OK = 1,
        Cancel = 2,
    }

親ウインドウから子ウインドウを呼び出す[編集 | ソースを編集]

Xamarin.Macモーダルウインドウを表示するには「NSApplication.SharedApplication.RunModalForWindowメソッド」を使うようだ。親ウインドウは勝手に認識されている?

子ウインドウを閉じる[編集 | ソースを編集]

子ウインドウを閉じるには「NSApplication.SharedApplication.StopModalWithCodeメソッド」を使うようだ。このメソッドを呼ばずに子ウインドウを閉じると親ウインドウに制御が戻らないので注意すること。

この例では子ウインドウが普通に「×ボタン」で閉じる際に「ModalResult.OK」を返している。ダイアログ風にするのであればOKボタンやキャンセルボタンを用意して、それらが押した際にNSApplication.SharedApplication.StopModalWithCodeメソッド呼ぶとよいようだ。
    public partial class SubWindowController : MonoMac.AppKit.NSWindowController
    {
        // 中略

        public override void AwakeFromNib()
        {
            base.AwakeFromNib();

            this.Window.WillClose += (object sender, EventArgs e) => {
                Console.WriteLine("willClose");
                NSApplication.SharedApplication.StopModalWithCode((int)ModalResult.OK);
            };
        }
    }

なお、NSApplication.SharedApplication.StopModalWithCodeメソッドはウインドウのモーダル化が解除されるだけでウインドウ自体は閉じない。ボタンなどを押されたときにモーダルウインドウを閉じる場合にはthis.Window.Closeを呼んでやると良いようだ。

表示してみる[編集 | ソースを編集]

// ダイアログ生成
var dialog = new SubWindowController();

// LoadWindowでawakeNibなどの初期化処理が呼ばれる
dialog.LoadWindow();

// ウインドウを最前面にしておく(不要かもしれない)
dialog.Window.MakeKeyAndOrderFront(this);

// モーダル表示実行
NSApplication.SharedApplication.RunModalForWindow(dialog.Window);

関連項目[編集 | ソースを編集]

参考文献[編集 | ソースを編集]