WPF:弹出现有用户控件

WPF: Popout existing usercontrol

想象下一种情况:我的应用程序 window 里面有几个用户控件。它们过去是并排显示的,但现在我想在弹出窗口中显示其中一个 window。不在 Popup 控件中,而是新的 Window。

参见示例 XAML:

<Window x:Class="WpfApplication3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpfApplication3="clr-namespace:WpfApplication3"
    Title="MainWindow"
    Height="350"
    Width="525">
<Grid>
    <wpfApplication3:UserControl1 Visibility="Hidden"
                                  x:Name="UserControl1"/>
    <Button Click="ButtonBase_OnClick"
            Width="100"
            Height="60">open window</Button>
</Grid>

在后面的代码中,我需要从当前 Window 中分离用户控件并分配给新的:

  private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        var parent = VisualTreeHelper.GetParent(UserControl1);
        if (parent != null)
        {
            parent.RemoveChild(UserControl1);
        }

        var w = new Window
        {
            Content = UserControl1,
            Title = "sample",
            SizeToContent = SizeToContent.WidthAndHeight,
            ResizeMode = ResizeMode.CanResize

        };
        w.Show();
    }

并且在调用 w.Show() 之后,我总是得到空白 window。

如果在按钮点击处理程序中更改

内容 = UserControl1

内容 = new UserControl1()

我也会得到正确的内容。 但我不能使用这种方式,因为我想在弹出和弹出事件期间保持我的用户控件状态。 那么,如何在不重新创建新的 window 现有用户控件的情况下显示它呢?

有人问过类似的问题here 这给出了一个非常详细的答案。

快速回答是您必须从主 window 中删除控件,然后将其添加到弹出窗口 window。

我不确定您是如何在 DependencyObject as that method doesn't seem to exist. Note that VisualTreeHelper.GetParent returns DependencyObject 上调用 RemoveChild 的,因此,您发布的代码不应编译,除非您在某处定义了 RemoveChild 的扩展方法。

在你的情况下,你想要做的是将你的父对象转换为 Grid 或 Panel,然后从子对象中删除 UserControl 属性,然后将你的 UserControl 设置为你的 window.

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    Grid parent = VisualTreeHelper.GetParent(UserControl1) as Grid;
    if (parent != null)
    {
        parent.Children.Remove(UserControl1);
    }

    var w = new Window
    {
        Content = UserControl1,
        Title = "sample",
        SizeToContent = SizeToContent.WidthAndHeight,
        ResizeMode = ResizeMode.CanResize

    };
    w.Show();
}