Silverlight确认对话框以暂停线程

Ali*_*vin 6 silverlight confirm dialog childwindow

我正在尝试使用Silverlight的ChildWindow对象进行确认对话.

理想情况下,我希望它能够工作MessageBox.Show(),整个应用程序停止,直到从用户收到输入.

例如:

for (int i = 0; i < 5; i++)
{
    if (i==3 && MessageBox.Show("Exit early?",
        "Iterator", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
    {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果用户点击OK,将停止迭代3 ...

但是,如果我要按照以下方式做某事:

ChildWindow confirm = new ChildWindow();
confirm.Title = "Iterator";
confirm.HasCloseButton = false;
Grid container = new Grid();

Button closeBtn = new Button();
closeBtn.Content = "Exit early";
closeBtn.Click += delegate { confirm.DialogResult = true; confirm.Close(); };
container.Children.Add(closeBtn);

Button continueBtn = new Button();
continueBtn.Content = "Continue!";
continueBtn.Click += delegate { confirm.DialogResult = false; confirm.Close(); };
container.Children.Add(continueBtn);

confirm.Content = container;

for(int i=0;i<5;i++) {
  if (i==3) {
    confirm.Show();
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) {
      break;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这显然不起作用,因为线程没有停止... confirm.DialogResult.HasResult将是错误的,并且循环将继续超过3.

我只是想知道,我怎么能正确地做到这一点.Silverlight是单线程的,所以我不能让线程进入睡眠状态,然后在我准备就绪时将其唤醒,所以我只是想知道是否还有其他人可以推荐的东西?

我考虑过颠倒逻辑 - 即将我想要发生的动作传递给Yes/No事件,但在我的具体情况下,这不会起作用.

提前致谢!

SLa*_*aks 12

我认为你不能像WinForms一样在消息循环中阻止你的代码ShowDialog.

但是,您可以滥用迭代器来实现相同的效果:

interface IAction { void Execute(Action callback); }

public static void ExecAction(IEnumerator<IAction> enumerator) {
    if (enumerator.MoveNext())
        enumerator.Current.Execute(() => ExecAction(enumerator));
}

class DialogAction : ChildWindow, IAction {
    void IAction.Execute(Action callback) {
       //Show the window, then call callback when it's closed
    }
}

IEnumerator<IAction> YourMethod() { 
    ...
    var confirm = new DialogAction();
    yield return confirm;
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult)
        yield break;
    ...
}
Run Code Online (Sandbox Code Playgroud)

要使用这个系统,你会写ExecAction(YourMethod());.请注意,这将是一个半阻塞调用,我根本没有测试过.

C#5的新async功能完全相同(事实上,async编译器代码的初始版本很大程度上基于现有的迭代器实现),但具有更好的语法支持.