Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从WPF中的可视树中分离_C#_Wpf_Xaml_Visualtreehelper_Inlineuicontainer - Fatal编程技术网

C# 如何从WPF中的可视树中分离

C# 如何从WPF中的可视树中分离,c#,wpf,xaml,visualtreehelper,inlineuicontainer,C#,Wpf,Xaml,Visualtreehelper,Inlineuicontainer,我正试图从InlineUIContainer中正确删除UIElement,以便在另一个面板中使用它,但程序不断崩溃,并显示以下消息:“指定的Visual已是另一个Visual的子项或CompositionTarget的根。” 我创建了一个小应用程序来说明我的痛苦。在这个程序中,一旦Randy的按钮被他的女朋友杀死\删除,他仍然不会离开他的父母,我发现他的父母是UIElementIsland。然后,任何将Randy添加为其他任何事物的子对象的尝试都会导致应用程序崩溃(启示录按钮证明了我的观点:)。

我正试图从
InlineUIContainer
中正确删除
UIElement
,以便在另一个面板中使用它,但程序不断崩溃,并显示以下消息:“指定的Visual已是另一个Visual的子项或CompositionTarget的根。”

我创建了一个小应用程序来说明我的痛苦。在这个程序中,一旦Randy的按钮被他的女朋友杀死\删除,他仍然不会离开他的父母,我发现他的父母是
UIElementIsland
。然后,任何将Randy添加为其他任何事物的子对象的尝试都会导致应用程序崩溃(启示录按钮证明了我的观点:)。在删除Randy之前\之后,您可以单击查看Randy的父母,注意到他小时候一直处于
UIElementIsland
的管理之下,如果他与外界疏远,那么整个问题\启示录应该可以避免

这是一个有趣的应用程序,所以复制和编译,即使只是为了好玩!如有任何帮助/想法,将不胜感激

C部分:

现在你可以适当地杀死兰迪,并将他添加到UIElement天堂(在
StackPanel
):


谢谢大家。

这很有趣,但也很吵。如果你的演示很短,你会得到更快的答案

您可以简单地隐藏/显示它,而不是删除/添加视觉效果:

void deleteRandy_Click(object sender, RoutedEventArgs e) =>
    randy.Visibility = Visibility.Hidden;

void end_Click(object sender, RoutedEventArgs e) =>
    randy.Visibility = Visibility.Visible;

这样,您就不会以不可恢复的方式玩可视化树了。如果确实要删除UI元素,然后添加新的元素,则可以使用MVVM+数据模板或
x:Shared=False
资源删除可视化父元素似乎没有帮助:

private void end_Click(object sender, RoutedEventArgs e)
{
    IDisposable disp = VisualTreeHelper.GetParent(randy) as IDisposable;
    if (disp != null)
        disp.Dispose();

    DependencyObject parent = VisualTreeHelper.GetParent(randy);
    if (parent == null)
        MessageBox.Show("No parent");

    // If randy is removed properly, this would not crash the application.
    StackPanel s = new StackPanel();
    s.Children.Add(randy);
}
因此,您可以创建一个新的
按钮

public MainWindow()
{
    InitializeComponent();
    randy_container.Child = CreateRandyButton();
}

private void end_Click(object sender, RoutedEventArgs e)
{
    StackPanel s = new StackPanel();
    s.Children.Add(CreateRandyButton());
}

private Button CreateRandyButton()
{
    Button button = new Button { Name = "randy", Content = "I am a Randy, the button", ToolTip = "Meet Randy" };
    button.Click += randy_Click;
    return button;
}

…或者按照@Sinatr的建议将其隐藏。

我找到了一个解决方法,以防父对象仍然是
UIElementIsland
。由于它实现了
IDisposable
,因此可以通过以下方式清除其子项:

var parent = VisualTreeHelper.GetParent(element);
if (parent is IDisposable uiElementIsland)
{
   uiElementIsland.Dispose();
}

这不太好,但很管用。

“给它加点调料,让它变得有趣”在这里是弄巧成拙的。我认为您还必须从其父容器(即段落)中删除InlineUiContainer。我不知道为什么,但我的代码中有一个扩展方法可以做到这一点,因为我在几个月前遇到了同样的问题。下次我会赔礼道歉的。谢谢你,克莱门斯没用。刚才在@LennartNote处尝试过,您仍然可以编辑您的问题…是的,它仍然崩溃,但消息已更改为“指定的元素已经是另一个元素的逻辑子元素。请先断开它。”。我将看看如何解决这样做时它不会崩溃的问题:s.Children.Add(CreateRandyButton());嘿干得好!!!我从
InlineUIContainer
派生,并调用
removelogicchild()
。以及您关于
Dispose()
的建议。它成功了。谢谢!听起来不错,但这只是一个演示。我想使用richtextbox中的逻辑。
void deleteRandy_Click(object sender, RoutedEventArgs e) =>
    randy.Visibility = Visibility.Hidden;

void end_Click(object sender, RoutedEventArgs e) =>
    randy.Visibility = Visibility.Visible;
private void end_Click(object sender, RoutedEventArgs e)
{
    IDisposable disp = VisualTreeHelper.GetParent(randy) as IDisposable;
    if (disp != null)
        disp.Dispose();

    DependencyObject parent = VisualTreeHelper.GetParent(randy);
    if (parent == null)
        MessageBox.Show("No parent");

    // If randy is removed properly, this would not crash the application.
    StackPanel s = new StackPanel();
    s.Children.Add(randy);
}
public MainWindow()
{
    InitializeComponent();
    randy_container.Child = CreateRandyButton();
}

private void end_Click(object sender, RoutedEventArgs e)
{
    StackPanel s = new StackPanel();
    s.Children.Add(CreateRandyButton());
}

private Button CreateRandyButton()
{
    Button button = new Button { Name = "randy", Content = "I am a Randy, the button", ToolTip = "Meet Randy" };
    button.Click += randy_Click;
    return button;
}
var parent = VisualTreeHelper.GetParent(element);
if (parent is IDisposable uiElementIsland)
{
   uiElementIsland.Dispose();
}