Issue
Please help.I have a listview where I write data from the VM.I have a list of car brands and I want to use the search bar to display only what matches the text in the search bar. For example I have a list
BAC
BAE
BAIC
Bailey
Bajaj
Baker
Electric
Baldwin-Motion
Ballot
When I write for example Bai or bai I want that my list show me
BAIC
Bailey
Please help me
XAML CODE
<Frame CornerRadius="15" HasShadow="True" BorderColor="LightGray" Margin="10,10,10,0" Padding="5">
<controls:CustomSearchBar x:Name="searchBar" TextColor="Gray"
/>
</Frame>
<StackLayout>
<ListView x:Name="Company" SelectionMode="None" ItemsSource="{Binding Cars}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackLayout Spacing="0">
<BoxView
HeightRequest="1"
BackgroundColor="LightGray"
HorizontalOptions="FillAndExpand" VerticalOptions="Start" />
<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 .}"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
VM CODE
public class CarAddCompany : INotifyPropertyChanged
{
public ObservableCollection<Car> Cars { get; }
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 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();
}
public CarAddCompany(INavigation navigation,MainCar carC)
{
mainCar = carC;
this.Navigation = navigation;
this.navigateCommand = new Command(async () => await GotoPage2());
navigateCommandBACK = new Command(async () => await GotoPage1());
Cars = new ObservableCollection<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 });
ChangeMark = new Command<Car>((key) =>
{
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));
}
}
Solution
Change ListView itemsource from cars to new observable collection say SearchedCars
private ObservableCollection<Car> searchedCars = new ObservableCollection<Car>();
public ObservableCollection<Car> SearchedCars { get => searchedCars; set { searchedCars = value;OnPropertyChanged("SearchedCars");} }
<ListView x:Name="Company" SelectionMode="None" ItemsSource="{Binding SearchedCars}">
After that use Corcav.Behavior nuget to get searchbar textChanged event to your ViewModel https://github.com/corradocavalli/Corcav.Behaviors
...
xmlns:corcav="clr-namespace:Corcav.Behaviors;assembly=Corcav.Behaviors"
...
<SearchBar>
<corcav:Interaction.Behaviors>
<corcav:BehaviorCollection>
<corcav:EventToCommand EventName="TextChanged" Command="{Binding Path=SearchBarTextChangedCommand}" PassEventArgument="True"/>
</corcav:BehaviorCollection>
</corcav:Interaction.Behaviors>
</SearchBar>
Add and initialize command and finally apply the filter
public ICommand SearchBarTextChangedCommand { get; set; }
...
SearchBarTextChangedCommand = new Command<object>(OnSearchBarTextChanged);
...
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();
}
}
Answered By - Shubham Tyagi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.