1

我创建了一个新的 Visual Studio 插件,用于在 Visual Studio 工具箱中创建和添加我的自定义选项卡,并将新项目(控件)添加到我的自定义选项卡中。代码适用于将新选项卡添加到 Visual Studio 工具箱,但不适用于将新项目(控件)添加到我的选项卡。

我的 Visual Studio 插件代码是:

using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using EnvDTE90;
using EnvDTE100;
using System.Windows.Forms;
namespace MyAddin1
{
    /// <summary>The object for implementing an Add-in.</summary>
    /// <seealso class='IDTExtensibility2' />
    public class Connect : IDTExtensibility2
    {
        /// <summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
        public Connect()
        {
        }

        /// <summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary>
        /// <param term='application'>Root object of the host application.</param>
        /// <param term='connectMode'>Describes how the Add-in is being loaded.</param>
        /// <param term='addInInst'>Object representing this Add-in.</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
        {
            _applicationObject = (DTE2)application;
            _addInInstance = (AddIn)addInInst;
            // Pass the applicationObject member variable to the code example.
            ToolboxExample(_applicationObject);
        }

        public void ToolboxExample(DTE2 dte)
        {
            ToolBox tlBox = null;
            ToolBoxTabs tbxTabs = null;
            ToolBoxTab3 tbxTab = null;
            try
            {
                tlBox = (ToolBox)(dte.Windows.Item(Constants.vsWindowKindToolbox).Object);
                tbxTabs = tlBox.ToolBoxTabs;
                tbxTab = (ToolBoxTab3)tbxTabs.Add("MRS");
                tbxTab.Activate();
                tbxTab.ToolBoxItems.Add("FloorsGrouping", @"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WindowsFormsControlLibrary2\v4.0_1.0.0.0__197889249da45bfc\WindowsFormsControlLibrary2.dll", vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("ERROR: " + ex.Message);
            }
        }

        private DTE2 _applicationObject;
        private AddIn _addInInstance;
    }
}

以下代码行不起作用:

tbxTab.ToolBoxItems.Add("FloorsGrouping", @"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WindowsFormsControlLibrary2\v4.0_1.0.0.0__197889249da45bfc\WindowsFormsControlLibrary2.dll", vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);

我改变

tbxTab.ToolBoxItems.Add

和:

tbxTabs.Item("MRS").ToolBoxItems.Add

但是,它对我不起作用。即使我改变

@"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WindowsFormsControlLibrary2\v4.0_1.0.0.0__197889249da45bfc\WindowsFormsControlLibrary2.dll"

使用以下代码行并一一测试:

@"E:\Rostami\Saino\WindowsFormsControlLibrary2.dll"

"WindowsFormsControlLibrary2.FloorsGrouping, WindowsFormsControlLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=197889249da45bfc"

但是,它再次对我不起作用。

我的自定义控件主类名称是FloorsGrouping,它的显示名称是:

[DisplayName("Floors Group")]

它在 GAC 中的程序集名称是:

[Editor("WindowsFormsControlLibrary2.FloorsGrouping, WindowsFormsControlLibrary2, Version=1.0.0.0, Culture=neutral,  PublicKeyToken=197889249da45bfc", typeof(UITypeEditor))]

我在 Internet 上搜索了任何解决方案,但我只找到了几个解决方案,这些解决方案描述了向 Visual Studio 工具箱添加新选项卡以及从 Visual Studio Addin 向选项卡添加控件。

4

1 回答 1

1

我找到了解决方案,可以将我的自定义选项卡添加到 Visual Studio 工具箱,并使用 Windows 窗体应用程序项目而不是 Visual Studio 插件项目将我的自定义控件添加到我的自定义选项卡。我将其描述如下:

在 Windows Forms Application 项目中,首先,我们必须创建一个 Visual Studio IDE 的实例。然后,必须创建一个临时的 Windows 窗体应用程序项目,然后必须将我们的自定义选项卡添加到 Visual Studio 工具箱,并将我们的自定义控件添加到我们的自定义选项卡。

我的 Class1.cs 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;
using System.IO;

namespace InstallToolboxControls
{
    // Definition of the IMessageFilter interface which we need to implement and 
    // register with the CoRegisterMessageFilter API.
    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    interface IOleMessageFilter // Renamed to avoid confusion w/ System.Windows.Forms.IMessageFilter
    {
        [PreserveSig]
        int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo);

