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.
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...