「Xamarin.Macでモーダルウインドウを作成する」の版間の差分

提供: MonoBook
ナビゲーションに移動 検索に移動
imported>Administrator
 
(3人の利用者による、間の7版が非表示)
1行目: 1行目:
[[MonoMac]]で[[モーダルウインドウ]]を表示する。
+
[[MonoMac]]および[[Xamarin.Mac]]で[[モーダルウインドウ]]を表示する。
  
==実装例1==
+
==概要==
 +
[[Mac OS X]]では一般的に[[Windows]]風の「[[モーダルウインドウ]]」ではなく「[[シート]]」(親ウインドウに固定されたモーダルウィンドウ)を使うらしい。シートは親ウインドウに張り付くため、どれか親ウィンドウなのか明確なのでウインドウ開きすぎなグダグダな環境では良いとされている。
 +
 
 +
しかしながらが、特定業務専用機と化している[[Mac]]では親ウインドウを見ながら項目入力したいのとの苦情が殺到した。そのためWindows風のモーダルウインドウを実現する方法を模索した。
 +
 
 +
==実装1==
 
===戻り値の準備===
 
===戻り値の準備===
[[モーダルウインドウ]]の[[戻り値]]用に[[WinForms]]のDialogResult風に[[列挙体]]を用意しておくと[[可読性]]が向上する気がする。
+
[[モーダルウインドウ]]の[[戻り値]]用に[[WinForms]]のDialogResult風に[[列挙体]]を用意しておくと[[可読性]]が向上する気がする。<source lang="csharp">
<source lang="csharp">
 
 
     // モーダルウインドウの戻り値用
 
     // モーダルウインドウの戻り値用
 
     public enum ModalResult
 
     public enum ModalResult
15行目: 19行目:
  
 
===親ウインドウから子ウインドウを呼び出す===
 
===親ウインドウから子ウインドウを呼び出す===
MonoMacで[[モーダルウインドウ]]を表示するには NSApplication.SharedApplication.RunModalForWindowメソッドを使うようだ。
+
[[Xamarin.Mac]]で[[モーダルウインドウ]]を表示するには「NSApplication.SharedApplication.RunModalForWindowメソッド」を使うようだ。親ウインドウは勝手に認識されている?
親ウインドウは勝手に認識されている?
 
<source lang="csharp">
 
    public partial class MainWindowController : MonoMac.AppKit.NSWindowController
 
    {
 
        // 中略
 
 
 
        public override void WindowDidLoad()
 
        {
 
            base.WindowDidLoad();
 
 
 
            showSubWindowButton.Activated += (object sender, EventArgs e) => {
 
                var sub = new SubWindowController();
 
                var ret = NSApplication.SharedApplication.RunModalForWindow(sub.Window);
 
                if (ret == (int)ModalResult.OK)
 
                {
 
                    Console.WriteLine("ok");
 
                }
 
            };
 
        }
 
    }
 
</source>
 
  
 
===子ウインドウを閉じる===
 
===子ウインドウを閉じる===
子ウインドウを閉じるにはNSApplication.SharedApplication.StopModalWithCodeメソッドを使うようだ。このメソッドを呼ばずに子ウインドウを閉じると親ウインドウに制御が戻らないので注意すること。
+
子ウインドウを閉じるには「NSApplication.SharedApplication.StopModalWithCodeメソッド」を使うようだ。このメソッドを呼ばずに子ウインドウを閉じると親ウインドウに制御が戻らないので注意すること。
  
この例では子ウインドウが普通に×ボタンで閉じる際に「ModalResult.OK」を返している。ダイアログ風にするのであればOKボタンやキャンセルボタンを用意して、それらが押した際にNSApplication.SharedApplication.StopModalWithCodeメソッド呼ぶとよいようだ。
+
この例では子ウインドウが普通に「×ボタン」で閉じる際に「ModalResult.OK」を返している。ダイアログ風にするのであればOKボタンやキャンセルボタンを用意して、それらが押した際にNSApplication.SharedApplication.StopModalWithCodeメソッド呼ぶとよいようだ。<source lang="csharp">
<source lang="csharp">
 
 
     public partial class SubWindowController : MonoMac.AppKit.NSWindowController
 
     public partial class SubWindowController : MonoMac.AppKit.NSWindowController
 
     {
 
     {
59行目: 41行目:
 
</source>
 
</source>
  
なお、NSApplication.SharedApplication.StopModalWithCodeはウインドウのモーダル化が解除されるだけでウインドウ自体は閉じない。ボタンなどを押されたときにモーダルウインドウを閉じる場合にはthis.Window.Closeを呼んでやると良いようだ。
+
なお、NSApplication.SharedApplication.StopModalWithCodeメソッドはウインドウのモーダル化が解除されるだけでウインドウ自体は閉じない。ボタンなどを押されたときにモーダルウインドウを閉じる場合にはthis.Window.Closeを呼んでやると良いようだ。
<source lang="csharp">
 
        ModalResult _result = ModalResult.Cancel;
 
  
        public override void AwakeFromNib()
+
=== 表示してみる ===
        {
+
<syntaxhighlight lang="csharp">
            base.AwakeFromNib();
+
// ダイアログ生成
            // ----------------------------------------------------
+
var dialog = new SubWindowController();
 +
 
 +
// LoadWindowでawakeNibなどの初期化処理が呼ばれる
 +
dialog.LoadWindow();
  
            this.Window.WillClose += (object sender, EventArgs e) => {
+
// ウインドウを最前面にしておく(不要かもしれない)
                Console.WriteLine("WillClose");
+
dialog.Window.MakeKeyAndOrderFront(this);
                NSApplication.SharedApplication.StopModalWithCode((int)_result);
 
            };
 
  
            // cancelButtonはInterfaceBuilderで貼付けたNSButton
+
// モーダル表示実行
            cancelButton.Activated += (object sender, EventArgs e) => {
+
NSApplication.SharedApplication.RunModalForWindow(dialog.Window);
                Console.WriteLine("cancelButton");
 
                _result = ModalResult.Cancel;
 
                this.Window.Close();
 
            };
 
  
            // cancelButtonはInterfaceBuilderで貼付けたNSButton
+
</syntaxhighlight>
            okButton.Activated += (object sender, EventArgs e) => {
 
                Console.WriteLine("okButton");
 
                _result = ModalResult.OK;
 
                this.Window.Close();
 
            };
 
        }
 
</source>
 
  
 
==関連項目==
 
==関連項目==
98行目: 68行目:
  
 
[[category:MonoMac]]
 
[[category:MonoMac]]
 +
[[category:Xamarin.Mac]]

2018年8月7日 (火) 01:59時点における最新版

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);

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

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