从WPF调用WinForms窗口时窗口丢失焦点问题
WPF调用WinForms窗口显示在后方的解决方法
在基于.NET Framework的WPF应用中调用WinForms窗口(封装在DLL内)时,WinForms窗口会被置于WPF窗口后方,表现为窗口打开后失去焦点,或者WPF窗口始终抢占焦点。
问题代码示例
WPF按钮点击事件调用代码:
graficha.abre(2);
WinForms窗口打开代码:
public void abre(int modoShow = 1) { Form1 Form_1 = new Form1(Empresa,EmpIni,EmpFim,DataIni,DataFim); // 其他业务逻辑... if (modoShow == 1) Form_1.ShowDialog(); else Form_1.Show(); }
解决方案
1. 关联窗口所有者(推荐)
WPF与WinForms分属不同窗口系统,未设置所有者会导致层级异常。将WPF窗口句柄转换为WinForms可识别的IWin32Window,作为WinForms窗口的所有者传入:
修改WinForms的abre方法:
public void abre(int modoShow = 1, System.Windows.Forms.IWin32Window owner = null) { Form1 Form_1 = new Form1(Empresa,EmpIni,EmpFim,DataIni,DataFim); // 其他业务逻辑... if (modoShow == 1) Form_1.ShowDialog(owner); else Form_1.Show(owner); }
在WPF按钮点击事件中调用:
using System.Windows.Interop; // 获取当前WPF主窗口句柄 var wpfWindowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle; var winFormsOwner = new System.Windows.Forms.NativeWindow(); winFormsOwner.AssignHandle(wpfWindowHandle); // 传入所有者调用WinForms窗口 graficha.abre(2, winFormsOwner);
2. 强制激活WinForms窗口
若无需设置所有者,可在WinForms窗口显示后强制激活并前置:
修改WinForms的abre方法:
public void abre(int modoShow = 1) { Form1 Form_1 = new Form1(Empresa,EmpIni,EmpFim,DataIni,DataFim); // 其他业务逻辑... if (modoShow == 1) Form_1.ShowDialog(); else { Form_1.Show(); Form_1.Activate(); Form_1.BringToFront(); } }
或者在WinForms窗口的Load事件中添加:
private void Form1_Load(object sender, EventArgs e) { this.TopMost = true; this.Activate(); this.TopMost = false; // 仅激活时置顶,避免长期遮挡 }
3. 使用模态对话框(业务允许时)
如果业务场景支持模态窗口,直接调用ShowDialog()(对应modoShow=1),它会自动将WinForms窗口置于WPF窗口前方并获取焦点。
内容的提问来源于stack exchange,提问作者Vinicius Souza
相关产品推荐
相关产品推荐

