在随笔 【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.
理虽是这个理但是怎么设呢,层层包裹,皮厚的很啊,如下图.
怎么办,烧香,请GOOGLE大兄,结果找到下面这文章:
查看下文时,先看上面引用的文章
但是关键的代码没写,真是杯具啊
// 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,传哪一个都可以,效果完全一致.