【问题标题】:How to use search bar with ObservableCollection and List in MVVM如何在 MVVM 中使用带有 ObservableCollection 和 List 的搜索栏
【发布时间】:2020-09-30 16:27:06
【问题描述】:

请帮助。我有一个列表视图,我在其中写入来自 VM 的数据。我有一个汽车品牌列表,我想使用搜索栏仅显示与搜索栏中的文本匹配的内容。 例如我有一个列表

BAC

BAE

北汽

贝利

巴贾杰

贝克

电动

鲍德温运动

投票

当我写例如白或白时,我希望我的列表显示给我

北汽

贝利

请帮帮我

XAML 代码

<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>

虚拟机代码

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));
        }
    }

【问题讨论】:

标签: c# xaml xamarin xamarin.forms xamarin.android


【解决方案1】:

将 ListView itemsource 从汽车更改为新的可观察集合,例如 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}">

之后使用 Corcav.Behavior nuget 将搜索栏 textChanged 事件发送到您的 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>

添加和初始化命令,最后应用过滤器

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();
            }
        }

【讨论】:

  • 它有效,谢谢,但请告诉我如何做,以便当您删除搜索栏中的文本时,返回最后一个列表,只剩下我写的搜索栏
  • 请同时接受答案,如果它回答了您的问题并且我无法理解这一点:当您删除搜索栏中的文本时,返回最后一个列表,并且仅我写的搜索栏仍然存在请改写。
  • 我接受了。然后。我改写另一个问题。如果你知道请帮忙
  • 这是另一个问题的链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多