Reputation: 309
I've created a user control using vb.net
which inherits from ComboBox
class.
I have defined a property named "ComboType" of type of an enum
and some arrays
and a method named "ComboPopulate" which populates combo box depend on ComboType
property (I have used a select case or switch block for this) and also defined an event named "SelectedTypeChanged" which occurs whenever value of ComboType
property changes.
Problem:
When I add this UI to a form and change the ComboType
property it works but it inserts each array twice despite I've put the Me.Items.Clear()
method on top of ComboPopulate
method.
Why is this happening and what is the solution?
This is the code
Public Class AdvancedComboBox
Implements INotifyPropertyChanged
Dim Array1() As String = New String() {"item1", "item2", "item3"}
Dim Array2() As String = New String() {"number1", "number2", "city3"}
Dim Array3() As String = New String() {"city1", "city2", "city3"}
Public Event SelectedTypeChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(info As String)
RaiseEvent SelectedTypeChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Public Enum ComboTypes
None
Type1
Type2
Type3
End Enum
Dim _type As ComboTypes
Public Property ComboBoxType As ComboTypes
Get
Return _type
End Get
Set(value As ComboTypes)
_type = value
NotifyPropertyChanged("shomething")
End Set
End Property
Public Sub ComboPopulate()
Me.Items.Clear()
Select Case Me.ComboBoxType
Case ComboTypes.Type1
Items.Clear()
Items.AddRange(Array1)
Case ComboTypes.Type2
Items.Clear(
Items.AddRange(Array2)
Case ComboTypes.Type3
Items.Clear()
Items.AddRange(Array3)
Case ComboTypes.None
Items.Clear()
End Select
End Sub
Private Sub AdvancedComboBox_SelectedTypeChanged(sender As Object, e As PropertyChangedEventArgs) Handles Me.SelectedTypeChanged
ComboPopulate()
End Sub
End Class
Upvotes: 0
Views: 1518
Reputation: 38865
Your code has several conceptual problems, starting with this: I created a user control which inherits from ComboBox class
. If it is a UserControl it inherits from UserControl but would have a ComboBox on it. If you want to inherit from ComboBox, you are missing a key statement:
Public Class AdvancedComboBox
Inherits ComboBox ' this is missing
Implements INotifyPropertyChanged
The code references look more like an inherited control than UserControl, so I took a guess that is what you are after (confirmed via comments). The core problem is in the designer code:
Me.ComboEx1.ComboBoxType = WindowsApplication1.ComboEx.ComboTypes.Type2
Me.ComboEx1.FormattingEnabled = True
Me.ComboEx1.Items.AddRange(New Object() {"number1", "number2", "city3"})
When you add a control to the form and set the ComboBoxType
property, your code populates the Items. But, as you can see, when creating the form, VS is also adding those items directly to Items
as part of designer serialization. Since it is pretty odd for a CBO to populate itself, this is to be expected. If/when you change ComboBoxType at runtime, they don't double up.
One easy fix is to default to None and only set the Type at runtime, not via the IDE props window:
Dim _type As ComboTypes = ComboTypes.None
Sub Form1_Load(....
myAdvCBO.ComboBoxType = ComboTypes.Type2
If you do this, you might want to hide the Property from the IDE window:
<Browsable(False)>
Public Property ComboBoxType As ComboTypes
Another way to fix it is to implement ISupportInitialize
:
Public Class ComboEx
Inherits ComboBox
Implements ISupportInitialize
Tapping enter on that last line will add 2 new methods to your control:
Public Sub BeginInit() Implements ISupportInitialize.BeginInit
Public Sub EndInit() Implements ISupportInitialize.EndInit
These will be called before any properties are set on your control, and after all properties are set. EndInit
will allow you to undo the VS designer code (you can see these being called at the start and end of the designer code).
Public Sub EndInit() Implements ISupportInitialize.EndInit
ComboPopulate()
End Sub
Your ComboPopulate
already clears Items
which should fix the problem.
There are a few other potential issues:
Your property setter will raise false events because you are not testing if it actually changed. If the SelectedTypeChanged
event is supposed to hook into a ControlDesigner or something, the extra events might cause problems because VS will set/get repeatedly. Your setter should probably be:
Set(value As ComboTypes)
If value <> _type Then ' see if it really did change
_type = value
NotifyPropertyChanged("shomething") ' sic
ComboPopulate() ' same as reacting to event
End If
End Set
Since your local handler, AdvancedComboBox_SelectedTypeChanged
does so little, it seems like overkill as well. I got rid of it. Finally, since there is no way for the user to change the selected type, it can happen only via your form code:
ComboEx1.ComboBoxType = ComboEx.ComboTypes.Type3
So, what is the point of firing an event to tell your form code it just changed what it just changed? Perhaps this is part of some bigger scheme we are not privy to, but as presented it doesnt add any value.
If this was intended to react to the property being changed so Items
could be updated, you really dont need it.
Upvotes: 1