0

i have class inherited from textbox , and when i try to add the control from the toolbox i have this error in the picture.

this is class inherited from textbox control ,using listbox control to choose from auto complete list

Public Structure Account
    Dim Name As String
    Dim Number As String
    Public Sub New(Namee As String, Num As String)
        Name = Namee
        Number = Num
    End Sub

    Public Overrides Function ToString() As String
        Return Name
    End Function
End Structure
Public Class AutoCompleteTextBox
    Inherits TextBox
    Private ACL As List(Of Account), CACL As List(Of Account)
    Private CaseSensitive As Boolean
    Private MinChar As Integer

    Private LS As ListBox
    Private OLDText As String
    Private PN As Panel

    Public Sub New()
        MyBase.New
            MinTypedCharacters = 2
        CaseSesitivity = False
        ACL = New List(Of Account)

        LS = New ListBox
        LS.Name = "SeggestionListBox"
        LS.Font = Font
        LS.Visible = True

        PN = New Panel
        PN.Visible = False
        PN.Font = Font
        PN.AutoSizeMode = AutoSizeMode.GrowAndShrink
        PN.ClientSize = New Size(1, 1)
        PN.Name = "SeggestionPanel"
        PN.Padding = New Padding(0, 0, 0, 0)
        PN.Margin = New Padding(0, 0, 0, 0)
        PN.BackColor = Color.Transparent
        PN.ForeColor = Color.Transparent
        PN.PerformLayout()
        If Not PN.Controls.Contains(LS) Then
            PN.Controls.Add(LS)
        End If
        LS.Dock = DockStyle.Fill
        LS.SelectionMode = SelectionMode.One

        AddHandler LS.KeyDown, AddressOf LS_KeyDown
        AddHandler LS.MouseClick, AddressOf LS_MouseClick
        AddHandler LS.MouseDoubleClick, AddressOf LS_MouseDoubleClick

        CACL = New List(Of Account)
        LS.DataSource = CACL
        OLDText = Text

    End Sub

#Region "Properties"

    Public Property AutoCompleteList As List(Of Account)
        Get
            Return ACL
        End Get
        Set(value As List(Of Account))
            ACL.Clear()
            ACL = value
        End Set
    End Property

    Public Property CaseSesitivity As Boolean
        Get
            Return CaseSensitive
        End Get
        Set(value As Boolean)
            CaseSensitive = value
        End Set
    End Property

    Public Property MinTypedCharacters As Integer
        Get
            Return MinChar
        End Get
        Set(value As Integer)
            MinChar = value
        End Set
    End Property

    Public Property SelectedIndex As Integer
        Get
            Return LS.SelectedIndex
        End Get
        Set(value As Integer)
            If LS.Items.Count <> 0 Then
                LS.SelectedIndex = value
            End If
        End Set
    End Property

    Private ReadOnly Property ParentForm As Form
        Get
            Return Me.Parent.FindForm
        End Get
    End Property

