Xtravia9
Xtravia9

Reputation: 63

Menu Item Custom Control Events

I am trying to create a menu list item that contains both a textbox and a label as a single item. In the code below I have made the necessary custom control class inherited from ToolStripControlHost and this looks and behaves as expected when created in the form menu.

The problem I am having is that the control's events are not firing the handler routine. In the example below, what I would expect to happen is that when the user types into the text box a message should show (other events have the same problem).

Thank you.

Control Classes:

Public Class ToolStripTextBoxWithLabel
Inherits ToolStripControlHost



Public Sub New(Optional ByVal lblText As String = "label")
    MyBase.New(New ControlPanel(lblText))

End Sub

Public ReadOnly Property ControlPanelControl() As ControlPanel
    Get
        Return CType(Me.Control, ControlPanel)
    End Get
End Property

End Class


Public Class ControlPanel
Inherits Panel

Friend WithEvents txt As New TextBox
Friend WithEvents lbl As New Label

Public Sub New(ByVal lblText As String)

    Me.Height = 20

    lbl.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Bottom
    lbl.Text = lblText
    lbl.TextAlign = ContentAlignment.BottomLeft
    lbl.AutoSize = True
    lbl.Height = Me.Height
    lbl.Location = New Point(0, 3)
    lbl.Parent = Me

    txt.Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
    txt.Location = New Point(lbl.Right + 3, 0)
    txt.Width = Me.Width - txt.Left
    txt.Parent = Me


End Sub

End Class

Form Implementation:

Public Class Form1

Friend tb_SearchBox As ToolStripTextBoxWithLabel



Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    tb_SearchBox = New ToolStripTextBoxWithLabel("Search:") With {.Name = "tb_SearchBox"}
    AddHandler tb_SearchBox.TextChanged, AddressOf tb_SearchBox_TextChanged

    Item1ToolStripMenuItem.DropDownItems.Add(tb_SearchBox)

End Sub

Private Sub tb_SearchBox_TextChanged(sender As Object, e As EventArgs)
    MsgBox("Success")
End Sub

End Class

Upvotes: 0

Views: 241

Answers (2)

Xtravia9
Xtravia9

Reputation: 63

Thanks to jmcilhinney and Plutonix I have put together the solution. For completeness and future community reference the full solution is below.

User Control:

Public Class CustomTextBox

Public Event TextBoxTextChanged As EventHandler

Protected Overridable Sub OnTextBoxTextChanged(e As EventArgs)
    RaiseEvent TextBoxTextChanged(Me, e)
End Sub

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    OnTextBoxTextChanged(EventArgs.Empty)
End Sub

Public Sub New (lblText as string)
    InitializeComponent()
    Caption = lblText
End Sub

Public Property Caption() As String
Get
    Return Label1.Text
End Get
Set(ByVal value As String)
    Label1.Text = value
End Set
End Property
Public Overrides Property Text() As String
Get
    Return TextBox1.Text
End Get
Set(ByVal value As String)
    TextBox1.Text = value
End Set
End Property

Public Class

Implementation:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    Dim SearchBox As New CustomTextBox("Search")
    Dim host As ToolStripControlHost = new ToolStripControlHost(windowNewMenu)
    AddHandler SearchBox.TextBoxTextChanged, AddressOf SearchBox_TextChanged
    ToolStripMenuItem1.DropDownItems.Add(host)

End Sub


Private Sub SearchBox_TextChanged(sender As Object, e As EventArgs)
    MsgBox(sender.Text)
End Sub

Upvotes: 0

jmcilhinney
jmcilhinney

Reputation: 54427

Using the TextChanged event of your ToolStripTextBoxWithLabel in this instance is inappropriate because that event should only be raised when the Text property of that object changes, which is not happening here. You need to do what Plutonix suggested but you should also do it with your own custom event rather than with the TextChanged event of the host, e.g.

Public Event TextBoxTextChanged As EventHandler

Protected Overridable Sub OnTextBoxTextChanged(e As EventArgs)
    RaiseEvent TextBoxTextChanged(Me, e)
End Sub

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    OnTextBoxTextChanged(EventArgs.Empty)
End Sub

Rather than deriving your ControlPanel class from Panel and creating the child controls in code, I would suggest that you create a user control and add the children in the designer. You would then use my answer below in two steps, i.e. the user control would handle the TextChanged event of the TextBox and then raise an event of its own that would, in turn, be handled by the ToolStripTextBoxWithLabel that would its own event.

Upvotes: 2

Related Questions