在WPF中断开元素与任何/未指定的父容器的连接

我有一个控件是另一个控件的子控件(因为所有非root控件/元素都在WPF中)。 如果我想将控件移动到另一个容器,我必须先将它与当前容器断开连接(否则抛出exception)。

如果我知道父母是什么,那么我可以将其从子集合,内容或其他任何内容中删除。 但是,如果我不知道父容器的类型是什么 – 如何删除子控件呢?

在下面的代码示例中:如何在不知道父类型(Panel,GroupBox …)的情况下将“sp1”移动到另一个容器?

// Add the child object "sp1" to a container (of any type). StackPanel sp1 = new StackPanel(); SomeParentControl.Children.Add(sp1); // Somewhere else in the code. I still have a reference to "sp1" but now I don't know what container it is in. I just want to move the "sp1" object to another parent container. AnotherParentControl.Content = sp1; // Generates exception: "Must disconnect specified child from current parent Visual before attaching to new parent Visual." 

理想情况下,我只想写下这样的内容:

 sp1.Parent.RemoveChild(sp1); 

但我还没有找到类似的东西。

您可以使用扩展方法编写一个辅助类:

 public static class RemoveChildHelper { public static void RemoveChild(this DependencyObject parent, UIElement child) { var panel = parent as Panel; if (panel != null) { panel.Children.Remove(child); return; } var decorator = parent as Decorator; if (decorator != null) { if (decorator.Child == child) { decorator.Child = null; } return; } var contentPresenter = parent as ContentPresenter; if (contentPresenter != null) { if (contentPresenter.Content == child) { contentPresenter.Content = null; } return; } var contentControl = parent as ContentControl; if (contentControl != null) { if (contentControl.Content == child) { contentControl.Content = null; } return; } // maybe more } } 

新:

我建议使用基类而不是列出的所有其他类。 试试这个代码,这3个类是最符合您需求的用例。 据我了解,它与previos ^)几乎相同

  var parent = VisualTreeHelper.GetParent(child); var parentAsPanel = parent as Panel; if (parentAsPanel != null) { parentAsPanel.Children.Remove(child); } var parentAsContentControl = parent as ContentControl; if (parentAsContentControl != null) { parentAsContentControl.Content = null; } var parentAsDecorator = parent as Decorator; if (parentAsDecorator != null) { parentAsDecorator.Child = null; } 

OLD:据我记忆,你可以使用Visual type作为父类型,并尝试调用RemoveVisualChild方法。