WPF中的自定义模态窗口?

3

我有一个WPF应用程序,希望创建一个具有模态行为的自定义弹出窗口。我已经能够使用等效于“DoEvents”的方法来解决问题,但是是否有更好的方法?以下是我目前的代码:

    private void ShowModalHost(FrameworkElement element)
    {
        //Create new modal host
        var host = new ModalHost(element);

        //Lock out UI with blur
        WindowSurface.Effect = new BlurEffect();
        ModalSurface.IsHitTestVisible = true;

        //Display control in modal surface
        ModalSurface.Children.Add(host);

        //Block until ModalHost is done
        while (ModalSurface.IsHitTestVisible)
        {
            DoEvents();
        }
    }

    private void DoEvents()
    {
        var frame = new DispatcherFrame();
        Dispatcher.BeginInvoke(DispatcherPriority.Background,
            new DispatcherOperationCallback(ExitFrame), frame);
        Dispatcher.PushFrame(frame);            
    }

    private object ExitFrame(object f)
    {
        ((DispatcherFrame)f).Continue = false;

        return null;
    }

    public void CloseModal()
    {
        //Remove any controls from the modal surface and make UI available again
        ModalSurface.Children.Clear();
        ModalSurface.IsHitTestVisible = false;
        WindowSurface.Effect = null;
    }

我的ModalHost是一个用户控件,旨在承载另一个具有动画和其他支持的元素。


是的,这就是应该的做法。除了你可能不需要 IsHitTestVisible 循环。 - Ray
循环是使ShowModalHost调用阻塞的原因;否则,在ModalHost关闭之前,它将返回到原始调用上下文。 - Dan Bryant
1个回答

2
我建议重新思考这个设计。
在某些情况下,使用 "DoEvents" 可能会导致一些非常奇怪的行为,因为您同时允许代码运行,同时又试图阻止它。
而不是使用弹出窗口,您可以考虑使用一个带有 ShowDialog 的窗口,并适当地进行样式设置。这将是实现模态行为的“标准”方法,WPF 让您很容易地将窗口样式设置得与弹出窗口完全相同...

谢谢,这个方法好多了。重新设计的窗口给了我想要的模态行为,同时还能保持灵活性以达到我想要的视觉效果。这让我可以摆脱 ModalSurface 及其相关的 hack 来阻止点击底层窗口的问题。 - Dan Bryant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接