0

Xamarin.Mac では、 を簡単に作成しNSAlert、 を呼び出すことができますRunModal()。問題は、これが MainThread を独占し、他のものの実行をブロックすることです。たとえば、ThreadPool からのスレッドが呼び出しInvokeOnMainThread( delegate => { do_NSAlert_modal(); } );を行う場合、ThreadPool スレッドがその対話を待機している唯一のスレッドになるようにしたいと考えています。

NSAlert をモーダルに実行する代わりに、ノンブロッキングの代替手段はありますか? または、この機能を実行するために新しいカスタム ウィンドウを作成する必要がありますか?

4

1 に答える 1

1

次のようにできます: alert.RunModal() を呼び出す代わりに、次のようにします:

NSApplication.SharedApplication.BeginSheet (alert.Window, this.WindowForSheet);

その 2 番目のパラメーターについては、アラート ウィンドウをアタッチするウィンドウをフィードする必要があります。私の場合、これは NSDocument から呼び出されました。

次に、アラートを閉じると、他のスレッドからそれを行うことができます

alert.Window.Close ();
NSApplication.SharedApplication.EndSheet (alert.Window);

私の場合、別のスレッドでサーバーにデータをアップロードしているときにアラートを表示し、終了したら閉じました(ダーティメソッドを使用して[OK]ボタンも非表示にしました)。OK ボタンを表示したい場合は、アラートの [OK] ボタンから閉じた場合でも、その 2 行目を呼び出す必要がある場合があります (これは自分でテストする必要があります)。

NSApplication.BeginSheet と EndSheet は 10.10 で廃止されることに注意してください。Apple は、代わりに NSWindow.BeginSheet と EndSheet を使用する必要があることを示しており、アラートをアタッチしたいウィンドウで呼び出します。ただし、これらの 2 つの方法は 10.10 でのみ使用できることにも注意してください。したがって、10.9 もターゲットにしている場合 (ほとんどの開発者はまだそうしています)、今のところ非推奨バージョンを使用する必要があります...アプリ開発者のことはあまり気にしない

更新 この方法では、アラートのサイズが自動的に変更されないようです。RunModal と RunSheetModal は、コンテンツが収まるようにアラートのサイズを変更します。非モーダルにしたい場合は、alert.Window.SetContentSize を使用して、何らかの形で収まるようにサイズを計算する必要があります。すべてのサブビューをループして、alert.MessageText で nstextfield を検出し、それに合うサイズを計算し、frame.right + 10 を使用して、アラート ウィンドウに必要な値を計算することができます。ただし、これは os x の将来のバージョンで動作することを保証するものではありません

于 2015-06-27T10:03:11.620 に答える