user9090742
user9090742

Reputation:

Search by list Xamarin Forms (MVVM)

I have a problem with searching records. As you type characters, the list will not update.

At the moment I am using Binding Login for testing but I will be using Uri with a photo.

My ViewModel

private ObservableCollection<FollowerModel> _followerItems = null;
public ObservableCollection<FollowerModel> FollowerItems
{
    get => _followerItems;
    set
    {
        _followerItems = value;
        OnPropertyChanged();
        OnPropertyChanged();
    }
}

private FollowerModel _followerItem = null;
public FollowerModel FollowerItem
{
    get => _followerItem;
    set
    {
        _followerItem = value;
        OnPropertyChanged();
        OnFollowerItemChanged();
    }
}

// ...

private  void OnSearchPhrase()
{
    var searchPhrase = _searchPhrase.Trim();

    if (searchPhrase.Length < SEARCH_PHRASE_MIN_LENGTH) return; // SEARCH_PHRASE_MIN_LENGTH = 3

    FollowerItems.Where(name => name.Login.Contains(searchPhrase));
}

My PageView

<flv:FlowListView SeparatorVisibility="None" HasUnevenRows="true" FlowItemTappedCommand="{Binding FollowerItemCommand}" FlowColumnMinWidth="100" FlowItemsSource="{Binding FollowerItems}">
    <flv:FlowListView.FlowColumnTemplate>
        <DataTemplate>
            <Grid Padding="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="98" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="98" />
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Login}" /> 
                </Image>-->
            </Grid>
        </DataTemplate>
    </flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>

Upvotes: 0

Views: 1231

Answers (2)

Dennis Schr&#246;er
Dennis Schr&#246;er

Reputation: 2422

First of all, you will need two ObservableCollections:

  • One ObservableCollection which contains all items
  • One ObservableCollection which contains the filtered items

The filtered ObservableCollection will be the one which is binded to your control. So you only need a private variable for all items and a public property for the filtered items:

private ObservableCollection<FollowerModel> _allFollowerItems;
private ObservableCollection<FollowerModel> _followerItems;

public ObservableCollection<FollowerModel> FollowerItems
{
    get { return _followerItems}
    set
    {
        _followerItems = value;
        RaisePropertyChanged();
    }
}

One more thing I noticed is that you are using OnPropertyChanged(). It is deprecated, use RaisePropertyChanged() instead.

In your OnSearchPhrase() method, you want to set FollowerItems to the original items (_allFollowerItems) if searchPhrase.Length < SEARCH_PHRASE_MIN_LENGTH. Otherwise, you will filter it:

private void OnSearchPhrase()
{
    var searchPhrase = _searchPhrase.Trim();

    if (searchPhrase.Length < SEARCH_PHRASE_MIN_LENGTH)
    {
        FollowerItems = _allFollowerItems;
    }
    else
    {
        FollowerItems = new ObservableCollection<FollowerModel>(_allFollowerItems.Where(name => name.Login.ToLower().Contains(searchPhrase.ToLower())));
    }
}

Notice that I added ToLower() to the strings to have a more user friendly search. If Case-sensetive search was intended, just remove it.

Don't forget to set FollowerItems and _allFollowerItems once when at the place where you are loading your items right now:

FollowerItems = new ObservableCollection(items); _allFollowerItems = new ObservableCollection(items);

Upvotes: 0

LeRoy
LeRoy

Reputation: 4446

First add a search bar in your xaml

 <SearchBar Placeholder="Search" Text="{Binding SearchText}"  />

Then Create a Bindable property for it

private string _searchText;
public string SearchText
{
    get { return _searchText; }
    set
    {
        _searchText = value;
        SearchUserText(_searchText);
        RaisePropertyChanged("SearchText");
    }
}

Then Create a function SearchUserText that will listen for text and change your list

   public void SearchUserText(string text)
    {
          var searchPhrase = _searchPhrase.Trim();

            if (searchPhrase.Length < SEARCH_PHRASE_MIN_LENGTH) return; // SEARCH_PHRASE_MIN_LENGTH = 3

            FollowerItems.Where(name => name.Login.Contains(searchPhrase));

    }

NB: Don't forget to add getters and setters on your model FollowerModel

example:

public class FollowerModel : BindableBase
{
    private int _id;
    public int Id
    {
        get { return _id; }
        set { SetProperty(ref _id, value); }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }
}

Upvotes: 1

Related Questions