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

关于第二个参数,您必须输入要为其附加警报窗口的窗口。就我而言,这是从 NSDocument 调用的。

然后,当您关闭警报时,您可以通过其他线程执行此操作

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

就我而言,当我在单独的线程上将一些数据上传到服务器上时显示警报,然后在完成后关闭它(我也会使用一些肮脏的方法隐藏确定按钮)。如果您想让 ok 按钮可见,您可能需要调用第二行,即使您从警报的 ok 按钮关闭它(您必须自己测试)

请注意 NSApplication.BeginSheet 和 EndSheet 在 10.10 中已弃用。Apple 表示您必须改用 NSWindow.BeginSheet 和 EndSheet,方法是将其调用到要附加警报的窗口上。但还要注意,这两种方法仅在 10.10 上可用,因此,如果您也以 10.9 为目标(大多数开发人员仍然这样做),您现在必须使用已弃用的版本......这就是苹果弃用事物的方式 - 他们并不真正关心他们的应用程序开发人员

更新 似乎以这种方式警报不会自动调整大小。RunModal 和 RunSheetModal 会调整警报的大小以适应内容。如果您希望它是非模态的,则必须使用 alert.Window.SetContentSize 以某种方式计算大小以适应。您可以遍历所有子视图并使用 alert.MessageText 检测 nstextfield 并计算大小以适应它并使用 frame.right + 10 来计算警报窗口应具有的大小。但这不保证适用于未来版本的 os x

于 2015-06-27T10:03:11.620 回答