Enhancing AutoCompleteBox part 1: distinguishing similar items
Among other novelties Silverlight 3 also included new and very useful AutoCompleteBox allowing to make smart suggestions to a user during text input. Unfortunately, as it always happens with new and pretty complex controls like that, there are some scenarios when you can't avoid changing or enhancing its default behavior to get the functionality you want.
The first thing I'd like to discuss is how to make AutoCompleteBox work like combo: not only selecting the text you want, but also selecting the object you want. As it turns out, AutoCompleteBox is not a perfect candidate for implementing this functionality: you'll need to extend the code a little to make it work smoothly.
Problems start when you need to distinguish objects which are represented by the same text in AutoCompleteBox's text box. For example, you are implementing an AutoCompleteBox for editing persons LastName. In a dropdown list, you display person's FullName (FirstName+LastName), but in textbox - only LastName. Than, you bind your Person property to AutoCompleteBox.SelectedItem and expect that you'll get as SelectedItem the object you selected in list. But no: selecting second person with the same name
makes AutoCompleteBox thinks that the first item is selected!
This is actually a well-known problem discussed on Silverlight forums. AutoCompleteBox creators recommend to avoid this scenario completely, but actually, not all is that bad, this problem is fixable in a rather simple way. Unfortunately, custom ItemFilters and overriding FormatValue won't help here: it all goes to the same string displayed in AutoCompleteBox text box. When you do a selection in popup, AutoCompleteBox remembers only this string. To get a selected item, it searches again in the whole list and, surely, is having troubles with duplicates, as the information about the actual selection is lost. But can fix it - just make it remember. In your custom class inherited from AutoCompleteBox, define a new dependency property (name it, for example, SelectionBoxItem like it was named in ComboBox), than override OnDropDownClosing:
protected override void OnDropDownClosing(RoutedPropertyChangingEventArgs<bool> e) { base.OnDropDownClosing(e); SelectionBoxItem = SelectionAdapter.SelectedItem; }
You'll need to bind to SelectionBoxItem instead of SelectedItem to get the proper item from selection. Nothing spectacular, but it works, as you may see in the demo attached.
| Attachment | Size |
|---|---|
| autocompleteboxduplicates.zip | 152.08 KB |

Comments
This fix worked like a charm!!
Thanks for posting this fix. It was really annoying and had eaten up a day's effort to fix it.