PopupWrapper.Silverlight crashes when child view contains element with another Popup

Topics: Prism v2 - Silverlight 2
Mar 3, 2009 at 6:10 PM
If you use the PopupWrapper in silverlight and try to give it a view with anything that uses a popup internally (Combo box, Listbox, etc..) silverlight crashes. It looks like it's an issue with nested popups...

From what I'm reading, the basic solution is to insert the popup control into the visual tree (don't know what all that entails). I can't figure out either why it's not already being done (by the region manager, adapter, other, etc?), or where we need to change the silverlight PopupWrapper to accomplish this.

Here are some threads that talk about this issue. 

http://www.telerik.com/community/forums/silverlight/window/combobox-inside-dialog.aspx

http://silverlight.net/forums/p/32622/180376.aspx 

LOOKS LIKE THE WORKAROUND IS THIS: LayoutRoot.Children.Add(mypopup) BUTHOW TO IMPLEMENT?

Any thoughts? (asap if possible???)

Thanks,
Jason Jarrett


Mar 3, 2009 at 6:58 PM
I've got a hack that seems to work for now... but I can almost bet there's a more elegant solution.

In the PopupWrapper constructor I call into a hack helper method where we pull a Grid out of the root visual (using a little helper) and I have to remove all popup controls out of the tree, and re-add the new popup when it shows up.

I hope someone can suggest a more elegant solution...

public PopupWrapper()
{
this.container = new ContentControl();

this.popUp = new Popup();
this.popUp.Child = this.container;

HackPopupIntoVisualTree();
}


/// <summary>
/// This is to support an issue where a popup cannot contain another popup.
/// So a view cannot contain anything like a combobox/listbox/etc without this workaround.
/// </summary>
private void HackPopupIntoVisualTree()
{
var g = XamlExtensions.FindName((FrameworkElement)Application.Current.RootVisual, "PopupGridContainer") as Grid;

Debug.Assert(g != null, "The current shell does not have a <Grid x:Name=\"PopupGridContainer\"> defined. Cannot use the popup region adapter without this grid.");

var existingPopupsQuery = g.Children.Where(w => w.GetType() == typeof(Popup));

foreach (var item in existingPopupsQuery.ToArray())
g.Children.Remove(item);

Debug.Assert(existingPopupsQuery.Count() == 0);

g.Children.Insert(0, popUp);
}