Windows Develop Bookmark and Share   
 index > Windows Forms Designer > Custom Combobox SmartTag
 

Custom Combobox SmartTag

Hi,

I'm looking for a sample of how to add a custom combo box smarttag to a control I have written.

The control is used in a search routine. The programmer drops on the control onto the form and sets some options for the control, it's then polled during program execution in order to build a search string.

What I want to do is have a combo box on the smart tag with three options 'Leading Wildcard', 'Trailing Wildcard' , 'Both Wildcards' and read that value later on.

Below is what I have to date but it's not working properly, I end up with a strange 'combo within a combo' that doesn't return what I expect and it doesn't work properly. Some of the code here is from other examples I've found online...I don't claim to completly get it all as yet.

Any help or direction to a good example would be appreciated!

Thanks in advance

Evan

Code Block

#Region " Smart Tag Design Time Extension "

Public Class SearchDateTimeDesigner
Inherits System.Windows.Forms.Design.ControlDesigner

Private lists As DesignerActionListCollection

Public Overrides ReadOnly Property ActionLists() As DesignerActionListCollection
Get
If lists Is Nothing Then
lists = New DesignerActionListCollection()
lists.Add(New ActionList(Me.Component))
End If
Return lists
End Get
End Property

End Class

Public Class ActionList
Inherits System.ComponentModel.Design.DesignerActionList

'---reference to the custom control
Private Cntrl As SearchDateTime
'---reference to DesignerActionUIService
Private designerActionSvc As DesignerActionUIService = Nothing

'associate the control with the smart tag list
Public Sub New(ByVal component As IComponent)
MyBase.New(component)
Me.Cntrl = component
Me.designerActionSvc = CType(GetService(GetType(DesignerActionUIService)), DesignerActionUIService)
End Sub

' utility function to re
Private Function GetPropertyByName(ByVal propName As String) As PropertyDescriptor
Dim prop As PropertyDescriptor
prop = TypeDescriptor.GetProperties(Cntrl)(propName)
If prop Is Nothing Then
Throw New ArgumentException("Invalid property.", propName)
Else
Return prop
End If
End Function

'*** Properties that the smarttags call

'The Editor property overrides the default type in favour of the derived class
<Editor(GetType(SearchWildcard), GetType(System.Drawing.Design.UITypeEditor))> _
Public Property SearchWildcard() As String
Get
Select Case Cntrl.SearchWildcard
Case SearchArgumentWildcard.LeadingWildcard
Return SearchArgumentWildcard.LeadingWildcard
Case SearchArgumentWildcard.TrailingWildcard
Return SearchArgumentWildcard.TrailingWildcard
Case SearchArgumentWildcard.LeadingAndTrailingWildcard
Return SearchArgumentWildcard.LeadingAndTrailingWildcard
Case Else
Return SearchArgumentWildcard.None
End Select
End Get
Set(ByVal value As String)
Select Case value
Case "Leading"
Cntrl.SearchWildcard = SearchArgumentWildcard.LeadingWildcard
Case "Trailing"
Cntrl.SearchWildcard = SearchArgumentWildcard.TrailingWildcard
Case "Leading and Trailing"
Cntrl.SearchWildcard = SearchArgumentWildcard.LeadingAndTrailingWildcard
Case Else
Cntrl.SearchWildcard = SearchArgumentWildcard.None
End Select
End Set
End Property

Public Property SearchDBField() As String
Get
Return Cntrl.DataField
End Get
Set(ByVal value As String)
Cntrl.DataField = value
End Set
End Property

'Attach the smarttag items
Public Overrides Function GetSortedActionItems() As DesignerActionItemCollection
Dim items As New DesignerActionItemCollection()

'Define designer action header
'items.Add(New DesignerActionHeaderItem("Search Settings"))

'items.Add(New DesignerActionPropertyItem("AutoSize", "Auto Size", "Appearance", "Auto sizes the control"))

'If Not AutoSize Then
' items.Add(New DesignerActionHeaderItem("Size"))

' items.Add(New DesignerActionPropertyItem("Width", "Width", "Size", "Sets the width of the control"))

' items.Add(New DesignerActionPropertyItem("Height", "Height", "Size", "Sets the height of the control"))
'End If

items.Add(New DesignerActionPropertyItem("SearchDBField", "Database Field", "Search Settings", "DB Field to search against"))

items.Add(New DesignerActionPropertyItem("SearchWildcard", "Wildcard Type", "Search Settings", "Wildcards to Apply"))

