是否有Xamarin.Mac非模态NSAlert对话框?

时间:2015-03-23 19:03:41

标签: c# multithreading modal-dialog xamarin.mac nsalert

在Xamarin.Mac中,我可以轻松创建NSAlert,并致电RunModal()。问题是,这会占用MainThread,并阻止其他东西运行。例如,如果ThreadPool中的一个线程调用InvokeOnMainThread( delegate => { do_NSAlert_modal(); } );,我们真的希望ThreadPool线程成为等待该对话的唯一线程。

是否存在以模块方式运行NSAlert的非阻塞替代方案?或者我是否需要创建一些新的自定义窗口来执行此功能?

1 个答案:

答案 0 :(得分:1)

你可以这样做: 而不是调用alert.RunModal(),执行此操作:

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

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

然后,当您关闭警报时,您可以通过

从其他线程执行此操作
alert.Window.Close ();
NSApplication.SharedApplication.EndSheet (alert.Window);

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

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

<强>更新 似乎以这种方式不会自动调整警报的大小。 RunModal和RunSheetModal会调整警报的大小以使内容适合。如果你想要它是非模态的,你将不得不使用alert.Window.SetContentSize计算大小以适合某种方式。您可以遍历所有子视图并使用alert.MessageText检测nstextfield并计算大小以适应该值并使用frame.right + 10来计算警报窗口应具有的内容。但这并不能保证在os x的未来版本上起作用