2017-03-03 132 views
0

我想創建一個菜單列表項,它包含一個文本框和一個標籤作爲單個項目。在下面的代碼中,我已經從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 
+1

你'ControlPanel'class沒有引發任何事件。它需要訂閱子控件上的任何事件,然後在控件觸發時自行提升。這有時被稱爲「冒泡事件」 – Plutonix

回答

2

使用在這種情況下,TextChanged事件您ToolStripTextBoxWithLabel的是不適當的,因爲該事件應該只提出在該對象的Text財產在這裏沒有發生變化。您需要完成Plutonix的建議,但您也應該使用您自己的自定義事件來完成,而不是使用主機的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類,並在代碼中創建子控件相反,我建議你創建一個用戶控件,並在設計中添加的孩子。然後,您可以分兩步使用我的答案,即用戶控件將處理TextBoxTextChanged事件,然後引發自己的事件,然後由ToolStripTextBoxWithLabel處理它自己的事件。

+0

該死,你太快了。剛剛發佈了類似的答案。 ;) –

0

感謝jmcilhinney和Plutonix我已經把解決方案放在一起。爲了完整性和未來的社區參考,下面是完整的解決方案。

用戶控制:

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 

實現:

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