Taras Kryvko
Taras Kryvko

Reputation: 177

Creating an MVVM search page Xamarin

I want to create Xamarin search page with using MVVM. I have created a logic in my MainWindowViewModel which has to update my ListView once user entered a character into the searchar. But i have such result: In some reason UI is not updating

I do not know what i done wrong. And also i would like to invoke ExecuteSearchCommand asynchronysly, and i will approsiate if you show how to implement it correctly. Thanks.

  <ContentPage.BindingContext>
    <ViewModels:MainWindowViewModel/>
  </ContentPage.BindingContext>

<ContentPage.Content>
    <StackLayout>

        <SearchBar SearchCommand="{Binding SearchCommand}" 
                   Text="{Binding EnteredText}"
                   />
        <Label Text="{Binding EnteredText}"></Label>
        <ListView x:Name="lstContatos" ItemsSource="{Binding MyList}" HasUnevenRows="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Grid MinimumHeightRequest="80" HeightRequest="120" HorizontalOptions="FillAndExpand" >
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>

                                <Label Grid.Row="0" Text="{Binding PhrasalVerb}"/>
                                <Button  Text="Delete" Grid.Column="1" BackgroundColor="Black" HeightRequest="30" WidthRequest="40" IsVisible="True"/>

                            </Grid>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>

This is my ViewModel that binds to the View

        public string EnteredText
         {
         get { return enteredText; }
         set
         {
            enteredText = value;
            this.SearchCommand.Execute(null);
            OnPropertyChanged(nameof(EnteredText));
        }
    }


    void  ExecuteSearchCommand(object parameter)
    {
        if (enteredText.Length>=1)
        {
            MyList = new ObservableCollection<PhV_Get>(phrasalVerbGet
                .Where(x => x.PhrasalVerb.ToLower()
                .Contains(enteredText.ToLower())).ToList());
        }
        else
        {
            MyList = phrasalVerbGet;
        }

    }

    public ObservableCollection<PhV_Get> MyList
    {
        set
        {
            phrasalVerbGet = value;
            OnPropertyChanged(nameof(MyList));
        }
        get
        {
            return phrasalVerbGet;
        }
    }

    public Command SearchCommand {
        get
        {
            return new Command(ExecuteSearchCommand, 
            CanExecuteSeachCommand);
        }
    }

    public bool CanExecuteSeachCommand(object parameter)
    {
        return true;
    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        this.PropertyChanged?.Invoke(this, new 
                    PropertyChangedEventArgs(propertyName));
    }

Upvotes: 1

Views: 749

Answers (1)

Dave Smash
Dave Smash

Reputation: 3001

The line MyList = new ObservableCollection in ExecuteSearchCommand is a no-no. Your listview is bound to the old ObservableCollection - when you create a new one, then you break that binding and the view will not update because it doesn't know anything about the new one.

When you need to change the contents of an observable collection, do it like this (in pseudocode):

MyList.Clear();
foreach (thing in myListOfThings) 
{
    MyList.Items.Add(thing);
}

That way you are updating the collection that the ListView is bound to, and the ListView will see the changes.

Upvotes: 1

Related Questions