#End Region

    Public Sub HideSuggestionListBox()
        If Not ParentForm Is Nothing Then
            PN.Hide()
            If ParentForm.Controls.Contains(PN) Then
                ParentForm.Controls.Remove(PN)
            End If
        End If
    End Sub

    Private Function SelectItem() As Boolean
        If LS.Items.Count > 0 AndAlso LS.SelectedIndex > -1 Then
            Text = LS.SelectedItem.ToString

            HideSuggestionListBox()
        End If
        Return True
    End Function
        Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
        If e.KeyCode = Keys.Up Then
            MoveSelection(SelectedIndex - 1)
            e.Handled = True
        ElseIf e.KeyCode = Keys.Down Then
            MoveSelection(SelectedIndex + 1)
            e.Handled = True
        ElseIf e.KeyCode = Keys.PageUp Then
            MoveSelection(SelectedIndex - 10)
            e.Handled = True
        ElseIf e.KeyCode = Keys.PageDown Then
            MoveSelection(SelectedIndex + 10)
            e.Handled = True
        ElseIf e.KeyCode = Keys.Enter Then
            SelectItem()
            e.Handled = True
        Else
            MyBase.OnKeyDown(e)
        End If

    End Sub

    Protected Overrides Sub OnLostFocus(e As EventArgs)
        If Not PN.ContainsFocus Then
            MyBase.OnLostFocus(e)
            If Not CheckItem(Text) Then
                Text = ""
            End If
            HideSuggestionListBox()
        End If

    End Sub
    Protected Overrides Sub OnTextChanged(e As EventArgs)
        If Not DesignMode Then
            ShowSuggests()
        End If
        MyBase.OnTextChanged(e)
        OLDText = Text
    End Sub
    Private Sub LS_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
        If (e.KeyCode = Keys.Enter) Then
            Me.SelectItem()
            e.Handled = True
        End If
    End Sub

    Private Sub LS_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
        ' select the current item
        Me.SelectItem()
        MsgBox(LS.SelectedItem.number)
    End Sub

    Private Sub LS_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)

        Me.SelectItem()
    End Sub
    Private Function CheckItem(ItemSTR As String) As Boolean
        For Each STR As Account In ACL
            If ItemSTR.ToLower = STR.ToString.ToLower Then
                Return True
                Exit Function
            End If
        Next
        Return False
    End Function

    Private Sub MoveSelection(Index As Integer)
        If Index <= -1 Then
            SelectedIndex = 0
        ElseIf Index > (LS.Items.Count - 1) Then
            SelectedIndex = LS.Items.Count - 1
        Else
            SelectedIndex = Index
        End If
    End Sub

    Private Sub ShowSuggests()
        If Text.Length >= MinTypedCharacters Then
            PN.SuspendLayout()
            If Text.Length > 0 AndAlso OLDText = Text.Substring(0, Text.Length - 1) Then
                UpdateCurrentAutoCompleteList()

            ElseIf OLDText.Length > 0 AndAlso Text = OLDText.Substring(0, OLDText.Length - 1) Then
                UpdateCurrentAutoCompleteList()
            Else
                UpdateCurrentAutoCompleteList()
            End If

            If Not CACL Is Nothing AndAlso CACL.Count > 0 Then
                PN.Show()
                PN.BringToFront()
                Focus()
            Else
                HideSuggestionListBox()
            End If
            PN.ResumeLayout()
        Else
            HideSuggestionListBox()
        End If
    End Sub

    Private Sub UpdateCurrentAutoCompleteList()
        CACL.Clear()
        For Each STR As Account In ACL
            If CaseSesitivity = True Then
                If STR.ToString.IndexOf(Text) > -1 Then
                    CACL.Add(STR)
                End If
            Else
                If STR.ToString.ToLower.IndexOf(Text.ToLower) > -1 Then
                    CACL.Add(STR)
                End If
            End If
        Next
        If CACL.Count > 0 Then
            UpdateListBoxItems()
        Else
            HideSuggestionListBox()
        End If

    End Sub

    Private Sub UpdateListBoxItems()
        If Not ParentForm Is Nothing Then
            PN.Width = Width
            'PN.Height = ParentForm.ClientSize.Height - Height - Location.Y
            Dim F As Integer = ParentForm.ClientSize.Height - Height - Location.Y
            Dim Ten As Integer = Font.Height * 10
            Dim CUr As Integer = Font.Height * (CACL.Count + 1)
            If F < CUr Then
                PN.Height = F
            ElseIf CUr < Ten Then
                PN.Height = CUr
            ElseIf Ten < F Then
                PN.Height = Ten
            Else
                PN.Height = F
            End If

            'PN.Height = Font.Height * 10
            PN.Location = Location + New Size(0, Height)
            If Not ParentForm.Controls.Contains(PN) Then
                ParentForm.Controls.Add(PN)
            End If
            CType(LS.BindingContext(CACL), CurrencyManager).Refresh()
        End If
    End Sub

End Class

Error

firstly i used list(of string) before using the structure account . the problem appears after using the structure

Any Idea about this error ?

**** additional picture show another problem after substitutes the structure with class and adds attribute.

enter image description here

***** changed the Structure to class

<Serializable> Public Class Account
        Private Nam As String
        Private Numbe As String
        Public Sub New(Namee As String, Num As String)
            Name = Namee
            Number = Num
        End Sub
        Public Property Name As String
            Get
                Return Nam
            End Get
            Set(value As String)
                Nam = value
            End Set
        End Property
        Public Property Number As String
            Get
                Return Numbe
            End Get
            Set(value As String)
                Numbe = value
            End Set
        End Property

        Public Overrides Function ToString() As String
            Return Name
        End Function
    End Class
  • Make the `Account` a class instead of structure. Make both `Name` and `Number` public properties. –  Dec 13 '19 at 23:58
  • 1
    You have two problems: `Account` must have the `` attribute. You have `Option Strict Off`. It can be seen because of the Late Binding of `MsgBox(LS.SelectedItem.number)`, which should be `MsgBox(CType(LS.SelectedItem, Account).Number)`. Compile and re-drop. – Jimi Dec 14 '19 at 00:22
  • 1
    It's been a long time, but I think you need an empty constructor, too. – LarsTech Dec 14 '19 at 00:23
  • i have changed the account from structure to class and the problem still exist – Maged Algaafary Dec 14 '19 at 22:01
  • i added attribute to the structure but still have the problem too. – Maged Algaafary Dec 14 '19 at 22:01
  • what to do with the empty structure ? – Maged Algaafary Dec 14 '19 at 22:02
  • The error shown in the Image clearly states that `Account` (whatever that is now) is not marked as ``. If you have a class instead of a structure, decorate that class. Also, if you have modified your code, update your question accordingly. Otherwise is not understandable anymore. – Jimi Dec 14 '19 at 22:55
  • Edited, go up to see the update. – Maged Algaafary Dec 15 '19 at 00:04

