VSTO Excel 加载项:当从模态 windows 表单调用 Excel 输入框时,焦点转到 Visual Studio

VSTO Excel AddIn: When Excel Inputbox is called from modal windows form, focus goes to Visual Studio

我在 Excel AddIn 应用程序中有一个 windows 表单。我使用 ShowDialog() 将表单显示为模态 window。我需要在我的应用程序中指定一个范围地址。所以,我添加了一个按钮,调用 Application.InputBox。 按钮点击事件包含以下代码

       private void button1_Click(object sender, EventArgs e)
    {
        Excel.Range myRng;
        Excel.Application app = Globals.ThisAddIn.Application;
        myRng = app.InputBox("Prompt", "Title", Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing,   8);
        label1.Text = myRng.Address.ToString();
        this.Focus();
    }

它工作正常。但是,当输入框处于活动状态时,我需要隐藏 windows 表单。所以我稍微修改了代码

       private void button1_Click(object sender, EventArgs e)
    {
        Excel.Range myRng;
        Excel.Application app = Globals.ThisAddIn.Application;
        this.Visible = false;
        myRng = app.InputBox("Prompt", "Title", Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing,   8);
        label1.Text = myRng.Address.ToString();
        this.Visible = true;
        this.Focus();
    }

不幸的是,这引发了一个问题。当我单击按钮时,焦点移动到 Visual Studio。我究竟做错了什么?如何在 InputBox 打开的那一刻保持焦点在 Excel 应用程序上?

终于找到解决办法了。我更改了表单 class 中的代码,如下所示

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    private void button1_Click(object sender, EventArgs e)
    {
        Excel.Range myRng;
        Excel.Application app = Globals.ThisAddIn.Application;

        string fileName;
        fileName = app.ActiveWorkbook.Name;
        Process[] processes = Process.GetProcessesByName("excel");
        foreach (Process p in processes)
        {
            if (p.MainWindowTitle.Contains(fileName.Substring(fileName.LastIndexOf("/") + 1)))
            {
                SetForegroundWindow(p.MainWindowHandle);
            }
        }

        this.Visible = false;

        try
        {
            myRng = app.InputBox("Prompt", "Title", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 8);
        }
        catch
        {
            myRng = null;
        }

        if (myRng != null)
        {
            label1.Text = myRng.Address.ToString();
        }

        this.Visible = true;
        this.Activate();
    }

现在可以按要求工作了。但是,我仍然想知道为什么会出现问题,以及是否有更简单的解决方案。如果您有任何想法,请告诉我。

P.S。 link 很有帮助:Set Focus on Excel Application

对我来说,我在中间添加了这一行,如下所示,效果很好。

this.Visible = false;
this.BrintToFront();