我无法理解如何在Monogame Windows应用商店应用中实现同步MessageBox / QueryBox / QueryStringBox调用。
在其他平台(Android,WP7 / 8,IOS)上实现我们的引擎时,我们以同步方式调用MessageBox / QueryBox / QueryStringBox包装器:
if (SysDlg.QRESULT_YES == SysDlg.showQueryBox(APP_NAME, "Save data?", S_YES, S_NO))
{
//Save data
}
else
{
//do something else
}
这是最方便的方式,因为gui代码变为线性。这样的调用是在后台渲染线程中进行的,所以如果我们在SysDlg.showQueryBox中等待就可以了。伪代码看起来像这样:
int standardOpenDlg(int dlgType, <some arguments>)
{
msDlgActive = true;
< async construct and show dlg on main UI thread with handler like below >
dlg.onButtonPress += () =>
{
dlg.close();
msDlgResult = 1;
msDlgActive = false;
}
while (msDlgActive)
EngineSystem.Sleep(100);
//when user presses button msDlgActive becomes false and we quit endless loop and return msDlgResult
return msDlgResult;
}
在我目前的情况下,我有这样的MessageBox代码:
var messageDialog = new MessageDialog(msDlgText, msDlgTitle);
for (int i = 0; i < cnt; i++)
messageDialog.Commands.Add(new UICommand(buttonsTexts[i],
new UICommandInvokedHandler(MsgBoxInputFinishedCallBack), (int)i));
messageDialog.DefaultCommandIndex = 0;
messageDialog.ShowAsync();
按钮的回调:
private static void MsgBoxInputFinishedCallBack(IUICommand command)
{
// get the result
if (command != null && command.Id != null)
{
int result = (int)command.Id;
msDlgResult = (int)result;
}
msDlgActive = false;
}
我试图将消息框创建并调用
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {...} );
但是如果我之后阻止我的背景绘制线程,我从来没有看到消息框。它看起来像MainGame.Update(它完全在这个bg线程中执行)应该完成并将控制权返回给系统,以便我的代码可以在主线程上执行。
如果我调用(即使在我的线程中)然后继续执行(但也保留没有msDlgResult的调用者上下文),我的消息框按预期显示。
我也试过
messageDialog.ShowAsync();
await messageDialog.ShowAsync();
Task t = messageDialog.ShowAsync().AsTask();
t.Wait();
但没有任何帮助。
在Windows Phone 8中,我刚刚使用回调调用了Guide.BeginShowMessageBox,一切正常。
我想我不太了解这个新的Metro和async / await(虽然我知道它是什么)。 请告诉我如何在消息框关闭之前等待bg线程? 也许我应该使用其他一些winRT UI? 谢谢!
------更新
如果有人关心 - 最后我必须创建/显示对话框并在两个不同的地方处理结果。