1 Answers1

0

Problem Resolved* i will share the solve with you. all the problem is coming from the line

ACL = New List(Of Account)

and the line

CACL = New List(Of Account)

because it declare new list(of account) in design time. i solved the problem by deleting the both of line and modified the property (AutoCompleteList) to be like that.

Public WriteOnly Property AutoCompleteList As List(Of Account)
    Set(value As List(Of Account))
        ACL = value
        CACL = New List(Of Account)
    End Set
End Property

and the final code will be like that:-

the structure:

 Public Structure Account
    Public Name As String
    Public Number As String
    Public Sub New(Namee As String, Num As String)
        Name = Namee
        Number = Num
    End Sub
    Public Overrides Function ToString() As String
        Return Name
    End Function
End Structure

the class:

Public Class AutoCompleteTextBox

Inherits TextBox
Private ACL As List(Of Account), CACL As List(Of Account)
Private CaseSensitive As Boolean
Private MinChar As Integer

Private LS As ListBox
Private OLDText As String
Private PN As Panel


Public Sub New()
    MyBase.New

    MinTypedCharacters = 2
    CaseSesitivity = False

    LS = New ListBox
    LS.Name = "SeggestionListBox"
    LS.Font = Font
    LS.Visible = True

    PN = New Panel
    PN.Visible = False
    PN.Font = Font
    PN.AutoSizeMode = AutoSizeMode.GrowAndShrink
    PN.ClientSize = New Size(1, 1)
    PN.Name = "SeggestionPanel"
    PN.Padding = New Padding(0, 0, 0, 0)
    PN.Margin = New Padding(0, 0, 0, 0)
    PN.BackColor = Color.Transparent
    PN.ForeColor = Color.Transparent
    PN.PerformLayout()
    If Not PN.Controls.Contains(LS) Then
        PN.Controls.Add(LS)
    End If
    LS.Dock = DockStyle.Fill
    LS.SelectionMode = SelectionMode.One

    AddHandler LS.KeyDown, AddressOf LS_KeyDown
    AddHandler LS.MouseClick, AddressOf LS_MouseClick
    AddHandler LS.MouseDoubleClick, AddressOf LS_MouseDoubleClick

    LS.DataSource = CACL
    OLDText = Text

End Sub

Public WriteOnly Property AutoCompleteList As List(Of Account)
    Set(value As List(Of Account))
        'ACL.Clear()
        ACL = value
        CACL = New List(Of Account)
    End Set
End Property

Public Property CaseSesitivity As Boolean
    Get
        Return CaseSensitive
    End Get
    Set(value As Boolean)
        CaseSensitive = value
    End Set
End Property

Public Property MinTypedCharacters As Integer
    Get
        Return MinChar
    End Get
    Set(value As Integer)
        MinChar = value
    End Set
End Property

Public Property SelectedIndex As Integer
    Get
        Return LS.SelectedIndex
    End Get
    Set(value As Integer)
        If LS.Items.Count <> 0 Then
            LS.SelectedIndex = value
        End If
    End Set
End Property

Private ReadOnly Property ParentForm As Form
    Get
        Return Me.Parent.FindForm
    End Get
End Property

Public Sub HideSuggestionListBox()
    If Not ParentForm Is Nothing Then
        PN.Hide()
        If ParentForm.Controls.Contains(PN) Then
            ParentForm.Controls.Remove(PN)
        End If
    End If
End Sub

Private Function SelectItem() As Boolean
    If LS.Items.Count > 0 AndAlso LS.SelectedIndex > -1 Then
        Text = LS.SelectedItem.ToString
        MsgBox(LS.SelectedItem.number)
        HideSuggestionListBox()
    End If
    Return True