        [PreserveSig]
        int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType);

        [PreserveSig]
        int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType);
    }

    class Program : IOleMessageFilter
    {
        [DllImport("ole32.dll")]
        private static extern int CoRegisterMessageFilter(IOleMessageFilter newFilter, out IOleMessageFilter oldFilter);
        static string ctrlPath = "WindowsFormsControlLibrary2.FloorsGrouping, WindowsFormsControlLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=197889249da45bfc";//@"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\WindowsFormsControlLibrary2\v4.0_1.0.0.0__197889249da45bfc\WindowsFormsControlLibrary2.dll";//@"E:\Rostami\Saino\Program\Tests\WindowsFormsControlLibrary2\WindowsFormsControlLibrary2\bin\Debug\WindowsFormsControlLibrary2.dll";

        [STAThread]
        public static void Toolbox(string arg)
        {
            Program program = new Program();
            program.Register();
            if (arg.Equals("Install", StringComparison.CurrentCultureIgnoreCase))
            {
                program.InstallControl();
            }
            else if (arg.Equals("UnInstall", StringComparison.CurrentCultureIgnoreCase))
            {
                program.UninstallControl();
            }
            program.Revoke();

            // to ensure the dte object is actually released, and the devenv.exe process terminates.
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        void InstallControl()
        {
            // Create an instance of the VS IDE,
            Type type = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
            DTE dte = (DTE)System.Activator.CreateInstance(type, true);

            // create a temporary winform project;
            string tmpFile = Path.GetFileNameWithoutExtension(Path.GetTempFileName());
            string tmpDir = string.Format("{0}{1}", Path.GetTempPath(), tmpFile);
            Solution2 solution = dte.Solution as Solution2;
            string templatePath = solution.GetProjectTemplate("WindowsApplication.zip", "CSharp");
            Project proj = solution.AddFromTemplate(templatePath, tmpDir, "dummyproj", false);

            // add the control to the toolbox.
            EnvDTE.Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindToolbox);
            EnvDTE.ToolBox toolbox = (EnvDTE.ToolBox)window.Object;
            EnvDTE.ToolBoxTab myTab = toolbox.ToolBoxTabs.Add("Saino");
            myTab.Activate();
            myTab.ToolBoxItems.Add("MyUserControl", ctrlPath, vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
            dte.Solution.Close(false);
            Marshal.ReleaseComObject(dte);
            //Console.WriteLine("Control Installed!!!");
        }

        void UninstallControl()
        {
            Type type = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
            DTE dte = (DTE)System.Activator.CreateInstance(type, true);
            EnvDTE.Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindToolbox);
            EnvDTE.ToolBox toolbox = (EnvDTE.ToolBox)window.Object;
            EnvDTE.ToolBoxTab myTab = toolbox.ToolBoxTabs.Item("Saino");
            myTab.Activate();
            myTab.Delete();
            Marshal.ReleaseComObject(dte);
            //Console.WriteLine("Control Uninstalled!!!");
        }

        void Register()
        {
            IOleMessageFilter oldFilter;
            CoRegisterMessageFilter(this, out oldFilter);
        }

        void Revoke()
        {
            IOleMessageFilter oldFilter;
            CoRegisterMessageFilter(null, out oldFilter);
        }

        #region IOleMessageFilter Members
        public int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo)
        {
            return 0; //SERVERCALL_ISHANDLED
        }

        public int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
        {
            if (dwRejectType == 2) // SERVERCALL_RETRYLATER
            {
                return 200; // wait 2 seconds and try again
            }
            return -1; // cancel call
        }

        public int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
        {
            return 2; //PENDINGMSG_WAITDEFPROCESS
        }
        #endregion
    }
}

我的 Form1.cs 代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using InstallToolboxControls;

namespace WindowsFormsApplication12
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            InstallToolboxControls.Program prg = new InstallToolboxControls.Program();
            InstallToolboxControls.Program.Toolbox("Install");
        }
    }
}
于 2012-10-10T12:18:16.400 回答