ShowMetroDialogAsyncdoes在等待任务时不显示对话框

时间:2016-03-08 14:25:55

标签: c# wpf dialog mahapps.metro

我尝试实现类似here所述的DialogManager。我没有使用caliburn,所以我重构了一下,而且它不再是SimpleDialog而是CustomDialog,但是没有大的改变。

所以现在当我单击一个调用DialogManager.ShowDialog的按钮并等待task.Wait()生成的任务时,应用程序就会冻结(如等待的那样)但没有显示对话框。我试图调试,但它直到行

await Application.Current.Windows.OfType<MetroWindow>().First().ShowMetroDialogAsync(dialog);

。对话框是有效的BaseMetroDialog,我从Application.Cur...调用中获得了正确的窗口。当我只是调用ShowMessageAsync时也会发生这种情况,所以问题似乎在于调用和等待任务的连接。有没有办法真正阻止以下执行(强制对话框是模态的)?

如果您需要其他信息,请发表评论,我会延伸这个问题,但是现在我不知道除了已经链接的代码之外还要展示什么。

2 个答案:

答案 0 :(得分:1)

你提到task.Wait()。如果您开始显示对话框的任务,我担心您无法做到这一点。 GUI是单线程的。您仍然可以等待结果,只需从主线程启动,而不是任务。

答案 1 :(得分:0)

这是我要做的所有the头,以便无需使用async / await即可使它工作:

using SysThread = System.Threading;
using WpfThread = System.Windows.Threading;
using SysTasks = System.Threading.Tasks;
using MahCtl = MahApps.Metro.Controls;
using MahDlg = MahApps.Metro.Controls.Dialogs;
using Wpf = System.Windows;
.
.
.
private SysThread.CancellationTokenSource tokenSource;
.
.
.
    MahCtl.MetroWindow parentMetroWindow = Wpf.Application.Current.Windows.OfType<MahCtl.MetroWindow>().First();
    var metroDialogSettings = new MahDlg.MetroDialogSettings();
    metroDialogSettings.OwnerCanCloseWithDialog = true; //does not appear to have any effect
    metroDialogSettings.AnimateHide             = false;
    metroDialogSettings.AnimateShow             = false;
    using( tokenSource = new SysThread.CancellationTokenSource() )
    {
        metroDialogSettings.CancellationToken = tokenSource.Token;
        SysTasks.Task<MahDlg.MessageDialogResult> task = MahDlg.DialogManager.ShowMessageAsync( parentMetroWindow, title, message, mahStyle, metroDialogSettings );
        parentMetroWindow.Closing += onMainWindowClosing;
        while( !(task.IsCompleted || task.IsCanceled || task.IsFaulted) )
            Wpf.Application.Current.Dispatcher.Invoke( WpfThread.DispatcherPriority.Background, new Action( delegate { } ) );
        parentMetroWindow.Closing -= onMainWindowClosing;
        return task.Result;
    }
.
.
.
private void onMainWindowClosing( object sender, SysCompMod.CancelEventArgs cancelEventArgs )
{
    tokenSource.Cancel();
}

主窗口的Closing事件需要一个额外的处理程序,以便处理用户尝试通过任务栏关闭应用程序主窗口的情况,而模式对话框是开放,因为OwnerCanCloseWithDialog似乎没有任何效果,或者它从来没有做过文档诱使我相信它可能是应该做的事情。