Finally, we need to Override the GetSortedActionItems function that returns a collection of DesignerActionItems (the items on the Smart-Tag panel). Instead of returning the default collection, we create a new DesignerActionItemCollection, and add new Headers (New DesignerActionHeaderItem), properties (New DesignerActionPropertyItem and methods (New DesignerActionMethodItem). At the end, we return our new collection.
But first, we need to determine if our Dock/Undock method needs to display either "Dock" or "Undock" in its display title. This is simple enough with a normal If/Else construction. Just save the desired text into a String, which you pass as the Display title to the DesignerActionMethodItem.
The DesignerActionHeaderItems are easy enough: they only require one parameter, the displayName which is simply the name they will display on the Smart-Tag panel. These will be our categories, so take care to type them correctly.
The DesignerActionPropertyItems need a few more parameters:
- memberName: the name of the property you have created above.
- displayName: the name that will be displayed on the panel.
- category: the name (displayName) of the category (Header) you (may) have created. Leave this empty ("") to put it outside of any categories).
- description: the description that will show in a ToolTip if you hover your mouse over this item.
The DesignerActionMethodItems need one more parameter (the first one), namely the actionList property. You should pass the current DesignerActionList (Me) to this property.
Finally, we return this new collection:
vb.net Code:
Public Overrides Function GetSortedActionItems() As System.ComponentModel.Design.DesignerActionItemCollection
Dim str As String
Dim items As New DesignerActionItemCollection
If txt.Dock = DockStyle.Fill Then
str = "Undock in parent container."
Else
str = "Dock in parent container."
End If
'Add a few Header Items (categories)
items.Add(New DesignerActionHeaderItem("Category 1"))
items.Add(New DesignerActionHeaderItem("Category 2"))
'Add the properties
items.Add(New DesignerActionPropertyItem("Text", "Text", "Category 1", "Gets or sets the Text of the customTextBox."))
items.Add(New DesignerActionPropertyItem("Font", "Font", "Category 1", "Gets or sets the Font of the customTextBox."))
items.Add(New DesignerActionPropertyItem("BackColor", "BackColor", "Category 1", "Gets or sets the BackColor of the customTextBox."))
items.Add(New DesignerActionPropertyItem("MultiLine", "Multi-line", "Category 1", "Gets or sets the Multi-line property of the customTextBox."))
'Add the methods
items.Add(New DesignerActionMethodItem(Me, "OnClear", "Clear text", "Category 2", "Clears the text in the customTextBox."))
If txt.Multiline Then
items.Add(New DesignerActionMethodItem(Me, "OnMakeSquare", "Make a square", "Category 2", "Changes the width or height of the customTextBox to resemble a square."))
items.Add(New DesignerActionMethodItem(Me, "OnDock", str, "Category 2", "Docks or undocks the customTextBox in the parent container."))
End If
'Return the ActionItemCollection
Return items
End Function
(Note that I have added a few more items in this piece of code, which is straight from my example)
We are almost finished! The last thing we need to do (the thing I always forget
) is to tell our custom control or UserControl to actually use our Designer class! To do this, we need to add a System.ComponentModel.Designer attribute at the top of our class, to which we pass the type of our custom Designer class as a parameter:
vb.net Code:
<System.ComponentModel.Designer(GetType(customTextBoxDesigner))> _
Public Class customTextBox
Inherits TextBox
End Class
If you now Build your solution, drop the customTextBox on your form, and click the little arrow in the top-right corner, the Smart-Tags should pop up!

I have attached an example project (for VS2008 or higher), and in the next post I have posted the entire code for the Designer class (including the DesignerActionList class), so you shouldn't have any trouble incorporating this into your own control!
Still, if you have any questions, suggestions, or otherwise, just leave me a message here and I'll try to see if I can help you.
Enjoy it..!
Code:
Imports System.Windows.Forms.Design
Imports System.ComponentModel.Design
Imports System.ComponentModel
Public Class customTextBoxDesigner
Inherits ControlDesigner
Private _actionListCollection As DesignerActionListCollection
Public Overrides ReadOnly Property ActionLists() As System.ComponentModel.Design.DesignerActionListCollection
Get
If _actionListCollection Is Nothing Then
_actionListCollection = New DesignerActionListCollection()
_actionListCollection.Add(New TextBoxActionList(Me.Control))
End If
Return _actionListCollection
End Get
End Property
End Class
Friend Class TextBoxActionList
Inherits DesignerActionList
Private txt As customTextBox
Private designerActionSvc As DesignerActionUIService
Public Sub New(ByVal component As IComponent)
MyBase.New(component)
txt = DirectCast(component, customTextBox)
designerActionSvc = CType(GetService(GetType(DesignerActionUIService)), DesignerActionUIService)
End Sub
#Region " Properties to display in the Smart-Tag panel "
Public Property Text() As String
Get
Return txt.Text
End Get
Set(ByVal value As String)
txt.Text = value
End Set
End Property
Public Property Font() As Font
Get
Return txt.Font
End Get
Set(ByVal value As Font)
txt.Font = value
End Set
End Property
Public Property BackColor() As Color
Get
Return txt.BackColor
End Get
Set(ByVal value As Color)
txt.BackColor = value
End Set
End Property
Public Property MultiLine() As Boolean
Get
Return txt.Multiline
End Get
Set(ByVal value As Boolean)
txt.Multiline = value
designerActionSvc.Refresh(txt)
End Set
End Property
#End Region
#Region " Methods to display in the Smart-Tag panel "
Public Sub OnClear()
txt.Clear()
End Sub
Public Sub OnMakeSquare()
If txt.Multiline Then
If txt.Width >= txt.Height Then
txt.Height = txt.Width
Else
txt.Width = txt.Height
End If
designerActionSvc.Refresh(txt)
End If
End Sub
Public Sub OnDock()
If txt.Dock = DockStyle.Fill Then
txt.Dock = DockStyle.None
Else
txt.Dock = DockStyle.Fill
End If
designerActionSvc.Refresh(txt)
End Sub
#End Region
Public Overrides Function GetSortedActionItems() As System.ComponentModel.Design.DesignerActionItemCollection
Dim str As String
Dim items As New DesignerActionItemCollection
If txt.Dock = DockStyle.Fill Then
str = "Undock in parent container."
Else
str = "Dock in parent container."
End If
'Add a few Header Items (categories)
items.Add(New DesignerActionHeaderItem("Category 1"))
items.Add(New DesignerActionHeaderItem("Category 2"))
'Add the properties
items.Add(New DesignerActionPropertyItem("Text", "Text", "Category 1", "Gets or sets the Text of the customTextBox."))
items.Add(New DesignerActionPropertyItem("Font", "Font", "Category 1", "Gets or sets the Font of the customTextBox."))
items.Add(New DesignerActionPropertyItem("BackColor", "BackColor", "Category 1", "Gets or sets the BackColor of the customTextBox."))
items.Add(New DesignerActionPropertyItem("MultiLine", "Multi-line", "Category 1", "Gets or sets the Multi-line property of the customTextBox."))
'Add the methods
items.Add(New DesignerActionMethodItem(Me, "OnClear", "Clear text", "Category 2", "Clears the text in the customTextBox."))
If txt.Multiline Then
items.Add(New DesignerActionMethodItem(Me, "OnMakeSquare", "Make a square", "Category 2", "Changes the width or height of the customTextBox to resemble a square."))
items.Add(New DesignerActionMethodItem(Me, "OnDock", str, "Category 2", "Docks or undocks the customTextBox in the parent container."))
End If
'Return the ActionItemCollection
Return items
End Function
End Class