2010-03-27 148 views
2

我有一个WPF应用程序,我想创建一个具有模态行为的自定义弹出窗口。我已经能够使用相当于“DoEvents”的解决方案来破解解决方案,但有没有更好的方法来做到这一点?这是我目前所拥有的:WPF中的自定义模态窗口?

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是一个用户控件,用于托管另一个具有动画和其他支持的元素。

+0

是的,这是应该如何完成的。除此之外,你可能不需要IsHitTestVisible循环。 – Ray

+0

该循环是什么使ShowModalHost呼叫阻塞;否则它将在ModalHost关闭之前返回到原始调用上下文。 –

回答

2

我会推荐重新考虑这个设计。

在某些情况下使用“DoEvents”会导致一些非常奇怪的行为,因为您允许代码在试图同时阻止的情况下运行。

除了使用弹出窗口外,还可以考虑使用带有ShowDialog的窗口,只需适当地设置它即可。这将是实现模态行为的“标准”方式,WPF让你设计一个窗口,使其看起来像一个弹出窗口,非常容易......

+0

谢谢,这效果更好。重新调整的窗口给了我想要的模态行为,并且我仍然可以灵活地获得我之后的视觉效果。这让我摆脱了ModalSurface及其关联的入侵,以阻止点击底层窗口。 –