using MaterialDesignThemes.Wpf; using Prism.Ioc; using Prism.Mvvm; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Interop; using System.Windows.Threading; using System.Windows; namespace DM_Weight.util { internal class MaterialDialogService : DialogService { private readonly IContainerExtension _containerExtension; public MaterialDialogService(IContainerExtension containerExtension) : base(containerExtension) { _containerExtension = containerExtension; } public void ShowDialogHost(string name, IDialogParameters parameters, Action callback) => ShowDialogHost(name, null, parameters, callback); public void ShowDialogHost(string name, string dialogHostName, IDialogParameters parameters, Action callback) { if (parameters == null) parameters = new DialogParameters(); var content = _containerExtension.Resolve(name); if (!(content is FrameworkElement dialogContent)) { throw new NullReferenceException("A dialog's content must be a FrameworkElement"); } AutowireViewModel(dialogContent); if (!(dialogContent.DataContext is IDialogAware dialogAware)) { throw new ArgumentException("A dialog's ViewModel must implement IDialogAware interface"); } var openedEventHandler = new DialogOpenedEventHandler((sender, args) => { dialogAware.OnDialogOpened(parameters); }); var closedEventHandler = new DialogClosedEventHandler((sender, args) => { dialogAware.OnDialogClosed(); }); dialogAware.RequestClose += res => { if (DialogHost.IsDialogOpen(dialogHostName)) { callback(res); DialogHost.Close(dialogHostName); } }; var dispatcherFrame = new DispatcherFrame(); if (dialogHostName == null) { _ = DialogHost.Show(dialogContent, openedEventHandler, null, closedEventHandler) .ContinueWith(_ => dispatcherFrame.Continue = false); ; } else { _ = DialogHost.Show(dialogContent, dialogHostName, openedEventHandler, null, closedEventHandler) .ContinueWith(_ => dispatcherFrame.Continue = false); } try { // tell users we're going modal ComponentDispatcher.PushModal(); Dispatcher.PushFrame(dispatcherFrame); } finally { // tell users we're going non-modal ComponentDispatcher.PopModal(); } dialogAware.RequestClose -= callback; } private static void AutowireViewModel(object viewOrViewModel) { if (viewOrViewModel is FrameworkElement view && view.DataContext is null && ViewModelLocator.GetAutoWireViewModel(view) is null) { ViewModelLocator.SetAutoWireViewModel(view, true); } } public void ShowDialogHost(string name, IDialogParameters parameters, string dialogHostName) { var content = _containerExtension.Resolve(name); if (!(content is FrameworkElement dialogContent)) { throw new NullReferenceException("A dialog's content must be a FrameworkElement"); } AutowireViewModel(dialogContent); if (!(dialogContent.DataContext is IDialogAware dialogAware)) { throw new ArgumentException("A dialog's ViewModel must implement IDialogAware interface"); } var openedEventHandler = new DialogOpenedEventHandler((sender, args) => { dialogAware.OnDialogOpened(parameters); }); var closedEventHandler = new DialogClosedEventHandler((sender, args) => { dialogAware.OnDialogClosed(); }); dialogAware.RequestClose += res => { if (DialogHost.IsDialogOpen(dialogHostName)) { DialogHost.Close(dialogHostName); } }; var dispatcherFrame = new DispatcherFrame(); if (dialogHostName == null) { _ = DialogHost.Show(dialogContent, openedEventHandler, null, closedEventHandler) .ContinueWith(_ => dispatcherFrame.Continue = false); ; } else { _ = DialogHost.Show(dialogContent, dialogHostName, openedEventHandler, null, closedEventHandler) .ContinueWith(_ => dispatcherFrame.Continue = false); } try { // tell users we're going modal ComponentDispatcher.PushModal(); Dispatcher.PushFrame(dispatcherFrame); } finally { // tell users we're going non-modal ComponentDispatcher.PopModal(); } } } }