3

I have a ComboBox with the following code:

private void comboBox1_TextChanged(object sender, EventArgs e)
{
    using (var service = WebServiceHelper.GetCoreService())
    {
        string physicianXml = service.SearchPhysicians(SessionInfo.Current.ClientCode, SessionInfo.Current.MachineName,
                                    SessionInfo.Current.Username, comboBox1.Text);

        var physicians = PhysicianItemList.FromXml(physicianXml);

        AutoCompleteStringCollection autoCompleteStringCollection = new AutoCompleteStringCollection();
        foreach (var physician in physicians.Items)
        {
            autoCompleteStringCollection.Add(physician.LastName + ", " + physician.FirstName);
        }

        comboBox1.AutoCompleteCustomSource = autoCompleteStringCollection;
        comboBox1.Select(comboBox1.Text.Length, 0);
    }
}

Basically, a user types the first few characters of a physician's name and it should populate the auto-complete list with the top 100 matching records. It works great, but I need to associate it back to a key (either the PK from the table, or the Physician's NPI number). It seems the AutoCompleteStringCollection doesn't support keys. Can anyone suggest a way of doing this? There are approximately 7 million records in the table, so I don't want to prepopulate the ComboBox.

Thanks

Adam Plocher
  • 13,994
  • 6
  • 46
  • 79

3 Answers3

1

It looks like your problem is that AutoCompleteStringComplete was made specifically for strings (hence, the name).

You may want to look into the parents (IList, ICollection, IEnumerable) and see if you can homebrew something templated toward a key/value struct.

Joseph
  • 903
  • 1
  • 10
  • 25
  • Thank you for your reply. I tried a `List>` and when I set the `AutoCompleteCustomSource` I get errors saying it can't be casted. If I try to explicitly cast it, it throws an exception at runtime. I think I might just have to add the Physician's NPI number to the string, so it could show as "Doh, John (#11111)" and regex parse the number. Sucky. Thanks a lot though! – Adam Plocher Jan 18 '13 at 20:14
  • Glad it helped! Having to parse the strings isn't the worst thing that could happen. You may even be able to use `String.Split()` http://msdn.microsoft.com/en-us/library/system.string.split(v=vs.110).aspx – Joseph Jan 18 '13 at 20:19
1

When you build your AutoCompleteStringCollection, build a Dictionary<String, int> for the name, id pairs as well. Then use some event (textbox validation or user submit/save click) to lookup and set the id. You could store the dictionary on the textbox Tag.

Edit

For some reason I thought you were working with a textbox control. Forget about the AutoCompleteStringCollection and just build a Dictionary<String, int>. For the combobox set your autocompletesource to ListItems, set the combobox display name and value and set the datasource to the dictionary.

combobox.DisplayMember = "key";
combobox.ValueMember = "value";
combobox.AutocompleteSource = AutocompleteSource.ListItems;
combobox.DataSource = myDictionary;

However you should only populate the datasource and autocomplete once when the user enters n characters in the combobox, otherwise it gets buggy. I tried to use this for a dynamic autocomplete once (eg the list clears if the user clear the text and retypes), but I had to forget about the combobox and use a hybrid textbox listbox approach much like this user

Community
  • 1
  • 1
  • If I follow you, you're saying have two collections: one Dictionary, and one AutoCompleteStringCollection? How do I match the two to lookup the ID? There could be duplicate physician names (like "John Smith"). Although, now that I think about it - that could cause another problem since the user will never know which to pick. Hmmm – Adam Plocher Jan 18 '13 at 20:18
  • That's right. Yes, needs to be unique strings. Both for the dictionary and for your user's sake in identifying the correct physician. –  Jan 18 '13 at 20:22
1

Too late but maybe someone will use this code :

this.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;

RNProveedor rnProveedor = new RNProveedor();
var listaProveedores = rnProveedor.Buscar();
Dictionary<int, String> dicTemp = new Dictionary<int, string>();

foreach (var entidad in listaProveedores)
{
    dicTemp.Add(entidad.ProvNro, entidad.ProNombre);
}

this.DataSource = new BindingSource(dicTemp, null);
this.DisplayMember = "Value";
this.ValueMember = "Key";

And to select the value

public int GetValorDecimal()
{
    KeyValuePair<int, string> objeto = (KeyValuePair<int, string>)this.SelectedItem;     
    return objeto.Key;
}

With this example you won't have any problem with duplicated strings as the examples above

H. Pauwelyn
  • 13,575
  • 26
  • 81
  • 144
Eduardo Mass
  • 79
  • 1
  • 2