【VS Shell Integrated】在VS.Net 2008 IDE中如何设置直接弹出的WPF窗体的Owner(对<在VS.Net 2008 IDE中直接使用WPF窗体作为弹出窗体>的补充

在随笔 【VS Shell Integrated】在VS.Net 2008 IDE中直接使用WPF窗体作为弹出窗体 中虽然实现使用WPF窗体, 但是有一个问题,就是在操作系统任务栏切换VS.Net 2008 IDE和弹出的WPF窗口或其它程序窗体时,WPF窗口有时会被 VS.Net 2008 IDE 挡住,也就是跑到VS.Net 2008 IDE的后面去了. 这是因为,虽然使用了ShowDialog方法,但是弹出前没有设置WPF窗体的Owner.

 

理虽是这个理但是怎么设呢,层层包裹,皮厚的很啊,如下图.

image

 

怎么办,烧香,请GOOGLE大兄,结果找到下面这文章:

http://blogs.msdn.com/wpfsdk/archive/2007/04/03/centering-wpf-windows-with-wpf-and-non-wpf-owner-windows.aspx

 

查看下文时,先看上面引用的文章

 

但是关键的代码没写,真是杯具啊

 

// Get the handle to the non-WPF owner window
IntPtr ownerWindowHandle = ...; // Get hWnd for non-WPF window
 
没法子,发信给作者,问他怎么能直接得到ToolWindow或IDE的handle.
结果是微软 Developer Division User Education 的一个姐姐(不知年龄)给了回复.不过,来来回回,好像她还是没完全搞明白程序结构.
只给了一些基本的提示,有些用处,但是没解决根本性问题,不过还是非常感谢这位姐姐.
 
我这一看,看来玩直接的是不行啦,咱变通一下吧,用点间接方法吧,很简单,就是通过实例成员,传!

 

1) 在WPF用户控件定义一个成员变量ParentHandle

 public partial class ExplorerControlWPF : System.Windows.Controls.UserControl
    {
        public ExplorerControlWPF()
        {
            InitializeComponent();
        }

        public IntPtr ParentHandle;

2) 在Winform 用户控件中传递Handle

  public partial class ExplorerControl : System.Windows.Forms.UserControl
    {
        public ExplorerControl()
        {
            InitializeComponent();

            //
            //传ElementHost的Handle
            //
            //或者传ExplorerControl.Handle 
            //(this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.elementHost1.Parent.Handl
            //

            (this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.elementHost1.Handle;
        }

3) 经过上述步骤,就可以在WPF用户控件ExplorerControlWPF中使用Handle了

  private void MuNewProject_Click(object sender, RoutedEventArgs e)
        {
            RegProjectForm RegWin = new RegProjectForm();
            WindowInteropHelper helper = new WindowInteropHelper(RegWin);
            helper.Owner = this.ParentHandle;

            try
            {
                if (RegWin.ShowDialog() == true)
                {

运行,大功告成!

    

通过类似的方法,也可以把Tool Window的Handle传给ExplorerControlWPF   

 

1) 在 ExplorerControl  , 声明一个成员变量 ParentWindow

public partial class ExplorerControl : System.Windows.Forms.UserControl
    {
        public  ToolWindowPane ParentWindow;
        public ExplorerControl()
        {
            InitializeComponent();

            //
            //传ElementHost的Handle
            //
            //或者传ExplorerControl.Handle 
            //(this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.elementHost1.Parent.Handl
            //

            //(this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.elementHost1.Handle;
        }

2) 在Tool Window里,把自身传给ExplorerControl 的实例

    [Guid("e6a26ad4-7f6d-48e1-b1b4-dfb65654800f")]
    public class ExplorerForm : ToolWindowPane
    {        
        private ExplorerControl ContentControl;

        public ExplorerForm() :
            base(null)
        {
            
            this.Caption = UiResources.ExplorerWindowTitle;
            this.BitmapResourceID = 301;
            this.BitmapIndex = 1;
            this.ContentControl = new ExplorerControl();
            
            //传递自身
            this.ContentControl.ParentWindow = this;            
        }

 
3)在 ExplorerControl的 OnLoad事件中传递Tool Window的handle给ExplorerControlWPF. 
  注意:不是在构造函数里,因为这时ParentWindow还没被赋上引用.
 public partial class ExplorerControl : System.Windows.Forms.UserControl
    {
        public  ToolWindowPane ParentWindow;
        public ExplorerControl()
        {
            InitializeComponent();

            //
            //传ElementHost的Handle
            //
            //或者传ExplorerControl.Handle 
            //(this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.elementHost1.Parent.Handle
            //

            //(this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.elementHost1.Handle;
        }

        protected override void OnLoad(EventArgs e)
        {
            (this.elementHost1.Child as ExplorerControlWPF).ParentHandle = this.ParentWindow.Window.Handle;
            base.OnLoad(e);
        }

4) 经过上述步骤,就可以在WPF用户控件ExplorerControlWPF中使用Handle了

  private void MuNewProject_Click(object sender, RoutedEventArgs e)
        {
            RegProjectForm RegWin = new RegProjectForm();
            WindowInteropHelper helper = new WindowInteropHelper(RegWin);
            helper.Owner = this.ParentHandle;

            try
            {
                if (RegWin.ShowDialog() == true)
                {

运行,大功告成!

这三个Handle,传哪一个都可以,效果完全一致.

posted on 2010-03-18 10:24  Apollo Sun  阅读(1686)  评论(2编辑  收藏  举报

导航