【问题标题】:How to move WPF UserControl from one window to another?如何将 WPF UserControl 从一个窗口移动到另一个窗口?
【发布时间】:2013-04-09 01:35:08
【问题描述】:

假设我在 MainWindow.xaml 中有一个名为 MyVideoControl 的用户控件:

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

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

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

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

【问题讨论】:

  • 我认为这是不可能的。你在其他地方见过这个功能吗?我很确定所有控件都必须包含在一个(并且只有一个)窗口中。
  • 您可以简单地从人窗口中删除用户控件,并在用户单击按钮时将其添加到新窗口。
  • @Jras - 也许我不清楚。 在任何给定时间,该控件将包含在一个(并且只有一个)窗口中。所以在某一时刻它将是 MainWindow,但在另一时刻它将是 PopUpWindow。只有一个实例,但它会在两个窗口中移动。
  • @Eternal21 我对“浮动在 MainWindow.xaml 之上”的措辞感到困惑。在阅读它时,我想象控件物理地离开窗口并通过某种 wpf 转换浮动到新窗口。

标签: c# wpf user-controls window


【解决方案1】:

是的,您可以通过从Mainwindow 中删除userControl 并将其作为逻辑子项添加到PopupWin 窗口中的任何控件来实现。

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: 公开一个新的构造函数来接受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.cs 在 Button_Click 上,从当前 MainWindow 中移除 userControl,并将其传递给 PopupWin,在本例中是通过构造函数。

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

        var wind = new PopupWin(this.myUserControl);

        wind.ShowDialog();
    }

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

【讨论】:

  • 接受这个答案,因为它是在仍然能够使用 XAML 和不必求助于资源字典之间的一个很好的折衷方案,后面的代码很少。
【解决方案2】:

如果您将UserControl 设为资源,您可以这样做。

例子:

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>

主窗口

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

弹出窗口

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

结果:

【讨论】:

    【解决方案3】:

    另一种实现方式,使用动态布局...

     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);
        }
    }
    

    }

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

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      相关资源
      最近更新 更多