private void UpdateTextCompletion(bool userInitiated)
{
// By default this method will clear the selected value
object newSelectedItem = null;
string text = Text;
// Text search is StartsWith explicit and only when enabled, in
// line with WPF's ComboBox lookup. When in use it will associate
// a Value with the Text if it is found in ItemsSource. This is
// only valid when there is data and the user initiated the action.
if(_view.Count > 0)
{
if(IsTextCompletionEnabled && TextBox != null && userInitiated)
{
int currentLength = TextBox.Text.Length;
int selectionStart = TextBox.SelectionStart;
if(selectionStart == text.Length && selectionStart > _textSelectionStart)
{
// When the FilterMode dependency property is set to
// either StartsWith or StartsWithCaseSensitive, the
// first item in the view is used. This will improve
// performance on the lookup. It assumes that the
// FilterMode the user has selected is an acceptable
// case sensitive matching function for their scenario.
object top = FilterMode == AutoCompleteFilterMode.StartsWith || FilterMode == AutoCompleteFilterMode.StartsWithCaseSensitive
? _view[0]
: TryGetMatch(text, _view, AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.StartsWith));
// If the search was successful, update SelectedItem
if(top != null)
{
newSelectedItem = top;
string topString = FormatValue(top, true);
// Only replace partially when the two words being the same
int minLength = Math.Min(topString.Length, Text.Length);
if(AutoCompleteSearch.Equals(Text.Substring(0, minLength), topString.Substring(0, minLength)))
{
// Update the text
UpdateTextValue(topString);
// Select the text past the user's caret
TextBox.SelectionStart = currentLength;
TextBox.SelectionLength = topString.Length - currentLength;
}
}
}
}
else
{
// Perform an exact string lookup for the text. This is a
// design change from the original Toolkit release when the
// IsTextCompletionEnabled property behaved just like the
// WPF ComboBox's IsTextSearchEnabled property.
//
// This change provides the behavior that most people expect
// to find: a lookup for the value is always performed.
newSelectedItem = TryGetMatch(text, _view, AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.EqualsCaseSensitive));
}
}
// Update the selected item property
if(SelectedItem != newSelectedItem)
{
_skipSelectedItemTextUpdate = true;
}
SelectedItem = newSelectedItem;
// Restore updates for TextSelection
if(_ignoreTextSelectionChange)
{
_ignoreTextSelectionChange = false;
if(TextBox != null)
{
_textSelectionStart = TextBox.SelectionStart;
}
}
}