「Xamarin.Macでモーダルウインドウを作成する」の版間の差分
imported>Administrator |
|||
(3人の利用者による、間の7版が非表示) | |||
1行目: | 1行目: | ||
− | [[MonoMac]]で[[モーダルウインドウ]]を表示する。 | + | [[MonoMac]]および[[Xamarin.Mac]]で[[モーダルウインドウ]]を表示する。 |
− | == | + | ==概要== |
+ | [[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行目: | ||
===親ウインドウから子ウインドウを呼び出す=== | ===親ウインドウから子ウインドウを呼び出す=== | ||
− | + | [[Xamarin.Mac]]で[[モーダルウインドウ]]を表示するには「NSApplication.SharedApplication.RunModalForWindowメソッド」を使うようだ。親ウインドウは勝手に認識されている? | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===子ウインドウを閉じる=== | ===子ウインドウを閉じる=== | ||
− | + | 子ウインドウを閉じるには「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. | + | なお、NSApplication.SharedApplication.StopModalWithCodeメソッドはウインドウのモーダル化が解除されるだけでウインドウ自体は閉じない。ボタンなどを押されたときにモーダルウインドウを閉じる場合にはthis.Window.Closeを呼んでやると良いようだ。 |
− | |||
− | |||
− | + | === 表示してみる === | |
− | + | <syntaxhighlight lang="csharp"> | |
− | + | // ダイアログ生成 | |
− | + | var dialog = new SubWindowController(); | |
+ | |||
+ | // LoadWindowでawakeNibなどの初期化処理が呼ばれる | ||
+ | dialog.LoadWindow(); | ||
− | + | // ウインドウを最前面にしておく(不要かもしれない) | |
− | + | dialog.Window.MakeKeyAndOrderFront(this); | |
− | |||
− | |||
− | + | // モーダル表示実行 | |
− | + | NSApplication.SharedApplication.RunModalForWindow(dialog.Window); | |
− | |||
− | |||
− | |||
− | |||
− | + | </syntaxhighlight> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | </ | ||
==関連項目== | ==関連項目== | ||
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);