窗口内弹出窗口:如何阻止UI线程?

时间:2016-12-22 01:10:36

标签: c# .net wpf mvvm mvvm-light

我目前正在实施 MessageDialog 控件。它完全替换MessageBox并显示为"窗口内弹出窗口" (需要正确的UX术语)

目前,它的构造函数是私有的,并且有一个方法Show,就像在MessageBox.Show中一样。但是,MessageBox会阻止UI线程并返回结果。

我的MessageDialog控件当前执行的操作是Action<MessageDialogResult> callback参数,单击按钮时会调用该参数。

使用MessageDialog

// class MessageDialog
public static void MessageDialog.Confirmation(Window owner, string message, Action<MessageDialogResult> callback);

// When used by other controls
MessageDialog.Confirmation(WindowMain.Singleton, true, (result) =>
{
    if (result.Button == MessageDialogButton.Yes)
    {
        //...
    }
});

dialog

但是,在MessageBox.Show中使用回调而不是阻塞方法调用对我来说绝对没有任何好处。它使事情变得相当复杂。我想要实现的目标就像......

if (MessageDialog.Confirmation(WindowMain.Singleton, true).Button == MessageDialogButton.Yes)
{
    //...
}

......在我看来这更干净。

目前的代码基本上是

  1. 创建MessageDialog的实例并使用文本填充内容
  2. 将其添加到Window.Content.Children
  3. 的子项中
  4. 点击按钮,拨打callback(result)并从Window.Content.Children
  5. 中删除

    问题:我想要实现的是阻塞方法调用,而不是触发回调的方法。

2 个答案:

答案 0 :(得分:3)

尽管接受的答案似乎有效,但我建议使用TaskCompletionSource提供更好的解决方案。这正是await的用途 - 它基本上只是一个回调(不会阻塞线程),但是使用它时你的代码看起来要简单得多。

TaskCompletionSource<DialogResult> taskSource;

Task<DialogResult> ShowAsync()
{
    return taskSource.Task;
}

public void OkButton_OnClick(EventArgs e, object sender)
{
    taskSource.SetResult(DialogResult.OK);
}

public void CancelButton_OnClick(EventArgs e, object sender)
{
    taskSource.SetResult(DialogResult.Cancel);
}

然后你必须等待电话:await Dialog.ShowAsync()

答案 1 :(得分:1)

这样的事情怎么样:

mean/variance/scale/shift