'items.Add(New DesignerActionPropertyItem("Image", "Button Image", "Appearance", "Sets the image of the button."))

'items.Add(New DesignerActionPropertyItem("ImageAlign", "Button Image Alignment", "Appearance", "Sets the alignment of image of the button."))

Return items
End Function

End Class

Public Class SearchWildcard
Inherits PropertyEditorBase

'Private WithEvents myCombo As New ComboBox

Private MyUserControl As New UserControl1

Protected Overrides Function GetEditControl(ByVal PropertyName As String, ByVal CurrentValue As Object) As System.Windows.Forms.Control

'With myCombo.Items
' .Clear()
' .Add("") '0
' .Add("Leading") '1
' .Add("Trailing") '2
' .Add("Leading and Trailing") '3
'End With

'myCombo.SelectedIndex = 0
'myCombo.Height = myCombo.PreferredHeight

Return MyUserControl

'Return myCombo

End Function

Protected Overrides Function GetEditedValue(ByVal EditControl As System.Windows.Forms.Control, ByVal PropertyName As String, ByVal OldValue As Object) As Object
'Return myCombo.SelectedText.ToString
Return MyUserControl.txtDataField.ToString
End Function
End Class


#End Region

#Region " Drop Down Property Editor Base "
''' <summary>
''' This is a UITypeEditor base class usefull for simple editing of control
''' properties in a DropDown at design mode (in Visual Studio IDE).
''' To use this, inherits a class from it and add this attribute to your control property(ies):
''' Editor(GetType(MyPropertyEditor),GetType(System.Drawing.Design.UITypeEditor))
''' </summary>
Public MustInherit Class PropertyEditorBase
Inherits System.Drawing.Design.UITypeEditor

''' <summary>
''' The driven class should provide its edit Control to be shown in the
''' DropDown or DialogForm window by means of this function.
''' If specified control be a Form, it is shown in a Modal Form, otherwise
''' in a DropDown window. This edit control should return its final value
''' at GetEditedValue() method.
''' </summary>
Protected MustOverride Function GetEditControl(ByVal PropertyName As String, ByVal CurrentValue As Object) As Control

''' <summary>The driven class should return the New Edited Value at this
''' function.</summary>
''' <param name="EditControl">
''' The control shown in DropDown window and used for editing.
''' This is the control you pass in GetEditControl() function.
''' </param>
''' <param name="OldValue">The original value of the property before
''' editing</param>
Protected MustOverride Function GetEditedValue(ByVal EditControl As Control, ByVal PropertyName As String, ByVal OldValue As Object) As Object

Protected IEditorService As IWindowsFormsEditorService
Private WithEvents m_EditControl As Control
Private m_EscapePressed As Boolean

''' <summary>
''' Sets the edit style mode based on the type of EditControl: DropDown or
''' Modal(Dialog).
''' Note that the driven class can also override this function and
''' explicitly set its value.
''' </summary>
Public Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
'Return UITypeEditorEditStyle.DropDown
Return UITypeEditorEditStyle.None
End Function

'Displays the Custom UI (a DropDown Control or a Modal Form) for value
'selection.
Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As IServiceProvider, ByVal value As Object) As Object
Try
If context IsNot Nothing AndAlso provider IsNot Nothing Then

'Uses the IWindowsFormsEditorService to display a drop-down
'UI in the Properties window:
IEditorService = DirectCast(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)

If IEditorService IsNot Nothing Then
Dim PropName As String = context.PropertyDescriptor.Name
'get Edit Control from driven class
m_EditControl = Me.GetEditControl(PropName, value)
If m_EditControl IsNot Nothing Then
m_EscapePressed = False
IEditorService.DropDownControl(m_EditControl)

If m_EscapePressed Then 'return the Old Value
'(because user press Escape)
Return value
Else 'get new (edited) value from driven class and
'return it
Return GetEditedValue(m_EditControl, PropName, value)
End If
End If 'm_EditControl
End If 'IEditorService
End If 'context And provider

Catch ex As Exception
'we may show a MessageBox here...
End Try
Return MyBase.EditValue(context, provider, value)

End Function

''' <summary>
''' Provides the interface for this UITypeEditor to display Windows Forms
''' or to display a control in a DropDown area from the property grid
''' control in design mode.
''' </summary>
Public Function GetIWindowsFormsEditorService() As IWindowsFormsEditorService
Return IEditorService
End Function

