SearchBar in ObserwableCollection e List MVVM

Oct 01 2020

Ho SearchBar che in tempo reale cerca le informazioni da List.Ma ho un problema.Ad esempio quando scrivo il testo nel campo viene visualizzato il nuovo testo ma quando cancello una parte del testo non viene aggiornato al precedente stato. Questo è se ho una lista:

BAC

BAE

BAIC

Bailey

Bajaj

Panettiere

Elettrico

Baldwin-Motion

Votazione

Quando scrivo ad esempio Bai o bai la mia lista me lo mostra

BAIC

Bailey Ma quando si cancella la lettera (ora ba) deve mostrare BAC

BAE

BAIC

Bailey

Bajaj

Panettiere

Ma è ancora BAIC

Bailey

Per favore aiuto

Codice Xaml

 <Frame CornerRadius="15" HasShadow="True" BorderColor="LightGray" Margin="0,10,0,0" Padding="5">
                    <controls:CustomSearchBar x:Name="searchBar"  
            TextColor="Gray" 
                 >
                    <!---->    <corcav:Interaction.Behaviors>
                            <corcav:BehaviorCollection>
                                <corcav:EventToCommand EventName="TextChanged" Command="{Binding Path=SearchBarTextChangedCommand}" PassEventArgument="True"/>
                            </corcav:BehaviorCollection>
                        </corcav:Interaction.Behaviors>
                    </controls:CustomSearchBar>
                </Frame>
   <ListView x:Name="Company"   SelectionMode="None" ItemsSource="{Binding SearchedCars}">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                <Grid >
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="46" />

                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                    </Grid.ColumnDefinitions>
                                    <StackLayout>
                                        <controls:ExtendedButton2   HeightRequest="45" Padding="5,10,0,10"
                             WidthRequest="300"   Margin="0"  HorizontalTextAlignment="Start"
                         BackgroundColor="{Binding CustButtonColor}" Text="{Binding Name}" TextColor="Gray" FontSize="18" 
                                           Command="{ Binding BindingContext.ChangeMark, 
                                            Source={x:Reference Name=Company} }"  CommandParameter="{Binding .}"/>

                                        <BoxView   Margin="0,-6,0,0" 
            HeightRequest="1" 
            BackgroundColor="LightGray" 
            HorizontalOptions="FillAndExpand"  VerticalOptions="End"/>
                                    </StackLayout>
                                    
                                </Grid>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

ViewModel

 class CarAddCompany : INotifyPropertyChanged
    {
        private List<Car> Cars = new List<Car>();

        public List<Car> SearchedCars { get => Cars; set { Cars = value; OnPropertyChanged("SearchedCars"); } }
        public ICommand ChangeMark { protected set; get; }
        public MainCar mainCar { get; set; }
        INavigation Navigation { get; set; }

        public Command navigateCommand { get; set; }

        public Command navigateCommandBACK { get; set; }
        public ICommand SearchBarTextChangedCommand { get; set; }
        public async Task GotoPage2()
        {
            if (mainCar.MarkCar != null) await Navigation.PushModalAsync(new Car_add_model(mainCar));
        }
        public async Task GotoPage1()
        {
            //mainCar.MarkCar ="";
            //   await Navigation.PushModalAsync(new Car_add());
            await Navigation.PopModalAsync();
        }
        private void OnSearchBarTextChanged(object obj)
        {
            if (obj is TextChangedEventArgs args)
            {
                string filter = args.NewTextValue;
                SearchedCars = Cars.Where(x => x.Name.ToLower().Contains(filter.Trim().ToLower())).ToList();
            }
        }
        public CarAddCompany(INavigation navigation,MainCar carC)
        {
            mainCar = carC;

            this.Navigation = navigation;
            this.navigateCommand = new Command(async () => await GotoPage2());
            navigateCommandBACK = new Command(async () => await GotoPage1());
            SearchBarTextChangedCommand = new Command<object>(OnSearchBarTextChanged);
            Cars = new List<Car>();
          Cars.Add(new Car() { Name = "BAC", CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "BAE", CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "BAIC",  CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "Bailey",  CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "Bajaj",  CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "Baker", CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "Electric", CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "Baldwin-Motion",CustButtonColor = Color.White });
        Cars.Add(new Car() { Name = "Ballot",  CustButtonColor = Color.White });

         

                foreach (var item in Cars)
                {

                    item.CustButtonColor = Color.White;
                }
                    
                    var car = key as Car;
                    car.CustButtonColor = Color.FromHex("#D1DAED");
                    mainCar.MarkCar = car.Name;

                
            });
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Voglio che quando cancello una parola mostri l'elenco precedente con Ba. A seconda del testo nella barra di ricerca

Risposte

1 ShubhamTyagi Oct 01 2020 at 19:38

Aggiornalo ed esegui il debug di questo metodo

private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
        {
            string filter = e.NewTextValue;
            if (!string.IsNullOrEmpty(filter))
            {
                var filterList = cars.Where(x => x.Name.ToLower().Contains(filter.Trim().ToLower())).ToList();
                SearchedCars = new ObservableCollection<Car>(filterList);
            }
            else
                SearchedCars = new ObservableCollection<Car>(cars);
        }
1 ShubhamTyagi Oct 02 2020 at 03:41

Hai identificato Cars e SearchCars, queste sono due raccolte separate

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using Xamarin.Forms;
namespace App1
{
    class CarAddCompany : INotifyPropertyChanged
    {
        private List<Car> Cars = new List<Car>();

        private List<Car> searchedCars = new List<Car>();
        public List<Car> SearchedCars { get => searchedCars; set { searchedCars = value; OnPropertyChanged("SearchedCars"); } }

        public ICommand ChangeMark { protected set; get; }

        private INavigation navigation;

        private INavigation GetNavigation()
        {
            return navigation;
        }

        private void SetNavigation(INavigation value)
        {
            navigation = value;
        }

        public ICommand SearchBarTextChangedCommand { get; set; }

        private void OnSearchBarTextChanged(object obj)
        {
            if (obj is TextChangedEventArgs args)
            {
                string filter = args.NewTextValue;
                SearchedCars = Cars.Where(x => x.Name.ToLower().Contains(filter.Trim().ToLower())).ToList();
            }
        }
        public CarAddCompany(INavigation navigation)
        {
            this.SetNavigation(navigation);

            SearchBarTextChangedCommand = new Command<object>(OnSearchBarTextChanged);
            Cars = new List<Car>();
            Cars.Add(new Car() { Name = "Ford", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Toyota", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Honda", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Tesla", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Chevrolet", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "BMW", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Audi", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Mercedes", CustButtonColor = Color.White });
            Cars.Add(new Car() { Name = "Lexus", CustButtonColor = Color.White });

            SearchedCars = new List<Car>(Cars);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}