Vb.net 菜单项自定义控件事件

Vb.net 菜单项自定义控件事件,vb.net,winforms,Vb.net,Winforms,我正在尝试创建一个菜单列表项,其中包含一个文本框和一个标签作为单个项。在下面的代码中,我创建了从ToolStripControlHost继承的必要自定义控件类,该类在表单菜单中创建时的外观和行为与预期一致 我遇到的问题是控件的事件没有触发处理程序例程。在下面的示例中,我希望发生的是,当用户在文本框中键入时,会显示一条消息(其他事件也有相同的问题) 多谢各位 控制类: Public Class ToolStripTextBoxWithLabel Inherits ToolStripControlH

我正在尝试创建一个菜单列表项,其中包含一个文本框和一个标签作为单个项。在下面的代码中,我创建了从ToolStripControlHost继承的必要自定义控件类,该类在表单菜单中创建时的外观和行为与预期一致

我遇到的问题是控件的事件没有触发处理程序例程。在下面的示例中,我希望发生的是,当用户在文本框中键入时,会显示一条消息(其他事件也有相同的问题)

多谢各位

控制类:

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
表格实施:

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
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

在本例中使用
ToolStripTextBoxWithLabel
TextChanged
事件是不合适的,因为只有当该对象的
Text
属性更改时才应引发该事件,而此处不发生这种情况。您需要按照Puropoix的建议进行操作,但也应该使用您自己的自定义事件,而不是主机的
TextChanged
事件,例如

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

与其从
Panel
派生
ControlPanel
类并在代码中创建子控件,我建议您创建一个用户控件并在设计器中添加子控件。然后,您将分两步使用我下面的答案,即用户控件将处理
TextBox
TextChanged
事件,然后引发自己的事件,反过来,由
ToolStripTextBoxWithLabel
处理,它将处理自己的事件。

在本例中,使用
ToolStripTextBoxWithLabel
文本更改事件是不合适的,因为该事件只应在该对象的
文本
属性更改时引发,而此处不发生此情况。您需要按照Puropoix的建议进行操作,但也应该使用您自己的自定义事件,而不是主机的
TextChanged
事件,例如

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

与其从
Panel
派生
ControlPanel
类并在代码中创建子控件,我建议您创建一个用户控件并在设计器中添加子控件。然后,您将分两步使用我下面的答案,即用户控件将处理
TextBox
TextChanged
事件,然后引发自己的事件,反过来,由带有标签的
ToolStripTextBoxWithLabel处理。

多亏了jmcilhinney和Puropoix,我才制定了解决方案。为了完整性和将来的社区参考,完整的解决方案如下

用户控制:

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
实施:

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
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

多亏了jmcilhinney和PUROTIX,我才找到了解决方案。为了完整性和将来的社区参考,完整的解决方案如下

用户控制:

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
实施:

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
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

您的
控制面板
类未引发任何事件。它需要订阅子控件上的任何事件,然后在控件触发它们时引发自己的事件。这有时称为“冒泡事件”,您的
控制面板
类不会引发任何事件。它需要订阅子控件上的任何事件,然后在控件触发它们时引发自己的事件。这有时被称为“冒泡事件”该死,你太快了。刚刚发布了一个类似的答案该死,你跑得太快了。刚刚发布了一个类似的答案