VB.NET  •  Build the Search Panel

Listing 1. The SearchRadioPanel derives from Windows.Forms.Panel, so it starts out as a simple container. The calling form creates the SearchRadioButtons and adds them to the control dynamically. You must initialize the controls that are private to the form. The result is a modified panel that provides useful functionality to your application.

Private Sub InitializeControl()
   Me.SuspendLayout()

   mSearchRadioButtons = New _
      SearchRadioButtonCollection
   mSearchRadioButtons.Container = Me

   PnlBack = New Windows.Forms.Panel
   PnlBack.BackColor = _
      Drawing.SystemColors.ActiveCaption
   PnlBack.BorderStyle = _
      Forms.BorderStyle.Fixed3D
   Me.Controls.Add(PnlBack)

   PnlSearch = New Windows.Forms.Panel
   PnlSearch.BorderStyle = _
      Forms.BorderStyle.FixedSingle
   PnlSearch.Height = 0
   PnlSearch.BackColor = _
      Drawing.SystemColors.Control
   PnlBack.Controls.Add(PnlSearch)

   BtnGo = New Windows.Forms.Button
   BtnGo.Text = "GO !"
   BtnGo.Name = "btnGo"
   BtnGo.Width = 50
   BtnGo.Anchor = Forms.AnchorStyles.Right Or _
      Forms.AnchorStyles.Top
   PnlSearch.Controls.Add(BtnGo)

   Me.ResumeLayout()

End Sub

Protected Overrides Sub OnControlAdded( _
   ByVal e As _
   System.Windows.Forms.ControlEventArgs)
   MyBase.OnControlAdded(e)
   Dim rdo As SearchRadioButton
   If TypeOf e.Control Is SearchRadioButton Then
      rdo = CType(e.Control, SearchRadioButton)
      AddHandler rdo.CheckedChanged, AddressOf _
         OnRadioButtonChanged
      AddHandler rdo.Click, AddressOf _
         OnRadioButtonClick
   End If
   End Sub

Protected Overridable Sub _
   OnRadioButtonChanged(ByVal sender As _
   Object, ByVal e As EventArgs)
   ' Drop down search
   Dim rdo As SearchRadioButton
   If TypeOf sender Is SearchRadioButton Then
      rdo = CType(sender, SearchRadioButton)
      If rdo.Checked And Not rdo.WasChecked Then
         RollOutSearch(rdo)
      Else
         rdo.WasChecked = False
         RollUpSearch()
      End If
   End If
End Sub

Protected Overridable Sub OnRadioButtonClick( _
   ByVal sender As Object, ByVal e As EventArgs)
   Dim rdo As SearchRadioButton
   If TypeOf sender Is SearchRadioButton Then
      rdo = CType(sender, SearchRadioButton)
      If rdo.WasChecked Then
      RaiseEvent CancelSearch(Me, New _
         System.EventArgs)
         rdo.Checked = False
      Else
         rdo.WasChecked = True
      End If
   End If
   End Sub

   Private Sub RollUpSearch()
   PnlBack.Visible = False
   Me.Height = ButtonHeight
End Sub

Private Sub RollOutSearch(ByVal rdo As _
   SearchRadioButton)
   Dim lbl As Windows.Forms.Label
   Dim txt As Windows.Forms.TextBox
   Dim left As Int32
   Dim top As Int32 = margin
   PnlBack.Visible = True
   If Not PnlSearch.Tag Is rdo Then
      PnlSearch.Tag = rdo
      PnlSearch.Controls.Clear()
      PnlSearch.Controls.Add(BtnGo)
      For Each criteria As Criteria In _
         rdo.CriteriaCollection
         lbl = New Windows.Forms.Label
         lbl.Location = New Drawing.Point( _
            margin, top)
         lbl.Text = criteria.Caption
         left = lbl.Right
         PnlSearch.Controls.Add(lbl)
         txt = New Windows.Forms.TextBox
         txt.Location = New Drawing.Point(left, _
            top)
         txt.Width = Me.Width - left - _
            BtnGo.Width - 5 * margin
         txt.Anchor = Forms.AnchorStyles.Top Or _
            Forms.AnchorStyles.Left Or _
            Forms.AnchorStyles.Right
         txt.Tag = criteria
         PnlSearch.Controls.Add(txt)
         lbl.Height = txt.Height
         top += txt.Height
      Next
      If top < 30 Then
         top = 30
      End If
      If Not txt Is Nothing Then
         BtnGo.Location = New _
            Drawing.Point(txt.Right + margin, _
            margin)
         BtnGo.Height = top - margin
      End If
   Else
      top = BtnGo.Bottom + margin
   End If
   top += margin
   PnlSearch.Height = top
   PnlBack.Height = PnlSearch.Height + CInt(2 * _
      margin)
   Me.Height = PnlBack.Bottom
End Sub

Protected Overridable Sub OnBtnGoClick(ByVal _
   sender As Object, ByVal e As EventArgs) _
   Handles BtnGo.Click
   RaiseEvent GoSearch(Me, New System.EventArgs)
   Me.GetCurrent.Checked = False
End Sub