断开与 BlockUIContainer 的控制

Disconnecting control from BlockUIContainer

我需要在 FlowDocument 中临时显示一些 UIElement。我将它封装在 BlockUIContainer 中,但是当我不再需要它时,我看不到它如何与 BlockUICO​​ntainer 断开连接。没有 Remove 方法。下面的代码显示 - 它以异常结束

System.InvalidOperationException: 'Specified element is already the logical child of another element. Disconnect it first.'

例如

<Grid x:Name="Grid1">
  <RichTextBox x:Name="rtb"/>
</Grid>

public MainWindow() {
    InitializeComponent();

    Loaded += MainWindow_Loaded;
}

private void MainWindow_Loaded(object sender, RoutedEventArgs e) {
    var c2 = new WrapPanel();
    // Imagine adding lots of controls into c2 ...
    rtb.Document.Blocks.Add(new BlockUIContainer(c2));

    var bc = (BlockUIContainer)c2.Parent;
    ((FlowDocument)(bc).Parent).Blocks.Remove(bc);

    Grid1.Children.Add(c2); // Exception. Here I want to move that c2 elsewhere in logical tree but I don't know how to disconnect it
        }

当然,我可以重新创建 c2,但这并不好。或者我看到我可以调用内部 RemoveLogicalChild 但这也看起来很老套。 WPF 如何期望这是完成的?

谢谢

您必须正确断开元素及其子元素与可视化树的连接。 XAML 规则不允许在树中多次引用 UIElemnts。不跟踪引用,这意味着没有单个实例的别名。每个 UIElement 元素必须是一个单独的实例。

您可以决定创建新实例或正确清除关联:

var c2 = new WrapPanel();

rtb.Document.Blocks.Add(new BlockUIContainer(c2));

var bc = (BlockUIContainer) c2.Parent;
rtb.Document.Blocks.Remove(bc);

// Remove parent association
bc.Child = null;

// Update the subtree/template association
c2.UpdateLayout();

Grid1.Children.Add(c2);