【问题标题】:Wait for MahApps Metro Dialog to return result等待 MahApps Metro Dialog 返回结果
【发布时间】:2015-03-24 09:23:58
【问题描述】:

我有一个 ViewModel 向视图发送消息(使用 MVVM Light Messenger)以显示 Metro Dialog,如下所示:

在 ViewModel 中,我从 DialogBox 类中调用此代码:

DialogBox.ShowDialogBox(
                        (result) => { DialogResult(result); },
                        "Dialog Title",
                        "Dialog Message",
                        MessageDialogStyle.AffirmativeAndNegative
                        );

这是处理向视图发送消息的对话框类:

public class DialogBox
{
    public Action<MessageDialogResult> dialogResultCallBack { get; set; }
    public string dialogTitle;
    public string dialogText;
    public MessageDialogStyle dialogStyle;
    public string okButtonText;
    public string cancelButtonText;

    public DialogBox(Action<MessageDialogResult> _dialogResultCallBack, string _dialogTitle, string _dialogText, MessageDialogStyle _dialogStyle, string _okButtonText, string _cancelButtonText)
    {
        dialogResultCallBack = _dialogResultCallBack;
        dialogTitle = _dialogTitle;
        dialogText = _dialogText;
        dialogStyle = _dialogStyle;
        okButtonText = _okButtonText;
        cancelButtonText = _cancelButtonText;
    }


    public static void ShowDialogBox(Action<MessageDialogResult> _dialogResultCallBack, string _dialogTitle, string _dialogText,
        MessageDialogStyle _dialogStyle, string _affirmativeButtonText = "OK", string _negativeButtonText = "Cancel")
    {
        Messenger.Default.Send(new DialogBox(
                       _dialogResultCallBack,
                       _dialogTitle,
                       _dialogText,
                       _dialogStyle,
                       _affirmativeButtonText,
                       _negativeButtonText), GlobalResources.MessengerTokens.dialogTokenMainWindow);
    }
}

View 代码隐藏有以下代码来接收消息:

Messenger.Default.Register<DialogBox>(this, GlobalResources.MessengerTokens.dialogTokenMainWindow, dialogData =>
            {
                ShowMessageDialog(dialogData);
            });

ShowMessageDialog 处理显示实际对话框。这些都工作正常。

当前,当用户选择肯定/否定时,返回结果并触发对 ViewModel 中 DialogResult(result) 的操作调用,如最上面的代码 sn-p 所示。

private void DialogResult(MessageDialogResult result)
    {
        if (result == MessageDialogResult.Affirmative)
        {
             //deal with the situation
        }
        else
        {
            //deal with the situation
        }
    }

实际上我想在 ViewModel 中调用 DialogBox.ShowDialogBox() 方法后立即等待结果。当前的方法是导致代码跳转到单独的方法调用,而不是能够立即处理结果。为了简要说明这一点,

if(condition)
{
  DialogBox.ShowDialogBox(...);

  //Needs some sort of await method to wait for results here

  if(result == MessageDialogResult.Affirmative)
  {
         //do stuff
  }
  else
  {
        //do stuff
  }
 }

我至少在 WinForms 上看到了一些示例代码,通过执行以下操作更容易等待结果(使用代码隐藏且不使用 MVVM):

