views:

186

answers:

1

I have a WPF application where I'd like to create a custom pop-up that has modal behavior. I've been able to hack up a solution using an equivalent to 'DoEvents', but is there a better way to do this? Here is what I have currently:

    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;
    }

Where my ModalHost is a user control designed to host another element with animation and other support.

+1  A: 

I would recommend rethinking this design.

Using "DoEvents" can cause some very odd behavior in certain situations, since you're allowing code to run, while trying to block it at the same time.

Instead of using a Popup, you could consider using a Window with ShowDialog, and just style it appropriately. This would be the "standard" way to implement modal behavior, and WPF lets you style a window to look exactly like a popup pretty easily...

Reed Copsey
Thanks, that works much better. A restyled window gives me the modal behavior I want and I still have the flexibility to get the visual effect I'm after. This lets me get rid of the ModalSurface and its associated hack to block clicking on the underlying Window, as well.
Dan Bryant