End Function



Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
    If e.KeyCode = Keys.Up Then
        MoveSelection(SelectedIndex - 1)
        e.Handled = True
    ElseIf e.KeyCode = Keys.Down Then
        MoveSelection(SelectedIndex + 1)
        e.Handled = True
    ElseIf e.KeyCode = Keys.PageUp Then
        MoveSelection(SelectedIndex - 10)
        e.Handled = True
    ElseIf e.KeyCode = Keys.PageDown Then
        MoveSelection(SelectedIndex + 10)
        e.Handled = True
    ElseIf e.KeyCode = Keys.Enter Then
        SelectItem()
        e.Handled = True
    Else
        MyBase.OnKeyDown(e)
    End If

End Sub

Protected Overrides Sub OnLostFocus(e As EventArgs)
    If Not PN.ContainsFocus Then
        MyBase.OnLostFocus(e)
        If Not CheckItem(Text) Then
            Text = ""
        End If
        HideSuggestionListBox()
    End If

End Sub
Protected Overrides Sub OnTextChanged(e As EventArgs)
    If Not DesignMode Then
        ShowSuggests()
    End If
    MyBase.OnTextChanged(e)
    OLDText = Text
End Sub
Private Sub LS_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
    If (e.KeyCode = Keys.Enter) Then
        Me.SelectItem()
        e.Handled = True
    End If
End Sub

Private Sub LS_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
    ' select the current item
    Me.SelectItem()
    MsgBox(LS.SelectedItem.number)
End Sub

Private Sub LS_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)

    Me.SelectItem()
End Sub
Private Function CheckItem(ItemSTR As String) As Boolean
    For Each STR As Account In ACL
        If ItemSTR.ToLower = STR.ToString.ToLower Then
            Return True
            Exit Function
        End If
    Next
    Return False
End Function

Private Sub MoveSelection(Index As Integer)
    If Index <= -1 Then
        SelectedIndex = 0
    ElseIf Index > (LS.Items.Count - 1) Then
        SelectedIndex = LS.Items.Count - 1
    Else
        SelectedIndex = Index
    End If
End Sub

Private Sub ShowSuggests()
    If Text.Length >= MinTypedCharacters Then
        PN.SuspendLayout()
        If Text.Length > 0 AndAlso OLDText = Text.Substring(0, Text.Length - 1) Then
            UpdateCurrentAutoCompleteList()

        ElseIf OLDText.Length > 0 AndAlso Text = OLDText.Substring(0, OLDText.Length - 1) Then
            UpdateCurrentAutoCompleteList()
        Else
            UpdateCurrentAutoCompleteList()
        End If

        If Not CACL Is Nothing AndAlso CACL.Count > 0 Then
            PN.Show()
            PN.BringToFront()
            Focus()
        Else
            HideSuggestionListBox()
        End If
        PN.ResumeLayout()
    Else
        HideSuggestionListBox()
    End If
End Sub

Private Sub UpdateCurrentAutoCompleteList()
    CACL.Clear()
    For Each STR As Account In ACL
        If CaseSesitivity = True Then
            If STR.ToString.IndexOf(Text) > -1 Then
                CACL.Add(STR)
            End If
        Else
            If STR.ToString.ToLower.IndexOf(Text.ToLower) > -1 Then
                CACL.Add(STR)
            End If
        End If
    Next
    If CACL.Count > 0 Then
        UpdateListBoxItems()
    Else
        HideSuggestionListBox()
    End If

End Sub
Sub Fill()
    For Each A As Account In CACL
        LS.Items.Add(A)
    Next
End Sub
Private Sub UpdateListBoxItems()
    If Not ParentForm Is Nothing Then
        PN.Width = Width
        'PN.Height = ParentForm.ClientSize.Height - Height - Location.Y
        Dim F As Integer = ParentForm.ClientSize.Height - Height - Location.Y
        Dim Ten As Integer = Font.Height * 10
        Dim CUr As Integer = Font.Height * (CACL.Count + 1)
        If F < CUr Then
            PN.Height = F
        ElseIf CUr < Ten Then
            PN.Height = CUr
        ElseIf Ten < F Then
            PN.Height = Ten
        Else
            PN.Height = F
        End If

        'PN.Height = Font.Height * 10
        PN.Location = Location + New Size(0, Height)
        If Not ParentForm.Controls.Contains(PN) Then
            ParentForm.Controls.Add(PN)
        End If
        Fill()
    End If
End Sub

End Class

thank you all.