public async Task ShowOverlayAsync(IMediaViewModel mediaModel, bool allowClosing, CancellationToken ct) { if (mediaModel == null) { throw new ArgumentNullException(nameof(mediaModel)); } var WINDOW_HANDLE = new WindowInteropHelper(this).Handle; var PRIMARY_SCREEN = System.Windows.Forms.Screen.PrimaryScreen; IntPtr PREVIOUS_WINDOW_HANDLE = IntPtr.Zero; try { var CANCELATION_TOKEN_SOURCE = CreateOverlayLinkedTokenSource(ct); var CANCELATION_TOKEN = CANCELATION_TOKEN_SOURCE.Token; var CONTENT = await Dispatcher.InvokeAsync(() => { var CC = new ContentControl() { Content = mediaModel, ContentTemplate = FindResource("VIDEO_PLAYER_TEMPLATE") as DataTemplate, }; return(CC); }); PREVIOUS_WINDOW_HANDLE = GetForegroundWindow(); if (PREVIOUS_WINDOW_HANDLE == WINDOW_HANDLE) { PREVIOUS_WINDOW_HANDLE = IntPtr.Zero; } SWP SHOW_FLAGS = SWP.SWP_NOREDRAW | SWP.SWP_ASYNCWINDOWPOS; HWND SHOW_HWND = PREVIOUS_WINDOW_HANDLE != IntPtr.Zero ? (HWND)PREVIOUS_WINDOW_HANDLE : HWND.HWND_NOTOPMOST; SetWindowPos(WINDOW_HANDLE, SHOW_HWND, 0, 0, PRIMARY_SCREEN.Bounds.Width, PRIMARY_SCREEN.Bounds.Height, SHOW_FLAGS); if (await OVERLAY_LOCK.WaitAsync(TimeSpan.Zero) == true) { try { await ShowOverlayWithLockAsync(CONTENT, allowClosing, Timeout.InfiniteTimeSpan, CANCELATION_TOKEN); } catch { throw; } finally { OVERLAY_LOCK.Release(); } } else { var WAIT_HANDLE = new SemaphoreSlim(0, 1); var CONTENT_LOCK = new ContentLock() { Content = CONTENT, WaitHandle = WAIT_HANDLE }; OVERLAY_CONTENT_STACK.Push(CONTENT_LOCK); ct.Register(async() => { var NEW_STACK = OVERLAY_CONTENT_STACK.Where(o => o != CONTENT_LOCK); OVERLAY_CONTENT_STACK = new ConcurrentStack <ContentLock>(NEW_STACK); if (OVERLAY_CONTENT_STACK.TryPeek(out var CURRENT_LOCK)) { await Dispatcher.InvokeAsync(() => _OVERLAY_CONTENT_HOST.Content = CURRENT_LOCK.Content); } }); await Dispatcher.InvokeAsync(() => _OVERLAY_CONTENT_HOST.Content = CONTENT); await WAIT_HANDLE.WaitAsync(Timeout.InfiniteTimeSpan, CANCELATION_TOKEN); } } catch { throw; } finally { var INSERT_AFTER = PREVIOUS_WINDOW_HANDLE != IntPtr.Zero ? (HWND)PREVIOUS_WINDOW_HANDLE : HWND.HWND_NOTOPMOST; SetWindowPos(WINDOW_HANDLE, INSERT_AFTER, 0, 0, PRIMARY_SCREEN.WorkingArea.Width, PRIMARY_SCREEN.WorkingArea.Height, SWP.SWP_NOREDRAW | SWP.SWP_ASYNCWINDOWPOS); } }
public async Task <bool> ShowAcceptDialogAsync(string message, MessageDialogButtons buttons, CancellationToken ct) { if (string.IsNullOrWhiteSpace(message)) { throw new ArgumentNullException(nameof(message)); } ////create view model //var viewModel = CompositionService.GetExportedValue<IMessageDialogViewModel>(); //viewModel.Message = message; //viewModel.Buttons = buttons; ////create view on UI thread //var view = await Dispatcher.InvokeAsync(() => CompositionService.GetExportedValue<AcceptDialogView>()); ////set data context on UI thread //await Dispatcher.InvokeAsync(() => view.DataContext = viewModel); //return await ShowDialogInternalAsync(view, Timeout.InfiniteTimeSpan, ct) is true; bool result = false; //create view model var viewModel = CompositionService.GetExportedValue <MessageDialogViewModel>(); viewModel.Message = message; viewModel.Buttons = buttons; #region CREATE VIEWS //create view on UI thread var CONTENT = await Dispatcher.InvokeAsync(() => CompositionService.GetExportedValue <AcceptDialogViewEx>()); //set data context on UI thread await Dispatcher.InvokeAsync(() => CONTENT.DataContext = viewModel); #endregion var LINKED_CTS = CreateOverlayLinkedTokenSource(ct); var LINKED_CT = LINKED_CTS.Token; if (await OVERLAY_LOCK.WaitAsync(TimeSpan.Zero)) { try { viewModel.AcceptCommand = new SimpleCommand <object, object>((o) => true, (o) => { HideCurrentOverlay(false); result = true; }); viewModel.CancelCommand = new SimpleCommand <object, object>((o) => true, (o) => { HideCurrentOverlay(false); result = false; }); await ShowOverlayWithLockAsync(CONTENT, false, Timeout.InfiniteTimeSpan, LINKED_CT); } catch { throw; } finally { OVERLAY_LOCK.Release(); } } else { var WAIT_HANDLE = new SemaphoreSlim(0, 1); var CONTENT_LOCK = new ContentLock() { Content = CONTENT, WaitHandle = WAIT_HANDLE }; OVERLAY_CONTENT_STACK.Push(CONTENT_LOCK); viewModel.AcceptCommand = new SimpleCommand <object, object>((o) => true, (o) => { try { WAIT_HANDLE.Release(); } catch (SemaphoreFullException) { //happens sometimes when multiple calls to release are made } result = true; }); viewModel.CancelCommand = new SimpleCommand <object, object>((o) => true, (o) => { try { WAIT_HANDLE.Release(); } catch (SemaphoreFullException) { //happens sometimes when multiple calls to release are made } result = false; }); await Dispatcher.InvokeAsync(() => { _OVERLAY_CONTENT_HOST.Content = CONTENT; }); await WAIT_HANDLE.WaitAsync(Timeout.InfiniteTimeSpan, LINKED_CT); OVERLAY_CONTENT_STACK.TryPop(out _); if (OVERLAY_CONTENT_STACK.TryPeek(out var CURRENT_LOCK)) { await Dispatcher.InvokeAsync(() => _OVERLAY_CONTENT_HOST.Content = CURRENT_LOCK.Content); } } return(result); }