예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }