指定的元素已经是另一个元素的逻辑子级。请先断开连接。

21

当我想将FrameworkElement附加到新窗口并发布为PNG文件时,就会出现错误。

所以我的想法是先移除父子链接,调用我的方法,然后使用以下代码重新添加子元素:

this.RemoveLogicalChild(element);
PublishFrameworkElement(element, stream);
this.AddLogicalChild(element);

但我收到了完全相同的错误...

我在这里在SO上看了很多关于这个错误的问题,但没有一个能回答我的问题。我错过了什么吗?

编辑:以下是对我起作用的代码:

var element = _GeneratedContent as FrameworkElement;
var ParentPanelCollection = (element.Parent as Panel).Children as UIElementCollection;
ParentPanelCollection.Clear();

FileStream stream = [...]

if (element != null)
{
    PublishFrameworkElement(element, stream);
    ParentPanelCollection.Add(element);
}
stream.Close();
4个回答

25
如果element是Panel(例如Grid)的子级,则必须从Panel的Children集合中将其删除。如果它被设置为ContentControlContent,则必须将该内容设置为null(或任何不是element的内容)。

设置为 null,是否也会断开事件? - Rauld
不,你还必须删除任何事件处理程序。 - Clemens
此外:如果您有一个名为BorderDecorator,您可以简单地将其Child=null - Markus Hütter

6

Guillaume,

你可以尝试在RemoveLogicalChild之后使用RemoveVisualChild方法:

this.RemoveLogicalChild(element);
this.RemoveVisualChild(element);
PublishFrameworkElement(element, stream);

希望这有所帮助,Piotr。

1
我之前尝试过,但是出现了这个错误:"指定的 Visual 不是此 Visual 的子级。" - Guillaume Slashy
Guillaume,我发布的代码没有抛出这个异常,所以也许你在不同的上下文中使用它。请发布更多的代码并详细描述您的问题,这样我们可以更容易地帮助您。 - Piotr Justyna
此外,在您的情况下,“this”是什么? - Piotr Justyna

3

虽然这个问题比较老,但我没有运气找到其他答案,所以我写了一个扩展方法来从父元素中移除该项。

public static class FrameworkElementHelper
{
    public static void RemoveFromParent(this FrameworkElement item)
    {
        if (item != null)
        {
            var parentItemsControl = (ItemsControl)item.Parent;
            if (parentItemsControl != null)
            {
                parentItemsControl.Items.Remove(item as UIElement);
            }
        }
    }
}

使用说明:将(ItemsControl)更改为您拥有的(Element parent)类型,例如如果您有<StackPanel />,则将其更改为(StackPanel),并在(StackPanel)的情况下将Items.Remove更改为Children.Remove。如有需要,请应用适合您选择的Element parent的任何更改。 - RAMM-HDR

1
我遇到了类似但略有不同的问题,但是收到了相同的错误消息。我通过创建一个继承类并调用RemoveLogicalChild(因为这是一个受保护的方法)来实现了一个解决方法。
 public partial class PopupWindow : Window
{
    public PopupWindow()
    {
        InitializeComponent();
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        this.RemoveLogicalChild(this.Content);    // since protected method
    }
}

对我来说起作用了。我制作了一个简单的示例,您可以在此处查看。

http://wpfgrid.blogspot.com/2013/01/wpf-error-specified-element-is-already.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接