How to detect when items are added to Combobox/Listbox

D

Don

Is there any way to detect when an item has been added to the Items
collection of a combobox or listbox? I am inheriting a Combobox and want to
validate items before they are added to the combobox, but I can't find
anything that will let me do that.

- Don
 
C

Cor Ligthert

Don,
Is there any way to detect when an item has been added to the Items
collection of a combobox or listbox? I am inheriting a Combobox and want
to
validate items before they are added to the combobox, but I can't find
anything that will let me do that.

This sounds for me as a strange question, where are those Items comming
from?

Cor
 
D

Don

The combobox is populating itself in its constructor. However, the VB.NET
IDE, for some reason, thinks it's a good idea to append blank items to the
end of the combobox. It keeps adding code like this to the Windows Code
section in the form:

Me.MyCustomCombobox.Items.AddRange(New Object() {""})

Almost every time I make a change on the form and recompile it, VB decides
to add another blank line to the combobox. And then another. And another.
I clear out the Items collection in the Properties window, but the blank
lines keep coming back. I can't figure out why it's doing this, so I'm just
trying to come up with a work around now to prevent that line of code from
working.

- Don
 
C

Cor Ligthert

Don,

Did you delete that line already, for me that never did harm at all.

When it is a two times inherited combobox look than as well in that
baseclass.

Cor
 
D

Don

I have tried deleting that line in the Form's code, but VB keeps putting it
back.

- Don
 
A

Adam Goossens

Can we see the code for the custom combo box? (Or, at least, the parts
that really count)

It might be a bug in your implementation that's causing the designer to
add that line of code (but I doubt it).

I've never run into this problem before. Then again, I've never
subclassed a combo box before :)

Cheers,
-Adam.
 
D

Don

Adam Goossens said:
Can we see the code for the custom combo box? (Or, at least, the parts
that really count)

It might be a bug in your implementation that's causing the designer to
add that line of code (but I doubt it).

I've never run into this problem before. Then again, I've never
subclassed a combo box before :)


Okay, here's how it works. I have a class library within which I have
created a custom combobox called EnumCombobox. It inherits from
System.Windows.Forms.Combobox. Now, this EnumCombobox is declared
MustInherit.

I have a second custom combobox class that inherits EnumCombobox. In its
constructor it calls a method of the base class (EnumCombobox) telling it to
populate the combobox.

The point of this arrangement was to create multiple custom comboboxes, one
for each of several custom Enums I have made for my project. The comboboxes
actually display the Enum names with spaces inserted before each capital
letter, or something like that, and have an option to display a blank item.

Here is how one of the second custom comboboxes looks. The only code I
added was the call to Me.Populate() in the constructor. The second
argument, a boolean, tells the Populate() method to insert a blank line. :


--- CODE START ---


Public Class ProcedureToothTypeComboBox
Inherits EnumComboBox

#Region " Component Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Component Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call
Me.Populate("VegaBizObj.Enumerations+ProcedureToothType", True)

End Sub

'Component overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Component Designer
'It can be modified using the Component Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
components = New System.ComponentModel.Container
End Sub

#End Region


End Class


--- CODE END ---


The Populate() from the base class looks like this. The code calls a
FillList() method which actually puts items in the list. The GetList()
method just retrieves a collection of objects representing the various
members of the Enum:


--- CODE START ---


Friend Sub Populate(ByVal enumName As String, ByVal includeBlankItem As
Boolean)


Dim selectedIndex As Integer = -1


Try

' Remember enum name
_EnumerationName = enumName
_IncludeBlankItem = includeBlankItem

' Prevent control from visually updating
Me.SuspendLayout()

' If an enum name has been specified...
If _EnumerationName.Length > 0 Then

' Clear the list
Me.Items.Clear()

' Fill in the control with enum values
FillList(GetList(_EnumerationName))

End If

Catch ex As Exception

' Log the error
LogError(ex)

Finally

' Allow control to visually update
Me.ResumeLayout()

End Try

End Sub


--- CODE END ---


This is what FillList() looks like:


--- CODE START ---


Friend Sub FillList(ByVal nameValueCollection As Collection)


Dim item As NameValue


' If we are to include a blank item in the list, then do so.
If _IncludeBlankItem Then Me.Items.Insert(0, String.Empty)

' If the collection we were given has something in it...
If Not IsNothing(nameValueCollection) Then

' Loop thru the collection
For Each item In nameValueCollection

' Add the item to the list
Me.Items.Add(item)

Next

End If


End Sub


--- CODE END ---


In the method above is the only line of code that adds a blank item to the
combobox. I'm guessing, maybe, when VB creates the objects on the form it
calls the constructor, which calls Populate(), which calls FillList()? And
maybe the GetList() is returning Nothing because the information it
retrieves is not available at that time, so it just adds the blank line and
that's it? I don't think this is the case because I've commented out that
line and it still does it. I've event commented out the call to the
Populate() method in the combobox that inherits EnumCombobox and I still get
extra blank items added after every compile.

There is also nothing special in the constructor for EnumCombobox. I
haven't modified it at all. I am simply at a loss here.

- Don
 
D

Don

I've figured out what is causing the appearance of a blank item in the
combobox, but I cannot figure out a way to prevent it.

When I compile my code, the constructor for the class is executed. This
means the following method is executed:


-- CODE START --


Friend Sub FillList(ByVal nameValueCollection As Collection)


Dim item As NameValue


' If we are to include a blank item in the list, then do so.
If _IncludeBlankItem Then Me.Items.Insert(0, String.Empty)

' If the collection we were given has something in it...
If Not IsNothing(nameValueCollection) Then

' Loop thru the collection
For Each item In nameValueCollection

' Add the item to the list
Me.Items.Add(item)

Next

End If


End Sub


-- CODE END --


Since I set _IncludeBlankItem to true before this gets called, VB executes
the Me.Items.Insert(0, String.Empty) code when it compiles the form. The
strange thing is that this is all the list contains. I've modified the
method so that the code to add the blank line is placed after the loop and
so that the blank line is only added if the list (Me.List) contains at least
one item, but the blank item is still always added even though it's the only
item in the list.

So, it looks like I have no choice but to remove the call to the method that
populates the combobox from the constructor and just make it public so that
the form can manually call it during its Load event or something. Unless
someone knows of a way to determine when code is being executed because of a
compile as opposed to normal execution, or if someone knows of a way to
prevent adding new Items to the list.

- Don
 
C

Cor Ligthert

Don,

Are you sure that your "nameValueCollection" is nothing and not is
"nameValuCollection.length (or count) = 0"

When you instance it with "new" than it is always something.

Cor
 
D

Don

Actually, I've discovered that, during the compile, the nameValueCollection
contains items in it, and they are added to the combobox's Item collection
along with the blank line. However, strangely enough, only the blank line
remains after the build; the others are discarded(?).

I've tested this by inserting Me.Items.Count instead of a blank line. Sure
enough, after a build, there is a line appended to the combobox with the
number of items the nameValueCollection is expected to have. I'm completely
at a loss to explain this strange behavior.

- Don
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top