指定System.Windows.Forms.Form的Owner为System.Windows.Window

来源:互联网 发布:香港有哪些导演 知乎 编辑:程序博客网 时间:2024/04/30 04:18

这是一个很好玩的尝试,如何设定一个WinForm的Owner(所有者)是一个WPF的Window。

 

在WinForm项目中,设定一个Form的Owner,是通过Show或者ShowDialog中,指定参数IWin32Window owner来实现,或者指定Owner属性。

 

那我们如何指定一个WinForm的Owner是WPF的Window?

 

似乎我们没必要这么做,但考虑一下,如果我们有一个用WinForm创建的UserControl控件,它带有一些Form窗体作为对话框(用语设定属性或者确认输入等),我们希望在显示这些窗体的时候,它们的StartPosition是CenterParent的。假如WPF项目中某个Window使用了这样的一个WinForm控件,这个控件的对话框应该以这个Window为中心。

 

为了实现这个功能,我们可以使用NativeWindow。

 

Step:

  • 创建一个WPF项目,名称指定为SetFormOwnerToWindow
  • 在Solution Explore,添加新的项目到现有项目,类型Windows Forms Control Library,名称可使用默认的WindowsFormsControlLibrary1
    • 添加一个新窗体到该项目,名称可使用默认的Form1
    • 打开UserControl1设计视图,添加一个Button,双击此Button添加Click事件
    • 切换到Code View,使用以下代码替换原先的代码:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Linq;

using System.Text;

using System.Windows.Forms;

 

namespace WindowsFormsControlLibrary1 {

    public partial class UserControl1 : UserControl {

 

        public UserControl1() {

            InitializeComponent();

        }

 

        public NativeWindow Owner;

 

        private void button1_Click(object sender, EventArgs e) {

            if (Owner == null) {

                MessageBox.Show("Please specify _owner.");

                return;

            }

            Form1 form1 = new Form1();

            form1.StartPosition = FormStartPosition.CenterParent;

            form1.ShowDialog(Owner);

        }

 

    }

}

 

  • 在Solution Explorer选定SetFormOwnerToWindow,添加WindowsFormsControlLibrary1引用到WPF项目(通过References-->Add Reference --> Project --> Select WindowsFormsControlLibrary1
  • 打开MainWindow设计视图,用以下代码取代原来的代码:

<Window xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"  x:Class="SetFormOwnerToWindow.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:uc="clr-namespace:WindowsFormsControlLibrary1;assembly=WindowsFormsControlLibrary1"

        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">

    <Grid>

        <my:WindowsFormsHost Margin="42,40,0,0" Height="154" VerticalAlignment="Top" HorizontalAlignment="Left" Width="201">

            <uc:UserControl1 x:Name="uc1"></uc:UserControl1>

        </my:WindowsFormsHost>

        <Label Content="This is a WPF window." Height="28" HorizontalAlignment="Left" Margin="42,12,0,0" Name="label1" VerticalAlignment="Top" />

    </Grid>

</Window>

 

  • 切换到Code View,用以下代码取代原先的代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

 

namespace SetFormOwnerToWindow {

    /// <summary>

    /// Interaction logic for MainWindow.xaml

    /// </summary>

    public partial class MainWindow : Window {

        public MainWindow() {

            InitializeComponent();

        }

 

        private void Window_Loaded(object sender, RoutedEventArgs e) {

            IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;

            System.Windows.Forms.NativeWindow ownerWindow = new System.Windows.Forms.NativeWindow();

            ownerWindow.AssignHandle(handle);

            uc1.Owner = ownerWindow;

        }

    }

}

 

 

 

 

注意,我们需要在Loaded事件中指定uc1的Owner,因为在MainWindow constructor中,Handle值为0。

 

  • 按CTRL+F5运行项目看看效果如何。

原创粉丝点击