How to move WPF UserControl from one window to another?

半城伤御伤魂 提交于 2020-01-13 11:10:55

问题


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

<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.

<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?


回答1:


Yes you can do this by removing the userControl from the Mainwindow and adding it as a logical child to any of the control in the PopupWin window.

UserControl.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 :

<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 :

<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 userControl and add it as a child to the 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.cs On Button_Click remove the userControl from the current MainWindow and pass it to PopupWin, in this case via constructor.

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

        var wind = new PopupWin(this.myUserControl);

        wind.ShowDialog();
    }

Note: The userControl instance should always be a logical child of only one element at anytime.




回答2:


If you make the UserControl a resource you can do this.

Example:

App.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:




回答3:


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.



来源:https://stackoverflow.com/questions/15891869/how-to-move-wpf-usercontrol-from-one-window-to-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!