在随笔 【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大兄,结果找到下面这文章:
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,传哪一个都可以,效果完全一致.