Showing a control on a popup twice blows up  
Author Message
Bill Henning





PostPosted: Windows Presentation Foundation (WPF), Showing a control on a popup twice blows up Top

Hi everyone,

I'm trying to show a popup over and over that reuses a child control but I get this exception on the second time of displaying the popup:

"Must disconnect specified child from current parent Visual before attaching to new parent Visual."

XAML is this in a Window:

<Button Click="button_Click">Click me</Button>

Codebehind is this:

---

private Button popupButton;

private void button_Click(object sender, RoutedEventArgs e) {
if (popupButton == null) {
popupButton = new Button();
popupButton.Content = "This button on a popup";
}

Popup popup = new Popup();
popup.Child = popupButton;
popup.PlacementTarget = this;
popup.PlacementRectangle = new Rect(0, 0, this.ActualWidth, this.ActualHeight - 18);
popup.Placement = PlacementMode.Bottom;
popup.StaysOpen = false;
popup.IsOpen = true; // Second time through get error here
popup.Closed += new EventHandler(popup_Closed);
}

private void popup_Closed(object sender, EventArgs e) {
Popup popup = (Popup)sender;
popup.Child = null;
popup.Closed -= new EventHandler(popup_Closed);
}

---

Clicking the "Click me" button create another button that says "This button on a popup" and displays it in a popup. When the popup closes, I try to remove the button from the parent popup by setting popup.Child = null; However the next time I display the popup, it blows up saying the button still has a parent.

Am I missing something here or is this a bug To repro, use the above code and click the "Click me" button twice. It will blow up on the second click.

Please help, I'm trying to learn how to reuse a control for multiple popups.

Thanks in advance!




Visual Studio 200843  
 
 
SerialSeb





PostPosted: Windows Presentation Foundation (WPF), Showing a control on a popup twice blows up Top

Hi,

You need to have the Popup open for the visual child to be set to null. When you set it to null when the popup is closed, it's former child is removed from the logical tree but not from the visual tree.

That said once a control is attached to a parent in a visual tree, it is usually unadvisable to try and move them around. Can't you achieve what you want with templates and databinding, and simply recreate for each popup



 
 
SerialSeb





PostPosted: Windows Presentation Foundation (WPF), Showing a control on a popup twice blows up Top

From msdn's documentation:

When content is added to a Popup control, the Popup control becomes the logical parent to the content. Similarly, the Popup content is considered to be the logical child of the Popup. The child content is not added to the visual tree that contains the Popup control. Instead, the child content is rendered in a separate window with its own visual tree when the IsOpen is set to true.

Hence why the popup.Child = null in theory doesnt remove the button from its parent's visual tree (although in reality as long as the popup is open it will be).



 
 
Bill Henning





PostPosted: Windows Presentation Foundation (WPF), Showing a control on a popup twice blows up Top

Well I have a complex control that I don't want to have to recreate each time the popup is displayed. There should be a way to do this. In Windows Forms you simply changed the Parent property and a control could be reused elsewhere. We should be able to do similar things in WPF. I can think of many scenarios where it's useful to be able to take a Control and "re-parent" it elsewhere.

 
 
SerialSeb





PostPosted: Windows Presentation Foundation (WPF), Showing a control on a popup twice blows up Top

You can go around this problem (I'd suggest filling it as a bug to Microsoft) by adding your button to a Panel, and clear the Panel instead of the popup when you want to reparent your control. Then it all works as expected:

    private Button popupButton;

    private void button_Click(object sender, RoutedEventArgs e)
    {
      if (popupButton == null)
      {
        popupButton = new Button();
        popupButton.Content = "This button on a popup";
      }

      Popup popup = new Popup();
      Grid grid = new Grid();
      grid.Children.Add(popupButton);
      popup.Child = grid;
      popup.PlacementTarget = this;
      popup.PlacementRectangle = new Rect(0, 0, this.ActualWidth, this.ActualHeight - 18);
      popup.Placement = PlacementMode.Bottom;
      popup.StaysOpen = false;
      popup.IsOpen = true; // Second time through get error here
      popup.Closed += new EventHandler(popup_Closed);
    }

    private void popup_Closed(object sender, EventArgs e)
    {
      Popup popup = (Popup)sender;
      ((Grid)popup.Child).Children.Clear();
      popup.Closed -= new EventHandler(popup_Closed);
    }


 
 
Bill Henning





PostPosted: Windows Presentation Foundation (WPF), Showing a control on a popup twice blows up Top

Good idea, thanks!