Sai Sunkari
Sai Sunkari

Reputation: 179

searching the ObservableCollection list based on a string given in search bar

I'm working on Xamarin forms project.

Below is my template .xaml file:

<StackLayout>
<SearchBar>.....</SearchBar>
<ListView>.....</ListView>
</StackLayout>

I'm populating listview as:

public ObservableCollection<Grouping<string, Ticket>> TicketList
    {
        get { return _ticketList; }
        set { _ticketList = value; OnPropertyChanged(); }
    }

listview.ItemSource = TicketList;

Here is the search code:

public void FilterList(string searchText)
{
TicketListNew = // getting list from local database

 // searching each field of list with the text entered
  GroupCollections(TicketListNew.Where(Tl => Tl.CustomerName.ToLower().Contains(searchText.ToLower())
}

private void GroupCollections(List<Ticket> ticketListNew){
var sorted = from ticket in ticketListNew
                     orderby ticket.DelPUDate
                     group ticket by GetTicketDate(ticket.DelPUDate) into ticketListGroup
                     select new Grouping<string, Ticket>(ticketListGroup.Key, ticketListGroup);
        if (TicketList == null) TicketList = new ObservableCollection<Grouping<string, Ticket>>(sorted);
        else
        {
            TicketList.Clear();
            var temp = sorted.ToList();
            for (var i = 0; i < temp.Count; i++)
            {
                TicketList.Add(temp[i]);
            }
        }

}

During the searching, it goes to the else part, and here it is taking too long to populate the list to TicketList. I feel like this is not the right design to clear the list first and assign each list item once at a time.

any better solution to search?

Upvotes: 0

Views: 653

Answers (1)

fmaccaroni
fmaccaroni

Reputation: 3916

I'd bind the ItemsSource property on the ListView instead of assigning it and also make sure you are setting RecycleElement in your ListView, so that your items gets recycled (if you do not put this all of the items will be loaded in the ListView directly; setting this will enable the virtualization of the items so that the cells are recycled and therefore the performance is improved dramatically for large collections)

<ListView
    ...
    ItemsSource="{Binding TicketList}`>
    ...
    <x:Arguments>
        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
    </x:Arguments>
</ListView>

And also directly do a foreach of your sorted variable:

foreach(var item in sorted)
{
    TicketList.Add(item);
}

If you do a .ToList() it will generate and allocate you a new List object, by doing the foreach directly will take the IEnumerable and iterate through it by reference.

I think this will speeds up the process.

HIH

Upvotes: 1

Related Questions