private void RefreshView()
{
if(_items == null)
{
ClearView();
return;
}
// Cache the current text value
string text = Text ?? string.Empty;
// Determine if any filtering mode is on
bool stringFiltering = TextFilter != null;
bool objectFiltering = FilterMode == AutoCompleteFilterMode.Custom && TextFilter == null;
int viewIndex = 0;
int viewCount = _view.Count;
List<object> items = _items;
foreach(object item in items)
{
bool inResults = !(stringFiltering || objectFiltering);
if(!inResults)
{
inResults = stringFiltering ? TextFilter(text, FormatValue(item)) : ItemFilter(text, item);
}
if(viewCount > viewIndex && inResults && _view[viewIndex] == item)
{
// Item is still in the view
viewIndex++;
}
else if(inResults)
{
// Insert the item
if(viewCount > viewIndex && _view[viewIndex] != item)
{
// Replace item
// Unfortunately replacing via index throws a fatal
// Cost: O(n) vs O(1)
_view.RemoveAt(viewIndex);
_view.Insert(viewIndex, item);
viewIndex++;
}
else
{
// Add the item
if(viewIndex == viewCount)
{
// Constant time is preferred (Add).
_view.Add(item);
}
else
{
_view.Insert(viewIndex, item);
}
viewIndex++;
viewCount++;
}
}
else if(viewCount > viewIndex && _view[viewIndex] == item)
{
// Remove the item
_view.RemoveAt(viewIndex);
viewCount--;
}
}
// Clear the evaluator to discard a reference to the last item
if(_valueBindingEvaluator != null)
{
_valueBindingEvaluator.ClearDataContext();
}
}