xamarin/Xamarin.Forms

[Bug] SearchHandler.ItemsSource does not listen to INotifyCollectionChanged.CollectionChanged event

Open

#6,500 opened on Jun 11, 2019

 (3 comments) (0 reactions) (0 assignees)C# (1,926 forks)batch import
a/shell :shell:e/4 :clock4:help wantedp/iOS 🍎t/bug :bug:up-for-grabs

Repository metrics

Stars
 (5,644 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Description

When using a collection implementing INotifyCollectionChanged as a source for SearchHandler.ItemsSource, the results aren't updated when adding/removing/updating the collection.

The UI is updated only when setting a new collection to ItemsSource.

Steps to Reproduce

  1. Create a solution from the Shell App Template
  2. Add a new class CustomSearchHandler inheriting from SearchHandler
  3. Implement it as below
  4. Add this CustomSearchHandler to a page
  5. Run the app and try to search "bc"
  6. The results should not be filtered
  7. Add ItemsSource = _items.ToList() at the end of OnQueryChanged
  8. Run the app, search for "bc"
  9. The results should be filtered
using System.Collections.ObjectModel;
using System.Linq;
using Xamarin.Forms;

namespace TestSearchHandler
{
    public class CustomSearchHandler : SearchHandler
    {
        private static readonly string[] Values = new[]
        {
            "Abc",
            "Bce",
            "Xyz",
            "Qwe",
            "Rer",
            "Gep",
            "Qdw",
            "545"
        };

        private ObservableCollection<string> _items = new ObservableCollection<string>();

        public CustomSearchHandler()
        {
            ShowsResults = true;
            ItemsSource = _items;
        }

        protected override void OnQueryChanged(string oldValue, string newValue)
        {
            base.OnQueryChanged(oldValue, newValue);

            var newItems = Values.Where(v => v.ToLowerInvariant().Contains(newValue.ToLowerInvariant())).ToList();

            for (int i = newItems.Count; i < _items.Count; i++)
            {
                _items.RemoveAt(i);
            }

            for (int i = 0; i < newItems.Count; i++)
            {
                if (i >= _items.Count)
                {
                    _items.Add(newItems[i]);
                }
                else
                {
                    _items[i] = newItems[i];
                }
            }
        }
    }
}

Expected Behavior

Results should be updated when the INotifyCollectionChanged collection is updated.

Actual Behavior

Results are not updated when the INotifyCollectionChanged collection is updated.

Basic Information

  • Version with issue: 4.0.0.482894
  • IDE: Visual Studio for Mac
  • Platform Target Frameworks:
    • iOS: 12.1
    • Android: 9.0

Screenshots

Actual

Expected

Reproduction Link

https://github.com/TimLariviere/XFIssueRepros/tree/master/SearchHandlerItemsSourceIssue

Contributor guide