指定的元素已经是另一个元素的逻辑子元素。

3
这个问题与以下主题相关。 Prism RegionAdapter - Removing then Adding View 管理员删除了我在该主题下的帖子,说它已经得到解答,但我需要另起一篇新帖。如果有人解决了这个问题,请告诉我。
我被删除的帖子是... 您是怎么解决 "指定元素已经是另一个元素的逻辑子级。请先断开连接。" 这个关闭事件错误的?我尝试了同样的方法,在关闭时从documentpane中移除dockablecontent, 但没有帮助,我仍然得到这个错误。一旦我移除了视图,然后稍后再次尝试以您添加的方式添加它,我就会得到这个错误。
请帮帮我,我不知道我错过了什么。我已经浪费了很多时间去解决它,但还没有任何进展。
以下是我正在使用的代码:
<ad:DockableContent ...
                    x:Name="viewRoot"
                    IsCloseable="True" HideOnClose="False"
                    Title="{Binding Title}">    
        <ContentControl Grid.Row="1" Content="{Binding View}"/>
    </Grid>
</ad:DockableContent>

它被用在这个里面:

<ad:DockingManager x:Name="DockingManagerControl" Grid.Column="1">
                <ad:ResizingPanel x:Name="MainResizingPanel" ResizeWidth="*" ResizeHeight="*" Orientation="Horizontal">
                    <ad:DockablePane ad:ResizingPanel.ResizeWidth="0.25*" prism:RegionManager.RegionName="ProjectBrowserRegion"/>
                    <ad:ResizingPanel x:Name="PespectiveResizingPanel" ResizeWidth="0.75*" ResizeHeight="*" Orientation="Horizontal">
                        <ad:DocumentPane x:Name="DockablePaneControl"/>
                    </ad:ResizingPanel>
                </ad:ResizingPanel>
            </ad:DockingManager>

查看内容绑定是来自独立dll的UI元素,因此我没有它们作为View / ViewModel对。所以我不能在这里使用ContentTemplate + DataContext方式。事情加载得很好,但是用户可以选择/取消选择这些视图。因此,如果视图已经打开了视图选择对话框,那么我会清除所有视图(从DockablePaneControl Items.Clear()中删除它),然后再次添加选定的视图(DockablePaneControl Items.Add()),然后我就会收到这个错误。


@jlafay,由于您在我的帖子末尾删除了“谢谢”,Stackoverflow已锁定了我的帐户,无法发布答案等。您是否投票反对或标记了我的问题?您能帮我吗?我有一段时间没有在这里活动了,但现在我无法在这里发布任何答案。 - Rajiv
抱歉,我没有对您的帖子进行投票、举报或其他任何操作。我只是提供了一次编辑。 - Jeff LaFay
1个回答

6
通常这是因为您试图将同一控件分配给两个不同的父级。
我经常在样式中看到这个问题,其中设置了包含控件的非模板属性,例如ContentControl.ContentDataGridColumn.Header 例如,如果您的样式设置了ContentControl.Content,并且您将两个ContentControls添加到窗口中,您将遇到此错误,因为该样式正在尝试将相同的控件分配到两个ContentControls的Content部分中。解决方法是设置一个模板样式,例如ContentControl.ContentTemplate而不是ContentControl.Content。我喜欢说这就像把同一个饼干给多个人吃-这根本行不通。你必须给他们每个人饼干切割器(模板),这样他们就可以自己制作。
事实上,我经常看到关于这个错误的问题,所以我写了一篇博客文章来解决它。

嗨,Rachel,感谢您的快速回复。是的,我正在使用ContentControl.Content属性来设置内容。我无法使用ContentTemplate + DataContext实现我的内容,因为内容作为整个FrameworkElement来自单独的dll。我在这里没有使用MVVM的奢侈, 请建议我如何解决这个问题。是否有一种方法可以使用ContentTemplate + DataContext完成它?请记住,我需要将整个UI元素托管在ContentControl中。 - Rajiv
@Rajiv 我需要看到你的源代码。点击问题上的“编辑”按钮,并添加导致错误的代码。我还给你发布的链接上的答案点了赞,并添加了一条评论说明为什么它是正确的。如果你的代码与链接帖子的代码相似,那么你可以尝试使用该解决方案来修复它。答案的链接是http://stackoverflow.com/questions/4993705/prism-regionadapter-removing-then-adding-view/4993910#4993910 - Rachel
@Rajiv 我需要看一下你用于添加/删除 UI 控件项的 C# 代码。我相当确定你之所以会出现错误,是因为你将同一个 UI 元素添加到了两个不同的控件中,这是不可能的。 - Rachel
是的,“View”这个底层UI项从未被重新创建。有一组视图注册表。因此,我尝试将其包装在Avalon DockableContent下,并尝试再次添加它。就像原始帖子(http://stackoverflow.com/questions/4993705/prism-regionadapter-removing-then-adding-view/8051884)所做的那样。基本上只有这一行代码… Items.Add(new DockableContent() {Content = view});每次都重复使用这个视图。我希望这解释清楚了。你现在明白我想要实现什么了吗? - Rajiv
@Rajiv 我猜想 view 已经被添加到了另一个 DockableContent,所以当你试图将其分配给第二个 DockableContent.Content 时出现了错误。除非我看到代码,否则我无法确定,但是我敢打赌如果你删除 Content = view,你就不会得到这个错误。要修复它,要么使 view 成为除 UI 元素之外的其他类型,并使用 DataTemplates 来告诉 WPF 如何绘制该类,要么确保在尝试将其添加到新元素之前从其旧 DockableContent 中删除 view - Rachel
已经有一段时间了,但我应该更新一下。我的区域适配器确实存在逻辑问题。Rachel上面的建议是正确的。 - Rajiv

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