if (MessageBox.Show("Title", "Message", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.OK)

对于我目前的情况,我可以采取类似的方法吗?感谢您的任何建议,如果我的问题太长,我们很抱歉。

【问题讨论】:

    标签: c# wpf mvvm mvvm-light mahapps.metro


    【解决方案1】:

    我认为有更好的方法来做你正在做的事情。为了让这个更 MVVM,这就是我所做的……首先,我使用 Caliburn Micro 来处理我的 MVVM 内容和 MEF。所以首先我们有两个接口:

    internal interface IDialogViewModel
    {
        event EventHandler Closed;
    }
    

    以下界面将帮助您获得对话的结果

    public interface IDialogManager
    {
        /// <summary>
        /// Show a dialog that performs as Task with generic return type. 
        /// </summary>
        /// <typeparam name="TResult">The result to be returned from the dialog task.</typeparam>
        /// <param name="viewModel">The DialogViewModel type to be displayed.</param>
        /// <returns>The Task to be awaited.</returns>
        Task<TResult> ShowDialog<TResult>(DialogViewModel<TResult> viewModel);
    
        /// <summary>
        /// Show a dialog that performs as Task.
        /// </summary>
        /// <param name="viewModel">The result to be returned from the dialog task.</param>
        /// <returns>The Task to be awaited.</returns>
        Task ShowDialog(DialogViewModel viewModel);
    }
    

    这些接口的实现是

    /// <summary>
    /// DialogViewModel class which should be inherited for all view 
    /// model that want to be displayed as metro dialogs.
    /// </summary>
    public abstract class DialogViewModel : Screen, IDialogViewModel
    {
        private readonly TaskCompletionSource<int> tcs;
        internal Task Task { get { return tcs.Task; } }
    
        /// <summary>
        /// Deafult constructor.
        /// </summary>
        protected DialogViewModel()
        {
            tcs = new TaskCompletionSource<int>();
        }
    
        /// <summary>
        /// Close the dialog.
        /// </summary>
        protected void Close()
        {
            tcs.SetResult(0);
            var handler = Closed;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
    
        /// <summary>
        /// Closed event.
        /// </summary>
        public event EventHandler Closed;
    }
    
    /// <summary>
    /// DialogViewModel class which should be inherited for all view 
    /// model that want to be displayed as metro dialogs that can return a 
    /// specific result.
    /// </summary>
    public abstract class DialogViewModel<TResult> : Screen, IDialogViewModel
    {
        private readonly TaskCompletionSource<TResult> tcs;
        internal Task<TResult> Task { get { return tcs.Task; } }
    
        /// <summary>
        /// Deafult constructor.
        /// </summary>
        protected DialogViewModel()
        {
            tcs = new TaskCompletionSource<TResult>();
        }
    
        /// <summary>
        /// Close the dialog.
        /// </summary>
        protected void Close(TResult result)
        {
            tcs.SetResult(result);
            var handler = Closed;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
    
        /// <summary>
        /// Closed event.
        /// </summary>
        public event EventHandler Closed;
    }
    

    经理类是

    /// <summary>
    /// The DialogManager that can be used to show Views as Metro modal dialogs.
    /// Import IDialogManager to any view model that needs to show a metro message 
    /// box.
    /// </summary>
    [Export(typeof(IDialogManager))]
    public class DialogManager : IDialogManager
    {
        /// <summary>
        /// Show the required dialog.
        /// </summary>
        /// <param name="viewModel">The view model ascociated with the view.</param>
        public async Task ShowDialog(DialogViewModel viewModel)
        {
            // Locate the ascociated view.
            var viewType = ViewLocator.LocateTypeForModelType(viewModel.GetType(), null, null);
            var dialog = (BaseMetroDialog)Activator.CreateInstance(viewType);
            if (dialog == null)
            {
                throw new InvalidOperationException(
                    String.Format("The view {0} belonging to view model {1} " +
                                      "does not inherit from {2}",
                                      viewType,
                                      viewModel.GetType(),
                                      typeof(BaseMetroDialog)));
            }
            dialog.DataContext = viewModel;
    
            // Show the metro window.
            MetroWindow firstMetroWindow = 
                Application.Current.Windows.OfType<MetroWindow>().First();
            await firstMetroWindow.ShowMetroDialogAsync(dialog);
            await viewModel.Task;
            await firstMetroWindow.HideMetroDialogAsync(dialog);
        }
    
        /// <summary>
        /// Show the required dialog.
        /// </summary>
        /// <typeparam name="TResult">The type of result to return.</typeparam>
        /// <param name="viewModel">The view model ascociated with the view.</param>
        public async Task<TResult> ShowDialog<TResult>(DialogViewModel<TResult> viewModel)
        {
            // Locate the ascociated view.
            var viewType = ViewLocator.LocateTypeForModelType(viewModel.GetType(), null, null);
            var dialog = (BaseMetroDialog)Activator.CreateInstance(viewType);
            if (dialog == null)
            {
                throw new InvalidOperationException(
                    String.Format("The view {0} belonging to view model {1} " +
                                      "does not inherit from {2}",
                                      viewType,
                                      viewModel.GetType(),
                                      typeof(BaseMetroDialog)));
            }
            dialog.DataContext = viewModel;
    
            // Show the metro window.
            MetroWindow firstMetroWindow = Application.Current.Windows.OfType<MetroWindow>().First();
            await firstMetroWindow.ShowMetroDialogAsync(dialog);
            TResult result = await viewModel.Task;
            await firstMetroWindow.HideMetroDialogAsync(dialog);
            return result;
        }
    }
    

    我们也有消息框设置

    /// <summary>
    /// Class that holds the settings for message box dialogs.
    /// </summary>
    public class MessageBoxSettings
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        public MessageBoxSettings()
        {
            this.AffirmativeButtonText = "OK";
            this.NegativeButtonText = "Cancel";
            this.MessageDialogStyle = MessageDialogStyle.AffirmativeAndNegative;
            this.MetroColorDialogScheme = MetroDialogColorScheme.Theme;
            this.Animation = false;
        }
    
        /// <summary>
        /// Sets the button styles to use.
        /// Default is 'OK' and 'Cancel'.
        /// </summary>
        public MessageDialogStyle MessageDialogStyle { get; set; }
    
        /// <summary>
        /// The color sheme to use for the dialog.
        /// </summary>
        public MetroDialogColorScheme MetroColorDialogScheme { get; set; }
    
        /// <summary>
        /// Affirmative button text. Default OK.
        /// </summary>
        public string AffirmativeButtonText { get; set; }
    
        /// <summary>
        /// The negative button text to use.
        /// </summary>
        public string NegativeButtonText { get; set; }
    
        /// <summary>
        /// First auxillary button text.
        /// </summary>
        public string FirstAuxillaryButtonText { get; set; }
    
        /// <summary>
        /// Second auxillary button text.
        /// </summary>
        public string SecondAuxiliaryButtonText { get; set; }
    
        /// <summary>
        /// Show animation on the dialog.
        /// </summary>
        public bool Animation { get; set; }
    }
    

    现在实际使用上面代码的视图和视图模型是

    /// <summary>
    /// View model for the message box view.
    /// </summary>
    public class MessageBoxViewModel : DialogViewModel<MessageDialogResult>
    {
        private MessageBoxSettings settings;
    
        #region Initialisation.
        /// <summary>
        /// Null.
        /// </summary>
        public MessageBoxViewModel() { }
    
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="title">The title of the message box dialog.</param>
        /// <param name="message">The message to display in the message box.</param>
        public MessageBoxViewModel(string title, string message)
        {
            this.Title = title;
            this.DialogBody = message;
            if (this.settings == null)
                this.settings = new MessageBoxSettings();
            SetDialogVisuals();
        }
    
        /// <summary>
        /// Overloaded.
        /// </summary>
        /// <param name="title">The title of the message box dialog.</param>
        /// <param name="message">The message to display in the message box.</param>
        /// <param name="settings">MessageBoxSettings for the dialog.</param>
        public MessageBoxViewModel(string title, string message, MessageBoxSettings settings)
        {
            this.Title = title;
            this.DialogBody = message;
            this.settings = settings;
            SetDialogVisuals();
        }
        #endregion // Initialisation.
    
        #region Class Methods.
        /// <summary>
        /// Set the dialog visuals based on the MessageBoxSettings.
        /// </summary>
        private void SetDialogVisuals()
        {
            // Set dialog button visibility.
            switch (settings.MessageDialogStyle)
            {
                case MessageDialogStyle.Affirmative:
                    this.AffirmativeButtonVisibility = Visibility.Visible;
                    this.NegativeButtonVisibility = Visibility.Collapsed;
                    this.FirstAuxillaryButtonVisibility = Visibility.Collapsed;
                    this.SecondAuxillaryButtonVisibility = Visibility.Collapsed;
                    break;
                case MessageDialogStyle.AffirmativeAndNegative:
                    this.AffirmativeButtonVisibility = Visibility.Visible;
                    this.NegativeButtonVisibility = Visibility.Visible;
                    this.FirstAuxillaryButtonVisibility = Visibility.Collapsed;
                    this.SecondAuxillaryButtonVisibility = Visibility.Collapsed;
                    break;
                case MessageDialogStyle.AffirmativeAndNegativeAndDoubleAuxiliary:
                    this.AffirmativeButtonVisibility = Visibility.Visible;
                    this.NegativeButtonVisibility = Visibility.Visible;
                    this.FirstAuxillaryButtonVisibility = Visibility.Visible;
                    this.SecondAuxillaryButtonVisibility = Visibility.Visible;
                    break;
                case MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary:
                    this.AffirmativeButtonVisibility = Visibility.Visible;
                    this.NegativeButtonVisibility = Visibility.Visible;
                    this.FirstAuxillaryButtonVisibility = Visibility.Visible;
                    this.SecondAuxillaryButtonVisibility = Visibility.Collapsed;
                    break;
                default:
                    break;
            }
    
            // Set the button text.
            this.AffirmativeButtonText = settings.AffirmativeButtonText;
            this.NegativeButtonText = settings.NegativeButtonText;
            this.FirstAuxillaryButtonText = settings.FirstAuxillaryButtonText;
            this.SecondAuxiliaryButtonText = settings.SecondAuxiliaryButtonText;
    
            // Color scheme.
            string name = MahApps.Metro.ThemeManager.DetectAppStyle(Application.Current).Item2.Name;
            this.Background = settings.MetroColorDialogScheme == MetroDialogColorScheme.Theme ?
                MahApps.Metro.ThemeManager.Accents
                    .Where(a => a.Name.CompareNoCase(name))
                    .First().Resources["HighlightBrush"] as SolidColorBrush :
                new SolidColorBrush(System.Windows.Media.Colors.White);
        }
    
        /// <summary>
        /// Handles the button click events for the affermative button.
        /// </summary>
        public void AffirmativeButtonClick()
        {
            Close(MessageDialogResult.Affirmative);
        }
    
        /// <summary>
        /// Handles the button click events for the negative button.
        /// </summary>
        public void NegativeButtonClick()
        {
            Close(MessageDialogResult.Negative);
        }
    
        /// <summary>
        /// Handles the button click events for the first auxillary button.
        /// </summary>
        public void FirstAuxillaryButtonClick()
        {
            Close(MessageDialogResult.FirstAuxiliary);
        }
    
        /// <summary>
        /// Handles the button click events for the second auxillary button.
        /// </summary>
        public void SecondAuxillaryButtonClick()
        {
            Close(MessageDialogResult.SecondAuxiliary);
        }
        #endregion // Class Methods.
    
        #region Properties.
        /// <summary>
        /// Hold the dialog title.
        /// </summary>
        private string title;
        public string Title
        {
            get { return title; }
            set
            {
                if (title == value)
                    return;
                title = value;
                NotifyOfPropertyChange(() => Title);
            }
        }
    
        /// <summary>
        /// Hold the text for the dialog body.
        /// </summary>
        private string dialogBody;
        public string DialogBody
        {
            get { return dialogBody; }
            set
            {
                if (dialogBody == value)
                    return;
                dialogBody = value;
                NotifyOfPropertyChange(() => DialogBody);
            }
        }
    
        /// <summary>
        /// Sets the button styles to use.
        /// Default is 'OK' and 'Cancel'.
        /// </summary>
        private MessageDialogStyle messageDialogStyle =
            MessageDialogStyle.AffirmativeAndNegative;
        public MessageDialogStyle MessageDialogStyle
        {
            get { return messageDialogStyle; }
            set
            {
                if (messageDialogStyle == value)
                    return;
                messageDialogStyle = value;
                NotifyOfPropertyChange(() => MessageDialogStyle);
            }
        }
    
        /// <summary>
        /// The color sheme to use for the dialog.
        /// </summary>
        private SolidColorBrush background;
        public SolidColorBrush Background
        {
            get { return background; }
            set
            {
                if (background == value)
                    return;
                background = value;
                NotifyOfPropertyChange(() => Background);
            }
        }
    
        /// <summary>
        /// Affirmative button text. Default OK.
        /// </summary>
        private string affirmativeButtonText = "OK";
        public string AffirmativeButtonText
        {
            get { return affirmativeButtonText; }
            set
            {
                if (affirmativeButtonText == value)
                    return;
                affirmativeButtonText = value;
                NotifyOfPropertyChange(() => AffirmativeButtonText);
            }
        }
    
        /// <summary>
        /// Visibility for the default affirmative button.
        /// </summary>
        private Visibility affirmativeButtonVisibility = Visibility.Visible;
        public Visibility AffirmativeButtonVisibility
        {
            get { return affirmativeButtonVisibility = Visibility.Visible; }
            set
            {
                if (affirmativeButtonVisibility == value)
                    return;
                affirmativeButtonVisibility = value;
                NotifyOfPropertyChange(() => AffirmativeButtonVisibility);
            }
        }
    
        /// <summary>
        /// The negative button text to use.
        /// </summary>
        private string negativeButtonText = "Cancel";
        public string NegativeButtonText
        {
            get { return negativeButtonText; }
            set
            {
                if (negativeButtonText == value)
                    return;
                negativeButtonText = value;
                NotifyOfPropertyChange(() => NegativeButtonText);
            }
        }
    
        /// <summary>
        /// Visibility for the default negative button.
        /// </summary>
        private Visibility negativeButtonVisibility = Visibility.Visible;
        public Visibility NegativeButtonVisibility
        {
            get { return negativeButtonVisibility; }
            set
            {
                if (negativeButtonVisibility == value)
                    return;
                negativeButtonVisibility = value;
                NotifyOfPropertyChange(() => NegativeButtonVisibility);
            }
        }
    
        /// <summary>
        /// First auxillary button text.
        /// </summary>
        private string firstAuxillaryButtonText;
        public string FirstAuxillaryButtonText
        {
            get { return firstAuxillaryButtonText; }
            set
            {
                if (firstAuxillaryButtonText == value)
                    return;
                firstAuxillaryButtonText = value;
                NotifyOfPropertyChange(() => FirstAuxillaryButtonText);
            }
        }
    
        /// <summary>
        /// First auxillary button visibility.
        /// </summary>
        private Visibility firstAuxillaryButtonVisibility = Visibility.Collapsed;
        public Visibility FirstAuxillaryButtonVisibility
        {
            get { return firstAuxillaryButtonVisibility; }
            set
            {
                if (firstAuxillaryButtonVisibility == value)
                    return;
                firstAuxillaryButtonVisibility = value;
                NotifyOfPropertyChange(() => FirstAuxillaryButtonVisibility);
            }
        }
    
        /// <summary>
        /// Second auxillary button text.
        /// </summary>
        private string secondAuxiliaryButtonText;
        public string SecondAuxiliaryButtonText
        {
            get { return secondAuxiliaryButtonText; }
            set
            {
                if (secondAuxiliaryButtonText == value)
                    return;
                secondAuxiliaryButtonText = value;
                NotifyOfPropertyChange(() => SecondAuxiliaryButtonText);
            }
        }
    
        /// <summary>
        /// Second auxillary button visibility.
        /// </summary>
        private Visibility secondAuxillaryButtonVisibility = Visibility.Collapsed;
        public Visibility SecondAuxillaryButtonVisibility
        {
            get { return secondAuxillaryButtonVisibility; }
            set
            {
                if (secondAuxillaryButtonVisibility == value)
                    return;
                secondAuxillaryButtonVisibility = value;
                NotifyOfPropertyChange(() => SecondAuxillaryButtonVisibility);
            }
        }
        #endregion // Properties.
    }
    

    观点是

    <MahAppsDialogs:CustomDialog 
            x:Class="GambitFramework.Core.MessageBox.MessageBoxView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:Caliburn="http://www.caliburnproject.org"
            xmlns:MahApps="http://metro.mahapps.com/winfx/xaml/controls"
            xmlns:Local="clr-namespace:GambitFramework.Core.MessageBox"
            xmlns:Converters="clr-namespace:GambitFramework.Core.Converters;assembly=GambitFramework"
            xmlns:MahAppsDialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
            Title="{Binding Title}">
        <MahAppsDialogs:CustomDialog.Content>
            <TextBlock Text="{Binding DialogBody}"
                          Margin="0,5,0,0"
                          TextWrapping="Wrap"/>
        </MahAppsDialogs:CustomDialog.Content>
        <MahAppsDialogs:CustomDialog.DialogBottom>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="25*" />
                    <ColumnDefinition Width="50*" />
                    <ColumnDefinition Width="25*" />
                </Grid.ColumnDefinitions>
                <StackPanel Grid.Column="1"
                                Orientation="Horizontal" 
                                HorizontalAlignment="Right"
                                Margin="0,0,0,0">
                    <Button x:Name="AffirmativeButton" 
                              Content="{Binding AffirmativeButtonText}"
                              Visibility="{Binding AffirmativeButtonVisibility}"
                              Style="{StaticResource AccentedSquareButtonStyle}"
                              Caliburn:Message.Attach="[Event Click] = [Action AffirmativeButtonClick()]"
                              MinWidth="75"
                              Padding="15,0"
                              Margin="5,10,0,5"/>
                    <Button x:Name="NegativeButton" 
                              Content="{Binding NegativeButtonText}"
                              Visibility="{Binding NegativeButtonVisibility}" 
                              Caliburn:Message.Attach="[Event Click] = [Action NegativeButtonClick()]"
                              MinWidth="75"
                              Padding="15,0"
                              Margin="10,10,0,5"/>
                    <Button x:Name="FirstAuxiliaryButton" 
                              Content="{Binding FirstAuxillaryButtonText}"
                              Visibility="{Binding FirstAuxillaryButtonVisibility}"
                              Caliburn:Message.Attach="[Event Click] = [Action FirstAuxillaryButtonClick()]"
                              MinWidth="75"
                              Padding="15,0"
                              Margin="5,10,0,5"/>
                    <Button x:Name="SecondAuxiliaryButton" 
                              Content="{Binding SecondAuxiliaryButtonText}"
                              Visibility="{Binding SecondAuxillaryButtonVisibility}"
                              Caliburn:Message.Attach="[Event Click] = [Action SecondAuxillaryButtonClick()]"
                              MinWidth="75"
                              Padding="15,0"
                              Margin="5,10,0,5"/>
                </StackPanel>
            </Grid>
        </MahAppsDialogs:CustomDialog.DialogBottom>
    </MahAppsDialogs:CustomDialog>
    

    这个视图后面有一个空代码。然后可以按如下方式使用此代码

    MessageBoxSettings settings = new MessageBoxSettings()
    {
        MessageDialogStyle = MessageDialogStyle.AffirmativeAndNegative,
        MetroColorDialogScheme = MetroDialogColorScheme.Accented,
        AffirmativeButtonText = "Delete",
        NegativeButtonText = "Cancel"
    };
    string message = String.Format(
        "Are you sure you want to delete back test \"{0}\" {1}",
        SelectedBackTest.Name,
        SelectedBackTest.LastRun == null ? 
            String.Empty : 
            String.Format("which was late run on {0:G}?", SelectedBackTest.LastRun));
    MessageDialogResult r = await dialogManager
        .ShowDialog<MessageDialogResult>(
            new MessageBoxViewModel("Confirm Delete", message, settings));
    if (r == MessageDialogResult.Affirmative)
    {
        ...
    }
    

    我希望这会有所帮助。

    【讨论】:

    • 非常感谢您提供一套完整的参考代码。确实可以帮助我解决当前的问题。 :)
    【解决方案2】:

    接受的答案需要一些额外的库和大量荒谬的代码。 这是我在等待对话框完成时所做的,仅使用 MahApps。

    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 Win32 = Microsoft.Win32;
    using Wpf = System.Windows;
    using SysCompMod = System.ComponentModel;
            [...]
            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( SysThread.CancellationTokenSource tokenSource = new SysThread.CancellationTokenSource() )
            {
                metroDialogSettings.CancellationToken = tokenSource.Token;
                SysTasks.Task<MahDlg.MessageDialogResult> task = MahDlg.DialogManager.ShowMessageAsync( parentMetroWindow, title, message, mahStyle, metroDialogSettings );
                // ReSharper disable once AccessToDisposedClosure
                SysCompMod.CancelEventHandler cancelEventHandler = (s, e) => tokenSource.Cancel();
                parentMetroWindow.Closing += cancelEventHandler;
                while( !(task.IsCompleted || task.IsCanceled || task.IsFaulted) )
                    Wpf.Application.Current.Dispatcher.Invoke( WpfThread.DispatcherPriority.Background, new Action( delegate { } ) );
                parentMetroWindow.Closing -= cancelEventHandler;
                return responseFromMahAppsMessageDialogResult( type, task.Result );
            }
    

    cancelEventHandler 是必要的,以防用户在模式对话框打开时尝试通过任务栏关闭您的主窗口。

    【讨论】:

      猜你喜欢
      • 2017-06-02
      • 2019-06-22
      • 2012-10-28
      • 2020-02-10
      • 2017-02-03
      • 2019-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多