/// <summary>
        /// Sets up the connection between view and viewModel, shows the view as a metro dialog,
        /// calls <paramref name="onShown"/> and waits for the dialog to be closed.
        /// </summary>
        public static async Task <T> ShowDialogAsync <T>(this MetroWindow window, CloseableViewModel <T> viewModel,
                                                         BaseMetroDialog view, Action onShown = null)
        {
            view.DataContext = viewModel;

            // Undefault buttons not in the dialog as they would be pressed instead of a dialog button on enter.
            var oldDefaults = window.FindVisualChildren <Button>().Where(b => b.IsDefault).ToList();

            oldDefaults.ForEach(b => b.IsDefault = false);
            // Clear keyboard focus as they focused element is pressed instead of a dialog element on enter.
            var oldFocus = Keyboard.FocusedElement;

            Keyboard.ClearFocus();

            await window.ShowMetroDialogAsync(view, new MetroDialogSettings { AnimateShow = false });

            DialogParticipation.SetRegister(view, viewModel);
            onShown?.Invoke();

            var result = await viewModel.WaitForCloseAsync();

            await window.HideMetroDialogAsync(view, new MetroDialogSettings { AnimateHide = false });

            DialogParticipation.SetRegister(view, null);

            // Restore IsDefault and keyboard focus.
            oldDefaults.ForEach(b => b.IsDefault = true);
            Keyboard.Focus(oldFocus);

            return(result);
        }
        /// <summary>
        /// Sets up the connection between view and viewModel, shows the view as a metro dialog,
        /// calls <paramref name="onShown"/> and waits for the dialog to be closed.
        /// </summary>
        public static async Task <T> ShowDialogAsync <T>(this MetroWindow window, CloseableViewModel <T> viewModel,
                                                         BaseMetroDialog view, Action onShown = null)
        {
            view.DataContext = viewModel;

            // Undefault buttons not in the dialog as they would be pressed instead of a dialog button on enter.
            var oldDefaults = window.FindVisualChildren <Button>().Where(b => b.IsDefault).ToList();

            oldDefaults.ForEach(b => b.IsDefault = false);
            // Save old keyboard focus.
            var oldFocus = Keyboard.FocusedElement;

            await window.ShowMetroDialogAsync(view, new MetroDialogSettings { AnimateShow = false });

            DialogParticipation.SetRegister(view, viewModel);
            // Focus the first focusable element in the view
            var element = view.FindVisualChildren <UIElement>().FirstOrDefault(e => e.Focusable);

            element?.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => Keyboard.Focus(element)));
            onShown?.Invoke();

            var result = await viewModel.WaitForCloseAsync();

            await window.HideMetroDialogAsync(view, new MetroDialogSettings { AnimateHide = false });

            DialogParticipation.SetRegister(view, null);

            // Restore IsDefault and keyboard focus.
            oldDefaults.ForEach(b => b.IsDefault = true);
            Keyboard.Focus(oldFocus);

            return(result);
        }
Example #3
0
        protected static MetroWindow GetMetroWindow(object context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (!DialogParticipation.IsRegistered(context))
            {
                throw new InvalidOperationException(
                          "Context is not registered. Consider using DialogParticipation.Register in XAML to bind in the DataContext.");
            }

            var association = DialogParticipation.GetAssociation(context);
            var metroWindow = association.Invoke(() => Window.GetWindow(association) as MetroWindow);

            if (metroWindow == null)
            {
                throw new InvalidOperationException("Control is not inside a MetroWindow.");
            }
            return(metroWindow);
        }
        private static async Task <MetroWindow> GetMetroWindowAsync(object context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (!DialogParticipation.IsRegistered(context))
            {
                var tcs = new TaskCompletionSource <DependencyObject>();
                ContextRegistrationChangedEventHandler handler = null;
                handler = (c, o) =>
                {
                    if (c == context)
                    {
                        DialogParticipation.ContextRegistrationChanged -= handler;
                        tcs.TrySetResult(o);
                    }
                };
                DialogParticipation.ContextRegistrationChanged += handler;

                var task = tcs.Task;
                if (await task.WithTimeout(TimeSpan.FromSeconds(2)))
                {
                    return(AssociationToWindow(task.Result));
                }
                else
                {
                    throw new InvalidOperationException(
                              "Context is not registered. Consider using DialogParticipation.Register in XAML to bind in the DataContext.");
                }
            }

            var association = DialogParticipation.GetAssociation(context);

            return(AssociationToWindow(association));
        }