Removing multiple instances of a value in a combobox [C#]

Shaitan00

Junior Contributor
Joined
Aug 11, 2003
Messages
358
Location
Hell
Given a dataset [ds] and combobox dropdown [cbClient], I need to populate the dropdown with the values from column0 of ds.Tables[0]
Problem is I want the values in the combobox [cbClient] to be unique...

Dataset ds looks like this (space in between each column):
client1 Assignment1 ACTIVE
client1 Assignment2 ACTIVE
client2 Assignment1 ACTIVE

As you can see there are two rows that have a value of Client1, if I populate my cbClient directly with the Dataset ds.Tables[0] then my Combobox [cbClient] will have Client1, Client1, Client2 - I only want UNIQUE names in the combobox, no repeating Client1 twice because it is in two rows.
The only thing I could think of is going through the dataset manually and checking to see if the item is already there, adding it only if it is not (using something like a foreach row loop and the .FindStringExact but that keeps giving me a lot of exception errors.

Any help/hints/comments would be greatly appreciated - I just want the list of words in my combobox [cbClient] to be unique and sorted alphabetically (if thats not asking to much ehhehe)
 
Well, the sorting can be done through the ComboBox itself.
As for the "distinct" part, I've not come across a way to do this automatically. I have "cheated" many times, using a Hashtable to store the values I want to add to the Combo with the keys being - for you - the value in Column 0. You will have to use a foreach and check ht.Contains() to see if a value already exists.

If this is data retrieved from a DB, you can always use DISTINCT in the QUERY returning data.

If you must use custom code, just wrap it in a function named GetDistinctValues() and you can always change your implementation later, if needed. I've found that using a hashtable is fine performance-wise. I've had as many as 200-300 entries before and it's very fast. Any more than that and I'd start to wonder why a user would want a drop-down anyway and not some sort of type-in control.

-ner
 
I like the idea of using the .Contains() but it expects a system.windows.forms.controls to be evalulated - not a string for distinct values. Not sure how you want me to use it?

I was looking into .FindStringExact but it keeps giving me exception errors and thought there would be a better way.

Can I really use the DISTINCT? Problem with that is I want it to return all the rows but only display distinct results in the combobox.

So I was thinking of doing something like (pseudo-code):
if ("Client1" is already in combobox) { // do nothing {
else (cbClient.items.add("Client1"))
I just can't get that to work correctly - or thought there might be a better way.
 
I was thinking of using Contains on a hashtable. Here's the pseudo-code:
Code:
Create Hashtable
Loop each item in DataSet
    if hashtable.Contains(name) continue

    Add value to hashtable
End Loop

Loop each item in hashtable (GetEnumerator)
    Add items to hashtable
End Loop

Another possibility is to create a dummy dataset with one table, one column and do something similar to above. You would add rows to the new DataSet if they weren't already there. The advantage is that you could bind to the new DataSet if you wanted. The disadvantage is that you'd likely have to do a datatable.Select(...) to see if a value existed, and that just seems slower to me. I wouldn't worry about performance at this stage though, always profile afterwards.

Let me know if you need a more concrete example.

-ner
 
I recently had some experience with this. I wanted the data values in a column listed distinctly in a combo box. The suggestion of using a Hashtable is a good one and probably faster. I use an ArrayList in my solution, but I am only iterating through 500-600 rows of data, and the ArrayList seems plenty fast for that. I was also Binding the DataSource property of my ComboBox to the ArrayList, but the Hashtable does not implement the IList interface.

Anyway, here is my code for iterating through the DataRows of a DataColumn and storing the distinct values in an ArrayList bound to a ComboBox.

Visual Basic:
Private Sub UpdateValueList(ByVal column As DataColumn)

   Dim bmb As BindingManagerBase
   Dim columnName As String
   Dim drc As DataRowCollection
   Dim index As Integer
   Dim rowCount As Integer
   Dim value As Object
   Dim valueIndex As Integer

   columnName = column.ColumnName
   drc = Me.m_filterMember.Rows
   index = 0
   rowCount = drc.Count

   If rowCount > 0 Then
      If Me.m_valueList Is Nothing Then
         m_valueList = New ArrayList
      ElseIf Me.m_valueList.Count > 0 Then
         m_valueList.Clear()
      End If

      'The ArrayList does not implement the IBindingList interface.  I call
      'the SuspendBinding and ResumeBinding methods of the BindingManagerBase
      'instance to force the data bound control to be updated.
      bmb = BindingContext(Me.m_valueList)
      bmb.SuspendBinding()
      For Each row As DataRow In drc
         value = row(columnName)
         If Not TypeOf (value) Is System.DBNull Then
            If TypeOf (value) Is System.DateTime Then
               value = Me.FormatDateValue(value)
            End If

            'Use the BinarySearch method for a case-insensitive "Contains" implementation
            valueIndex = m_valueList.BinarySearch(value, CaseInsensitiveComparer.Default)
            If valueIndex < 0 Then
               m_valueList.Add(value)
               index += 1
               m_valueList.Sort(Comparer.DefaultInvariant)
            End If
         End If
      Next
      bmb.ResumeBinding()
   End If
End Sub
 
Back
Top