You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:12:45