如何将 WPF UserControl 从一个窗口移动到另一个窗口?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15891869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:31:59  来源:igfitidea点击:

How to move WPF UserControl from one window to another?

c#wpfuser-controlswindow

提问by Eternal21

Let's say I have a UserControl called MyVideoControl located in MainWindow.xaml:

假设我在 MainWindow.xaml 中有一个名为 MyVideoControl 的 UserControl:

<Window Name="_mainWindow">
    <Grid>
        <MyVideoControl Name="_localVideo"/>
    </Grid>
</Window>

Now a user clicks a button and I want the UserControl to float on top of the MainWindow.xaml, inside a newly created window called PopUp.xaml.

现在用户单击一个按钮,我希望 UserControl 浮动在 MainWindow.xaml 之上,在一个名为 PopUp.xaml 的新创建窗口内。

<Window Name="_popUpWindow">
    <Grid>
        <MyVideoControl Name="_localVideo"/>
    </Grid>
</Window>

How do I accomplish this, so the entire object gets moved? Currently I use XAML to declaratively place MyVideoControl inside my windows, but I'm guessing I'll need to do everything programatically?

我如何完成此操作,以便移动整个对象?目前我使用 XAML 以声明方式将 MyVideoControl 放置在我的窗口中,但我猜我需要以编程方式完成所有操作?

回答by jacob aloysious

Yes you can do this by removing the userControlfrom the Mainwindowand adding it as a logical child to any of the control in the PopupWinwindow.

是的,你可以通过删除做到这一点userControlMainwindow并将其添加为逻辑孩子任何的控件的PopupWin窗口。

enter image description here

在此处输入图片说明

UserControl.xaml:

用户控件.xaml:

<UserControl x:Class="WpfApplication1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="100">
    <Grid>
        <TextBox x:Name="txtBlock1" Text="hai"/>
    </Grid>
</UserControl>

MainWindow.xaml :

主窗口.xaml :

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication1="clr-namespace:WpfApplication1" Title="MainWindow" Height="550" Width="555">
    <Grid>
        <StackPanel x:Name="mainPanel" Orientation="Vertical ">
            <Button Content="Button" Height="23" Name="button1" Width="75" Click="button1_Click" />
            <WpfApplication1:UserControl1 x:Name="myUserControl" />
        </StackPanel>
    </Grid>
</Window>

PopupWin.xaml :

弹出窗口.xaml :

<Window x:Class="WpfApplication1.PopupWin"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="PopupWin" Height="300" Width="300">

    <StackPanel x:Name="mainPanel"/>

</Window>

PopupWin.xaml.cs:Expose a new constructor to accept userControland add it as a child to the mainPanel

PopupWin.xaml.cs:公开一个新的构造函数以接受userControl并将其作为子项添加到mainPanel

public partial class PopupWin : Window
{
    public PopupWin()
    {
        InitializeComponent();
    }

    private UserControl control;

    public PopupWin(UserControl control)
        : this()
    {
        this.control = control;

        this.mainPanel.Children.Add(this.control);
    }
}

MainWindow.xaml.csOn Button_Click remove the userControl from the current MainWindowand pass it to PopupWin, in this case via constructor.

MainWindow.xaml.cs在 Button_Click 上从当前删除 userControlMainWindow并将其传递给PopupWin,在这种情况下通过构造函数。

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        this.mainPanel.Children.Remove(this.myUserControl);

        var wind = new PopupWin(this.myUserControl);

        wind.ShowDialog();
    }

Note:The userControlinstance should always be a logical child of only oneelement at anytime.

注意:userControl实例one在任何时候都应该始终是唯一元素的逻辑子元素。

回答by sa_ddam213

If you make the UserControla resource you can do this.

如果你制作UserControl一个资源,你可以做到这一点。

Example:

例子:

App.Xaml

应用程序.Xaml

<Application x:Class="WpfApplication10.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ContentControl x:Key="sharedContent">
            <Label Content="StackOverFlow" />
        </ContentControl>
    </Application.Resources>
</Application>

MainWindow

主窗口

<Window x:Class="WpfApplication10.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="325" Width="422" Name="UI">

    <StackPanel>
        <Button Content="Open PopUp" Click="Button_Click" />
        <ContentControl Content="{DynamicResource sharedContent}" />
    </StackPanel>
</Window>

PopUp Window

弹出窗口

<Window x:Class="WpfApplication10.PopupWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="PopupWindow" Height="300" Width="300" xmlns:my="clr-namespace:WpfApplication10">
    <Grid>
        <ContentControl Content="{DynamicResource sharedContent}" />
    </Grid>
</Window>

Result:

结果:

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明

回答by Chutes

Another way this can be accomplished, using a dynamic layout...

使用动态布局可以实现的另一种方法......

 public partial class MainWindow : Window
{
    public Button ControlToMove { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        //create button
        ControlToMove = new Button();

        //add text to button
        ControlToMove.Content = "Click to move me to pop up window";

        //add a new routed event to the buttons click property
        ControlToMove.Click += new RoutedEventHandler(MoveControlToPopUp);

        //add control to the layout grid
        MainGrid.Children.Add(ControlToMove);
    }

    //This method moves the button to a popup window
    private void MoveControlToPopUp(object sender, RoutedEventArgs e)
    {
        //get the name of the control from sender
        var control = sender as Button;
        var controlName = control.Name;

        //checks to see if this is the control we want moved
        //if its not, method exits
        if (controlName != ControlToMove.Name) return;

        //create copy of the control
        var copiedControl = control;

        //remove control from existing window
        MainGrid.Children.Remove(control);

        //create pop up window
        var popUpWindow = new PopUpWindow(copiedControl);
        popUpWindow.Show();
    }
}

public class PopUpWindow : Window
{
    public Grid Layout { get; set; }
    public PopUpWindow(Button button)
    {
        //create a grid for the new window
        Layout = new Grid();

        //add control to grid
        Layout.Children.Add(button);

        //add grid to window
        this.AddChild(Layout);
    }
}

}

}

The only thing I didn't do there was adding the capability to move the button back to main window when it is clicked in the popup window.

我唯一没有做的就是添加在弹出窗口中单击按钮时将按钮移回主窗口的功能。