表单失去焦点后无法获得焦点

4
我已经为Visual Studio 2008创建了一个插件,它使用Form1.Show(this);打开一个窗体。
如果用户在打开/关闭Visual Studio对话框(例如程序集信息)时打开了表单,则用户无法聚焦到插件创建的窗体。请问是否有什么我遗漏的东西可以让用户返回到窗体?如果我使用Form1.ShowDialog(this),则不会发生这种情况,但是我希望用户在我的自定义窗体打开时也能看到程序集信息。
该插件实现了IWin32Window
public System.IntPtr Handle
{
    get
    {
        return new System.IntPtr(_applicationObject.MainWindow.HWnd);
    }
}

编辑:重现步骤

  • 创建一个Visual Studio插件项目
  • 添加对System.Windows.Forms的引用
  • 将以下内容添加到public void Exec(...)
  • System.Windows.Forms.Form f = new System.Windows.Forms.Form();
    f.Show();
    

  • 运行插件,并在启动的Visual Studio实例中打开一个项目
  • 打开项目属性,转到“应用程序”选项卡,打开“程序集信息”,然后关闭它。

  • 我尝试创建一个简单的插件,但无法重现您的问题。您能否告诉我们更多关于您的 Form1 的信息? - tia
    我已经添加了重现步骤。 - JamesMLV
    2个回答

    5
    感谢您提供复制步骤,我已经成功地复制了您的问题。
    据我所知,在这个问题中,Visual Studio IDE使用的是控件(Control),而不是窗体(Forms)。
    由于不知道您的表单的预期功能,我在下面添加了一个基本示例来帮助入门。
    当然,还有很多其他的方法可以做到这一点。我不是AddIn开发人员,因此我的知识在这方面是有限的。 用户控件(User Control) 首先,右键单击您的项目并添加一个新的用户控件。在我的示例中,我将其命名为"MyForm"并在其中放置了一个简单的按钮,点击该按钮会显示"Hello"。
    这个用户控件将成为您的表单。
    namespace MyAddin1
    {
        public partial class MyForm : UserControl
        {
            public MyForm()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Hello");
            }
        }
    }
    

    创建表单

    我们需要使用托管您的 AddIn 的应用程序以及您的 AddIn 的实例。这两个成员已在您的 AddIn 项目中声明:_applicationObject 和 _addInInstance。它们在 OnConnection 事件中设置。

    在下面的代码中,我创建了一个新的工具窗口,并在其中托管了我的用户控件。我使用 Windows2.CreateTooWindow2 方法来完成这个操作。

    我将我的示例代码添加到 Excec 事件中,如下所示。再次说明,我不确定是否适合放置在该位置,但为了演示代码,这应该足够了。

    /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
    /// <param term='commandName'>The name of the command to execute.</param>
    /// <param term='executeOption'>Describes how the command should be run.</param>
    /// <param term='varIn'>Parameters passed from the caller to the command handler.</param>
    /// <param term='varOut'>Parameters passed from the command handler to the caller.</param>
    /// <param term='handled'>Informs the caller if the command was handled or not.</param>
    /// <seealso class='Exec' />
    public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
    {
        object tempObject = null;   // It's required but I'm not sure what one can do with it...
        Windows2 windows2 = null;   // Reference to the window collection displayed in the application host.
        Assembly asm = null;        // The assembly containing the user control.
        Window myWindow = null;     // Will contain the reference of the new Tool Window.
    
        try
        {
            handled = false;
    
            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                if (commandName == "MyAddin1.Connect.MyAddin1")
                {
                    handled = true;
    
                    // Get a reference to the window collection displayed in the application host.
                    windows2 = (Windows2)_applicationObject.Windows;
    
                    // Get the executing assembly.
                    asm = Assembly.GetExecutingAssembly();
    
                    // Create the tool window and insert the user control.
                    myWindow = windows2.CreateToolWindow2(_addInInstance, asm.Location, "MyAddin1.MyForm", "My Tool Window", "{CB2AE2BD-2336-4615-B0A3-C55B9C7794C9}", ref tempObject);
    
                    // Set window properties to make it act more like a modless form.
                    myWindow.Linkable = false;  // Indicates whether the window can be docked with other windows in the IDE or not.
                    myWindow.IsFloating = true; // Indicates whether the window floats over other windows or not.
    
                    // Show the window.
                    myWindow.Visible = true;
    
                    return;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    

    我测试了这个应用程序,它将我的插件添加到了IDE的工具菜单中,当我点击我的插件时,它显示了窗口并运行正常。在显示程序集对话框时,它也没有冻结、挂起或出现任何问题。



    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接