逐步解說: 自動載入工具箱項目
這個逐步解說將說明如何受管理的 VSPackage 可以使用反映來自動載入所有ToolboxItem自己的組件所提供的項目。
![]() |
---|
若要將自訂控制項加入至 [工具箱] 中的建議的方式是使用工具箱控制項樣板以 Visual Studio 10 SDK 隨附其中包括自動載入的支援。本主題被保留用於回溯相容性、 將現有的控制項加入至 [工具箱] 中,以及進階的工具箱開發。 如需有關如何使用範本建立工具箱控制項的詳細資訊,請參閱How to: 建立使用 Windows Form 的工具箱控制項和How to: 建立使用 WPF 的工具箱控制項。 |
本逐步解說會引導您完成下列步驟:
新增並正確地登錄所有工具箱 VSPackage 物件,藉由使用中的控制項ToolboxItemAttribute, ToolboxBitmapAttribute,以及DisplayNameAttribute。
建立下列兩個控制項,並將圖示加入針對每個工具箱:
藉由預設值,將一個控制項ToolboxItem類別。
藉由使用自訂的類別衍生自另一個控制項加入ToolboxItem類別。
提供登錄 VSPackage ToolboxItem物件的ProvideToolboxItemsAttribute類別。
使用反映來產生一份所有ToolboxItem VSPackage 提供載入時的物件。
建立處理常式的ToolboxInitialized和ToolboxUpgraded事件。 這樣可以保證, ToolboxItem的 VSPackage 物件就會正確地載入。
實作命令上強迫重新初始化 VSPackage 工具箱。
必要條件
若要完成這個逐步解說中,您必須安裝Visual Studio 2010 SDK。
![]() |
---|
如需有關 Visual Studio 的 SDK 的詳細資訊,請參閱擴充 Visual Studio 的概觀。若要了解如何下載 Visual Studio 的 SDK,請參閱Visual Studio 擴充性開發人員中心 MSDN 網站上。 |
Visual Studio 的封裝專案範本的位置
Visual Studio 的封裝的專案範本,請參閱以下三個不同的位置,在新的專案對話方塊:
在 [Visual Basic 擴充性。 專案的預設語言是 Visual Basic。
在 [C# 擴充性。 專案的預設語言是 C#。
在 [其他專案的型別擴充性。 專案的預設語言是 c + +。
建立受管理的 VSPackage
若要建立 LoadToolboxMembers VSPackage
建立名為 VSPackage LoadToolboxMembers。 如需詳細資訊,請參閱 逐步解說: 使用 Visual Studio 的封裝範本建立功能表命令。
新增功能表指令。
命名命令初始化 LoadToolboxMembers VB 的 Visual Basic 或初始化 LoadToolboxMembers CS 的視覺 C#。
如果您遵循本逐步解說中一個以上的語言,您必須更新的專案,可以清楚識別自動產生的組件。
若要釐清 Visual Basic 和視覺化 C# VSPackages
For Visual Basic:
在方案總管] 中,開啟專案的屬性,然後選取應用程式 ] 索引標籤。
將組件名稱變更成 LoadToolboxMembersVB,並將變更的預設命名空間 Company.LoadToolboxMembersVB。
For Visual C#:
在方案總管] 中,開啟專案的屬性,然後選取應用程式 ] 索引標籤。
將組件名稱變更成 LoadToolboxMembersCS,並將變更的預設命名空間 Company.LoadToolboxMembersCS。
在程式碼編輯器中開啟 LoadToolboxMembersPackage 類別。
若要重新命名現有的命名空間,以滑鼠右鍵按一下現有的命名空間名稱,請使用重整工具LoadToolboxMembers,指到重構,然後按一下 [ 重新命名。 將名稱變更成 LoadToolboxMembersCS。
儲存所有變更。
若要將支援的參考加入
在 [LoadToolboxMembers] 專案中,加入的參考, System.Drawing.Design 。NET 架構元件,如下所示。
在方案總管] 中LoadToolboxMembers 專案上按一下滑鼠右鍵,然後選擇 加入參考。
在 。NET 索引標籤上的加入參考 對話方塊中,連按兩下 [ System.Drawing.Design。
為 Visual Basic 加入專案中的 [匯入命名空間] 清單中的下列命名空間:
Company.LoadToolboxMembersVB
System
System.ComponentModel
System.Drawing
System.Windows.Forms
若要測試產生的程式碼
編譯並啟動 VSPackage Visual Studio 的實驗登錄區中。
在工具 ] 功能表中,按一下 初始化 LoadToolboxMembers VB 或初始化 LoadToolboxMembers CS。
如此會開啟訊息方塊,其中包含表示封裝的功能表項目處理常式所呼叫的文字。
關閉實驗性質的版本的Visual Studio。
建立工具箱控制項
本章節中,您需要建立並註冊使用者控制項, Control1,來宣告相關的預設工具箱項目。 如需有關如何撰寫 Windows Form 控制項,並ToolboxItem類別,請參閱在設計階段開發 Windows Form 控制項。
若要建立會使用預設值 ToolboxItem 工具箱控制項
在方案總管] 中,加入UserControl物件至 LoadToolboxMembers 的專案,如下所示:
在方案總管] 中,以滑鼠右鍵按一下 LoadToolboxMembers 專案,指向 新增,然後按一下 使用者控制項。
在加入新項目對話方塊方塊中,將名稱變更成 Control1.vb 的Visual Basic或 Control1.cs 的Visual C#。
如需有關如何將新的項目加入至專案的詳細資訊,請參閱How to: Add New Project Items。
在 [設計] 檢視中,開啟新的控制項。
從工具箱,拖曳 按鈕 控制項 (位於 通用控制項類別) 至設計工具。
按兩下您剛才建立的按鈕。 如此一來,會產生事件處理常式的按鈕的Click事件。 使用下列程式碼,以更新的事件處理常式:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click MessageBox.Show("Hello world from " & Me.ToString()) End Sub
private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Hello world from " + this.ToString()); }
修改建構函式,若要設定按鈕文字控制項的InitializeComponent ,會呼叫方法:
Public Sub New() InitializeComponent() Button1.Text = Me.Name + " Button" End Sub
public Control1() { InitializeComponent(); button1.Text = this.Name + " Button"; }
將屬性加入至檔案,以啟用查詢所提供的 VSPackage ToolboxItem類別:
' Set the display name and custom bitmap to use for this item. ' The build action for the bitmap must be "Embedded Resource". <DisplayName("ToolboxMember 1 VB")> _ <Description("Custom toolbox item from package LoadToolboxMembers.")> _ <ToolboxItem(True)> _ <ToolboxBitmap(GetType(Control1), "Control1.bmp")> _ Public Class Control1
// Set the display name and custom bitmap to use for this item. // The build action for the bitmap must be "Embedded Resource". [DisplayName("ToolboxMember 1 CS")] [Description("Custom toolbox item from package LoadToolboxMembers.")] [ToolboxItem(true)] [ToolboxBitmap(typeof(Control1), "Control1.bmp")] public partial class Control1 : UserControl {
儲存檔案。
在下列程序中,您需要建立並註冊第二個使用者控制項, Control2,與相關聯的自訂工具箱項目, Control2_ToolboxItem,也就是衍生自ToolboxItem類別。
若要建立使用自訂的 ToolboxItem 衍生類別的工具箱控制項
建立第二個使用者控制項,名為 Control2。 按兩下表單,以顯示 [程式碼檔。
新增System.Drawing.Design和System.Globalization類別中所使用的命名空間。
Imports System.Drawing.Design Imports System.Globalization
using System.Drawing.Design; using System.Globalization;
新增按鈕和按鈕 click 事件處理常式,並更新控制項的建構函式,就跟您更新的第一個控制項的方式一樣。
Add the DisplayNameAttribute, DescriptionAttribute, ToolboxItemAttribute, and ToolboxBitmapAttribute attributes to the file.
這些屬性可讓查詢 VSPackage ToolboxItem類別。
如需詳細資訊,以及如何撰寫自訂的範例ToolboxItem物件,請參閱ToolboxItem參考網頁。
與之前的變更,您的第二個控制項類別應該類似下列的程式碼。 符號Control2_ToolboxMenu會等到後的下一個步驟是未定義。
' Set the display name and custom bitmap to use for Me item. ' The build action for the bitmap must be "Embedded Resource". ' Also declare a custom toolbox item implementation. <DisplayName("ToolboxMember 2 VB")> _ <Description("Custom toolbox item from package LoadToolboxMembers.")> _ <ToolboxItem(GetType(Control2_ToolboxItem))> _ <ToolboxBitmap(GetType(Control2), "Control2.bmp")> _ Public Class Control2 Public Sub New() InitializeComponent() Button1.Text = Me.Name + " Button" End Sub Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click MessageBox.Show("Hello world from " & Me.ToString()) End Sub End Class
// Set the display name and custom bitmap to use for this item. // The build action for the bitmap must be "Embedded Resource". // Also declare a custom toolbox item implementation. [DisplayName("ToolboxMember 2 CS")] [Description("Custom toolbox item from package LoadToolboxMembers.")] [ToolboxItem(typeof(Control2_ToolboxItem))] [ToolboxBitmap(typeof(Control2), "Control2.bmp")] public partial class Control2 : UserControl { public Control2() { InitializeComponent(); button1.Text = this.Name + " Button"; } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Hello world from " + this.ToString()); } }
建立一個名為 Control2_ToolboxItem。 這ToolboxItem是建構為第二個控制項,並加入至工具箱。 類別必須具有SerializableAttribute套用到它。
<Serializable()> _ Friend Class Control2_ToolboxItem Inherits ToolboxItem Public Sub New(ByVal toolType As Type) MyBase.New(toolType) End Sub Public Overrides Sub Initialize(ByVal toolType As Type) If Not toolType.Equals(GetType(Control2)) Then Throw New ArgumentException( _ String.Format(CultureInfo.CurrentCulture, _ "The {0} constructor argument must be of type {1}.", _ Me.GetType().FullName, GetType(Control2).FullName)) End If MyBase.Initialize(toolType) End Sub End Class
[Serializable()] internal class Control2_ToolboxItem : ToolboxItem { public Control2_ToolboxItem(Type toolType) : base(toolType) { } public override void Initialize(Type toolType) { if (!toolType.Equals(typeof(Control2))) { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, "The {0} constructor argument must be of type {1}.", this.GetType().FullName, typeof(Control2).FullName)); } base.Initialize(toolType); } }
儲存檔案。
內嵌點陣圖圖示
兩個執行個體ToolboxBitmapAttribute使用稍早指出專案代表兩個控制項,以下列圖示:
Control1.bmp,找到包含第一個控制項的命名空間中。
Control2.bmp,找到包含第二個控制項的命名空間中。
若要內嵌點陣圖圖示的 ToolboxItem
加入兩個新的點陣圖到專案中,如下所示。
以滑鼠右鍵按一下 LoadToolboxMembers 專案。
指向新增,然後按一下 [ 新的項目。
在加入新項目 對話方塊中,選取 點陣圖檔,並命名為檔案 Control1.bmp。
重複這些步驟執行,第二個點陣圖,並命名為 Control2.bmp。
如此一來,便會開啟中的每一個點陣圖Visual Studio點陣圖編輯器。
設定每個圖示的大小為 16 x 16,如下所示。
每一個點陣圖中,按一下 屬性] 視窗中 的 檢視功能表。
在屬性 ] 視窗中,設定 高度 和 寬度為 16。
使用點陣圖編輯器,在Visual Studio建立的每個圖示的影像。
在方案總管] 中,按一下每個點陣圖的檔案,然後在 屬性 ] 視窗中,設定 建置動作 屬性,以 內嵌資源。
儲存所有開啟的檔案。
修改 VSPackage 實作
必須修改 VSPackage 的預設實作,執行下列動作:
註冊支援,是 「 工具箱項目提供者。
取得一份ToolboxItem VSPackage 支援的物件。
載入ToolboxItem物件在Visual Studio工具箱時ToolboxInitialized和ToolboxUpgraded事件的處理。
下一個程序會示範如何修改封裝實作。
若要修改封裝要使實作 VSPackage 的工具箱項目提供者
程式碼編輯器中開啟 LoadToolboxMembersPackage.cs 或 LoadToolboxMembersPackage.vb 檔案。
修改宣告LoadToolboxMembersPackage類別,也就是實作的Package ,如下所示在方案中的類別。
新增下列命名空間指示詞,可LoadToolboxMembersPackage類別檔案。
Imports System.Collections Imports System.ComponentModel Imports System.Drawing.Design Imports System.Reflection
using System.Collections; using System.ComponentModel; using System.Drawing.Design; using System.Reflection;
註冊成 VSPackage ToolboxItem加上的執行個體的類別ProvideToolboxItemsAttribute。
注意事項
唯一的引數的ProvideToolboxItemsAttribute版本的ToolboxItem ,由 VSPackage。變更此值會強制載入 VSPackage,即使它附帶的更早版本的快取的版本 IDE ToolboxItem類別。
加入下列這兩個新private ] 欄位, LoadToolboxMembersPackage類別:
ArrayList成員,名為ToolboxItemList,而保留一份ToolboxItem物件的LoadToolboxMembersPackage類別會管理。
A String、 具名CategoryTab,其中包含工具箱類別] 或 [用來容納的索引標籤ToolboxItem物件所管理的LoadToolboxMembersPackage類別。
這項修改的結果會類似下列的程式碼:
Imports Microsoft.VisualBasic Imports System Imports System.Diagnostics Imports System.Globalization Imports System.Runtime.InteropServices Imports System.ComponentModel.Design Imports Microsoft.Win32 Imports Microsoft.VisualStudio.Shell.Interop Imports Microsoft.VisualStudio.OLE.Interop Imports Microsoft.VisualStudio.Shell Imports System.Collections Imports System.ComponentModel Imports System.Drawing.Design Imports System.Reflection ' ... <PackageRegistration(UseManagedResourcesOnly:=True), _ DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0"), _ InstalledProductRegistration(False, "#110", "#112", "1.0", IconResourceID:=400), _ ProvideLoadKey("Standard", "1.0", "Package Name", "Company", 1), _ ProvideMenuResource(1000, 1), _ Guid(GuidList.guidLoadToolboxMembersPkgString)> _ <ProvideToolboxItems(1)> _ Public NotInheritable Class LoadToolboxMembersPackage Inherits Package ' List for the toolbox items provided by this package. Private ToolboxItemList As ArrayList ' Name for the Toolbox category tab for the package's toolbox items. Private CategoryTab As String = "LoadToolboxMembers Walkthrough VB" ' ...
using System; using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; using System.ComponentModel.Design; using Microsoft.Win32; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Shell; using System.Collections; using System.ComponentModel; using System.Drawing.Design; using System.Reflection; namespace Company.LoadToolboxMembersCS { // ... [PackageRegistration(UseManagedResourcesOnly = true)] // ... [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")] // ... [InstalledProductRegistration(false, "#110", "#112", "1.0", IconResourceID = 400)] // ... [ProvideLoadKey("Standard", "1.0", "Package Name", "Company", 1)] // ... [ProvideMenuResource(1000, 1)] [Guid(GuidList.guidLoadToolboxMembersPkgString)] [ProvideToolboxItems(1)] public sealed class LoadToolboxMembersPackage : Package { // List for the toolbox items provided by this package. private ArrayList ToolboxItemList; // Name for the Toolbox category tab for the package's toolbox items. private string CategoryTab = "LoadToolboxMembers Walkthrough CS"; // ...
展開套件成員區域,來修改Initialize方法,以執行下列動作:
對於Visual C#,訂閱ToolboxInitialized和ToolboxUpgraded事件。
呼叫CreateItemList方法,以填滿ArrayList物件ToolboxItemList。 ToolboxItemList將包含一份所有工具箱項目LoadToolboxMembersPackage管理。
Protected Overrides Sub Initialize() Trace.WriteLine(String.Format(CultureInfo.CurrentCulture, _ "Entering Initialize() of: {0}", Me.GetType().Name)) MyBase.Initialize() ' Add our command handlers for menu (commands must exist in the .vsct file) Dim mcs As OleMenuCommandService = _ TryCast(GetService(GetType(IMenuCommandService)), OleMenuCommandService) If Not mcs Is Nothing Then ' Create the command for the menu item. Dim menuCommandID As New CommandID( _ GuidList.guidLoadToolboxMembersCmdSet, CInt(PkgCmdIDList.cmdidMyCommand)) Dim menuItem As New MenuCommand( _ New EventHandler(AddressOf MenuItemCallback), menuCommandID) mcs.AddCommand(menuItem) End If ' Use reflection to get the toolbox items provided in this assembly. ToolboxItemList = CreateItemList(Me.GetType().Assembly) If ToolboxItemList Is Nothing Then ' Unable to generate the list. ' Add error handling code here. End If End Sub
protected override void Initialize() { Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); base.Initialize(); // Add our command handlers for menu (commands must exist in the .vsct file) OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if ( null != mcs ) { // Create the command for the menu item. CommandID menuCommandID = new CommandID(GuidList.guidLoadToolboxMembersCmdSet, (int)PkgCmdIDList.cmdidMyCommand); MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID ); mcs.AddCommand( menuItem ); // Subscribe to the toolbox intitialized and upgraded events. ToolboxInitialized += new EventHandler(OnRefreshToolbox); ToolboxUpgraded += new EventHandler(OnRefreshToolbox); } // Use reflection to get the toolbox items provided in this assembly. ToolboxItemList = CreateItemList(this.GetType().Assembly); if (null == ToolboxItemList) { // Unable to generate the list. // Add error handling code here. } }
加入兩個方法, CreateItemList和CreateToolboxItem,若要建構,藉由使用中繼資料、 的執行個體ToolboxItem中可用的物件LoadToolboxMembers組件,如下所示:
' Scan for toolbox items in the assembly and return the list of ' toolbox items. Private Function CreateItemList(ByVal asmbly As Assembly) As ArrayList Dim list As New ArrayList() For Each possibleItem As Type In asmbly.GetTypes() Dim item As ToolboxItem = CreateToolboxItem(possibleItem) If item IsNot Nothing Then list.Add(item) End If Next Return list End Function ' If the type represents a toolbox item, return an instance of the type ' otherwise, return Nothing. Private Function CreateToolboxItem(ByVal possibleItem As Type) As ToolboxItem ' A toolbox item must implement IComponent and must not be abstract. If Not GetType(IComponent).IsAssignableFrom(possibleItem) Or _ possibleItem.IsAbstract Then Return Nothing End If ' A toolbox item must have a constructor that takes a parameter of ' type Type or a constructor that takes no parameters. If possibleItem.GetConstructor(New Type() {GetType(Type)}) Is Nothing And _ possibleItem.GetConstructor(New Type() {}) Is Nothing Then Return Nothing End If Dim item As ToolboxItem = Nothing ' Check the custom attributes of the candidate type and attempt to ' create an instance of the toolbox item type. Dim attribs As AttributeCollection = _ TypeDescriptor.GetAttributes(possibleItem) Dim tba As ToolboxItemAttribute = TryCast( _ attribs(GetType(ToolboxItemAttribute)), ToolboxItemAttribute) If tba IsNot Nothing And Not tba.Equals(ToolboxItemAttribute.None) Then If Not tba.IsDefaultAttribute() Then ' This type represents a custom toolbox item implementation. Dim itemType As Type = tba.ToolboxItemType Dim ctor As ConstructorInfo = _ itemType.GetConstructor(New Type() {GetType(Type)}) If ctor IsNot Nothing And itemType IsNot Nothing Then item = CType(ctor.Invoke(New Object() {possibleItem}), ToolboxItem) Else ctor = itemType.GetConstructor(New Type() {}) If ctor IsNot Nothing Then item = CType(ctor.Invoke(New Object() {}), ToolboxItem) item.Initialize(possibleItem) End If End If Else ' This type represents a default toolbox item. item = New ToolboxItem(possibleItem) End If If item Is Nothing Then Throw New ApplicationException("Unable to create a ToolboxItem " & _ "object from " & possibleItem.FullName & ".") End If End If ' Update the display name of the toolbox item and add the item to ' the list. Dim displayName As DisplayNameAttribute = TryCast( _ attribs(GetType(DisplayNameAttribute)), DisplayNameAttribute) If displayName IsNot Nothing And Not displayName.IsDefaultAttribute() Then item.DisplayName = displayName.DisplayName End If Return item End Function
// Scan for toolbox items in the assembly and return the list of // toolbox items. private ArrayList CreateItemList(Assembly assembly) { ArrayList list = new ArrayList(); foreach (Type possibleItem in assembly.GetTypes()) { ToolboxItem item = CreateToolboxItem(possibleItem); if (item != null) { list.Add(item); } } return list; } // If the type represents a toolbox item, return an instance of the type; // otherwise, return null. private ToolboxItem CreateToolboxItem(Type possibleItem) { // A toolbox item must implement IComponent and must not be abstract. if (!typeof(IComponent).IsAssignableFrom(possibleItem) || possibleItem.IsAbstract) { return null; } // A toolbox item must have a constructor that takes a parameter of // type Type or a constructor that takes no parameters. if (null == possibleItem.GetConstructor(new Type[] { typeof(Type) }) && null == possibleItem.GetConstructor(new Type[0])) { return null; } ToolboxItem item = null; // Check the custom attributes of the candidate type and attempt to // create an instance of the toolbox item type. AttributeCollection attribs = TypeDescriptor.GetAttributes(possibleItem); ToolboxItemAttribute tba = attribs[typeof(ToolboxItemAttribute)] as ToolboxItemAttribute; if (tba != null && !tba.Equals(ToolboxItemAttribute.None)) { if (!tba.IsDefaultAttribute()) { // This type represents a custom toolbox item implementation. Type itemType = tba.ToolboxItemType; ConstructorInfo ctor = itemType.GetConstructor(new Type[] { typeof(Type) }); if (ctor != null && itemType != null) { item = (ToolboxItem)ctor.Invoke(new object[] { possibleItem }); } else { ctor = itemType.GetConstructor(new Type[0]); if (ctor != null) { item = (ToolboxItem)ctor.Invoke(new object[0]); item.Initialize(possibleItem); } } } else { // This type represents a default toolbox item. item = new ToolboxItem(possibleItem); } } if (item == null) { throw new ApplicationException("Unable to create a ToolboxItem " + "object from " + possibleItem.FullName + "."); } // Update the display name of the toolbox item and add the item to // the list. DisplayNameAttribute displayName = attribs[typeof(DisplayNameAttribute)] as DisplayNameAttribute; if (displayName != null && !displayName.IsDefaultAttribute()) { item.DisplayName = displayName.DisplayName; } return item; }
實作OnRefreshToolbox方法來處理ToolboxInitialized和ToolboxUpgraded事件。
OnRefreshToolbox方法會使用清單中的ToolboxItem中所包含的物件ToolboxItemList成員的LoadToolboxMembersPackage類別。 它還會執行下列動作:
會移除所有ToolboxItem已存在於工具箱分類所定義的變數中的物件CategoryTab。
新增新的執行個體,所有的ToolboxItem中所列的物件ToolboxItemList到 VSProject 的 [類別] 索引標籤。
設定工具箱到 VSProject 的 [類別] 索引標籤的作用中索引標籤。
Private Sub OnRefreshToolbox(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.ToolboxInitialized, Me.ToolboxUpgraded ' Add new instances of all ToolboxItems contained in ToolboxItemList. Dim service As IToolboxService = TryCast( _ GetService(GetType(IToolboxService)), IToolboxService) Dim toolbox As IVsToolbox = TryCast( _ GetService(GetType(IVsToolbox)), IVsToolbox) 'Remove target tab and all controls under it. For Each oldItem As ToolboxItem In service.GetToolboxItems(CategoryTab) service.RemoveToolboxItem(oldItem) Next toolbox.RemoveTab(CategoryTab) For Each itemFromList As ToolboxItem In ToolboxItemList service.AddToolboxItem(itemFromList, CategoryTab) Next service.SelectedCategory = CategoryTab service.Refresh() End Sub
void OnRefreshToolbox(object sender, EventArgs e) { // Add new instances of all ToolboxItems contained in ToolboxItemList. IToolboxService service = GetService(typeof(IToolboxService)) as IToolboxService; IVsToolbox toolbox = GetService(typeof(IVsToolbox)) as IVsToolbox; //Remove target tab and all controls under it. foreach (ToolboxItem oldItem in service.GetToolboxItems(CategoryTab)) { service.RemoveToolboxItem(oldItem); } toolbox.RemoveTab(CategoryTab); foreach (ToolboxItem itemFromList in ToolboxItemList) { service.AddToolboxItem(itemFromList, CategoryTab); } service.SelectedCategory = CategoryTab; service.Refresh(); }
注意事項
練習中,為其中一個可以開發一種機制,測試的新版的 VSPackage 或項目,並只會更新,如果 VSPackage 的版本已變更,否則版本的ToolboxItem已經變更。
正在初始化工具箱
若要實作命令,以初始化工具箱
變更功能表項目的命令處理常式方法中, MenuItemCallBack、,如下所示。
取代現有的實作MenuItemCallBack與下列程式碼:
Private Sub MenuItemCallback(ByVal sender As Object, ByVal e As EventArgs) Dim pkg As IVsPackage = TryCast(GetService(GetType(Package)), Package) pkg.ResetDefaults(CUInt(__VSPKGRESETFLAGS.PKGRF_TOOLBOXITEMS)) End Sub
private void MenuItemCallback(object sender, EventArgs e) { IVsPackage pkg = GetService(typeof(Package)) as Package; pkg.ResetDefaults((uint)__VSPKGRESETFLAGS.PKGRF_TOOLBOXITEMS); }
建置和執行方案
藉由在實驗登錄區中執行的 Visual Studio 的執行個體,您可以運用這項逐步解說的乘積。
若要執行這項逐步解說
在 Visual Studio,在建置 ] 功能表中,按一下 重建方案。
按 F5 以啟動的第二個執行個體Visual Studio的實驗登錄區中。
如需有關如何使用實驗登錄區的詳細資訊,請參閱實驗性的執行個體的 Visual Studio。
按一下 [工具] 功能表。
命令,名為初始化 LoadToolboxMembers VB 或初始化 LoadToolboxMembers CS 應該會出現在上方功能表中,加上有數字 1 的圖示。
建立新的Visual C#或Visual Basic Windows Form 應用程式。
A Form為基礎的設計工具應該會出現。
拖曳其中一個或多個新的控制項,在 LoadToolboxMembers 逐步解說 VB 或 LoadToolboxMembers 逐步解說 CS 類別的工具箱在表單設計工具中。
注意事項
如果工具箱 是沒有顯示,請按一下 [ 工具箱 的 檢視功能表。如果 VSPackage 的 [類別] 索引標籤沒有出現在工具箱,重新初始化 工具箱 ,即可 初始化 LoadToolboxMembers VB 或初始化 LoadToolboxMembers CS 的工具功能表。
建置 windows 應用程式,即可重建方案 的 建置功能表。
按一下其中一個執行的應用程式開始 或 以偵錯開始的 偵錯功能表。
當應用程式執行時,按一下其中一個控制項加入至應用程式。
訊息方塊出現,並顯示其中一個"Hello world from Company.LoadToolboxMembers.Control1"或 "Hello world from Company.LoadToolboxMembers.Control2"。
實作的分析
建立工具箱控制項
指定給屬性Control1和Control2方法會使用CreateItemList時它會查詢Assembly的可用工具箱控制項。
ToolboxItemAttribute會執行下列兩個功能:
該工作分派的ToolboxItemAttribute到Control1和Control2,這表示每一個都工具箱控制項。
引數為ToolboxItemAttribute建構函式,它會指示是否預設ToolboxItem或自訂的類別衍生自ToolboxItem時,控制項會使用工具箱。
執行個體ToolboxItemAttribute指派給Control1使用的引數來建立true,這表示它會使用預設的ToolboxItem類別時就會新增到工具箱。
執行個體的ToolboxItemAttribute ,係授與Control2由使用Type之類別的衍生自ToolboxItem, Control2_ToolboxItem。
ToolboxBitmapAttribute類別會指定環境所用來識別控制項的點陣圖。
將點陣圖內嵌在組件中,藉由設定其建置動作 屬性,以 內嵌資源將點陣圖放在組件的命名空間。 因此, Control1.bmp可以稱為Company.LoadToolboxMembers.Control1.bmp。
ToolboxBitmapAttribute支援這個完整的路徑,做為引數的建構函式。 例如, ToolboxBitmapAttribute類別,無法套用至Control1藉由使用[ToolboxBitmap("Company.LoadToolboxMembers.Control1.bmp")]。
若要支援的彈性,本逐步解說會使用建構函式可接受Type做為第一個引數類別ToolboxBitmapAttribute建構函式。 用來識別的點陣圖檔案的命名空間取自Type和點陣圖的主檔名的前面。
因為Type實作物件Package, LoadToolboxMembers,在Company.LoadToolboxMembers命名空間[ToolboxBitmap(typeof(Control1), "Control1.bmp")]相當於[ToolboxBitmap("Company.LoadToolboxMembers.Control1.bmp")]。
DisplayNameAttribute指定控制項的名稱工具箱。
正在註冊工具箱控制提供者
套用ProvideToolboxItemsAttribute類別來實作的類別Package會影響產生的 VSPackage 的登錄設定值。 如需有關的登錄設定ToolboxItem提供者,請參閱正在註冊工具箱支援功能。
Visual Studio環境中使用的版本引數ProvideToolboxItemsAttribute建構函式來管理快取提供的項目中的 VSPackages 工具箱。 已載入提供之後 VSPackage 工具箱項目、 快取版本的 VSPackage 用已註冊版以前的提供者的變更。因此,如果您想要修改這個逐步解說的產品,建之後,請確定若要變更 [版本] 引數的ProvideToolboxItemsAttribute建構函式,適用於AddToolboxItem。 例如, [ProvideToolboxItems(1)]應該變更為[ProvideToolboxItems(2)]。若未變更版本,然後在Visual Studio環境不會載入任何所做的修改。
在這個逐步解說中,VSPackage 被設定成只提供工具箱支援預設的剪貼簿格式的控制項。 如需預設剪貼簿格式的清單,請參閱工具箱 (Visual Studio SDK)。 如果您想要支援其他的剪貼簿格式,或決定不支援預設格式,請將屬性套用ProvideToolboxFormatAttribute到LoadToolboxMembersPackage類別。 如需有關登錄工具箱控制提供者,請參閱進階的工具箱控制項開發。
將控制項加入至工具箱
在 [功能CreateItemList模擬中可用System#Drawing#Design#IToolboxService#GetToolboxItems。
CreateItemList方法只會檢查非抽象Type物件的實作IComponent介面。
後續步驟
使用System#Drawing#Design#IToolboxService#GetToolboxItems而不是CreateItemList會使這項逐步解說產品更強大。
您也可以修改CreateItemList使用ParseToolboxResource載入控制項工具箱根據 [文字] 清單中內建LoadToolboxMembers組件。