''' <summary>Close DropDown window to finish editing</summary>
Public Sub CloseDropDownWindow()
If IEditorService IsNot Nothing Then IEditorService.CloseDropDown()
End Sub

Private Sub m_EditControl_PreviewKeyDown(ByVal sender As Object, ByVal e As PreviewKeyDownEventArgs) Handles m_EditControl.PreviewKeyDown
If e.KeyCode = Keys.Escape Then m_EscapePressed = True
End Sub

End Class

#End Region


EvanY  Thursday, October 25, 2007 6:34 PM

Here is an example for creating a smart-tag to your custom control, it conatins MyUserControl, user control with nothing but a property: MyQueryType (which is an enum). The smarttag allows users to change this property. Its in C# but I don't think you will have too much truble changing it to VB.NET

using System;

using System.Windows.Forms;

using System.ComponentModel;

using System.Windows.Forms.Design;

using System.ComponentModel.Design;

namespace WindowsApplication1

{

public enum MyQueryType

{

LeadingWildcard,

TrailingWildcard,

BothWildcards

}

[Designer(typeof(MyUserControlDesigner))]

public partial class MyUserControl : UserControl

{

private MyQueryType _queryType = MyQueryType.LeadingWildcard;

public MyQueryType QueryType

{

get { return _queryType; }

set { _queryType = value; }

}

public MyUserControl()

{

}

}

public class MyUserControlDesigner : ControlDesigner

{

public override DesignerActionListCollection ActionLists

{

get

{

// Create action list collection

DesignerActionListCollection actionLists =

new DesignerActionListCollection();

// Add custom action list

actionLists.Add(

new MyUserControlDesignerActionList(this.Component));

// Return to the designer action service

return actionLists;

}

}

}

public class MyUserControlDesignerActionList : DesignerActionList

{

public MyUserControlDesignerActionList(IComponent comp) : base(comp)

{

}

// Face property

public MyQueryType QueryType

{

get { return ((MyUserControl)this.Component).QueryType; }

set { ((MyUserControl)this.Component).QueryType = value; }

}

public override DesignerActionItemCollection GetSortedActionItems()

{

DesignerActionItemCollection actionItems = new DesignerActionItemCollection();

// Add Face designer action property item

actionItems.Add(new DesignerActionPropertyItem("QueryType", "Query Type"));

return actionItems;

}

}

}

Eli Gazit  Thursday, October 25, 2007 10:32 PM

Here is an example for creating a smart-tag to your custom control, it conatins MyUserControl, user control with nothing but a property: MyQueryType (which is an enum). The smarttag allows users to change this property. Its in C# but I don't think you will have too much truble changing it to VB.NET

using System;

using System.Windows.Forms;

using System.ComponentModel;

using System.Windows.Forms.Design;

using System.ComponentModel.Design;

namespace WindowsApplication1

{

public enum MyQueryType

{

LeadingWildcard,

TrailingWildcard,

BothWildcards

}

[Designer(typeof(MyUserControlDesigner))]

public partial class MyUserControl : UserControl

{

private MyQueryType _queryType = MyQueryType.LeadingWildcard;

public MyQueryType QueryType

{

get { return _queryType; }

set { _queryType = value; }

}

public MyUserControl()

{

}

}

public class MyUserControlDesigner : ControlDesigner

{

public override DesignerActionListCollection ActionLists

{

get

{

// Create action list collection

DesignerActionListCollection actionLists =

new DesignerActionListCollection();

// Add custom action list

actionLists.Add(

new MyUserControlDesignerActionList(this.Component));

// Return to the designer action service

return actionLists;

}

}

}

public class MyUserControlDesignerActionList : DesignerActionList

{

public MyUserControlDesignerActionList(IComponent comp) : base(comp)

{

}

// Face property

public MyQueryType QueryType

{

get { return ((MyUserControl)this.Component).QueryType; }

set { ((MyUserControl)this.Component).QueryType = value; }

}

public override DesignerActionItemCollection GetSortedActionItems()

{

DesignerActionItemCollection actionItems = new DesignerActionItemCollection();

// Add Face designer action property item

actionItems.Add(new DesignerActionPropertyItem("QueryType", "Query Type"));

return actionItems;

}

}

}

Eli Gazit  Thursday, October 25, 2007 10:32 PM

You can use google to search for other answers

Custom Search

More Threads

• how to make "About" form a cool flat one?
• Changing the font color in a RichTextBox
• Treeview control
• Dropping controls in a custom UserControl
• Windows Form Designer Fails to Load
• manual position of Form2 from Form1
• Design time only property
• Programatically setting the column widths in a TableLayoutPanel.
• Create Popup Alert
• puzzle to the window designer in vs2005