【问题标题】:ShowMetroDialogAsyncdoesn't show the dialog when waiting for the taskShowMetroDialogAsync 在等待任务时不显示对话框
【发布时间】:2016-03-08 14:25:55
【问题描述】:

我尝试像here 描述的那样实现 DialogManager。我没有使用caliburn,所以我重构了一下,它不再是SimpleDialog而是CustomDialog,但并没有太大的变化。

所以现在当我单击调用DialogManager.ShowDialog 的按钮并使用task.Wait() 等待生成的任务时,应用程序只是冻结(与等待一样)但不显示对话框。我试图调试,但它工作正常,直到行

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

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

如果您需要更多信息,请发表评论,我会扩展问题,但现在除了开头已经链接的代码之外,我不知道该显示什么。

【问题讨论】:

  • 为什么不使用Application.Current.MainWindow.ShowMetroDialogAsync...?你的Application.MainWindow 不是MetroWindow 吗?请注意,根据设计,MahApps 的对话框是模态的,并显示在所属窗口的覆盖层上。
  • mahApps 对话框设计为 模式,它是异步的,您无法点击其他任何内容,因为它位于窗口前面。但无论如何,是的,你是对的,我可以只使用主窗口,尽管我认为这不会改变任何事情,因为我也得到了主窗口实例。

标签: c# wpf dialog mahapps.metro


【解决方案1】:

你提到了 task.Wait()。如果您启动了显示对话框的任务,恐怕您不能这样做。 GUI 是单线程的。您仍然可以等待结果,只需从主线程启动,而不是任务。

【讨论】:

  • 是的,你完全正确,应该很明显 - 不知道为什么我没有得出这个结论:D
【解决方案2】:

这是我必须做的所有噱头,以便在不使用 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 似乎没有任何效果,或者它从来没有打算做文档欺骗我相信它可能应该做的事情。

【讨论】:

  • 感谢您的回答,但这是很久以前的事了,所以我无法真正检查这是否有效......
  • 没关系。这是为了子孙后代。
猜你喜欢
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多