steve
steve

Reputation: 917

complexed Issue with hiding ListView Xamarin Forms

I have a search bar with the property Text binded to a string property in my ViewModel.

I also have Behaviors within the search bar so that every time the text is changed a search is done within a list of objects using NewTextValue passed to as the query string.

The issue I have is that, I make the ListView invisible until a non-empty string is passed to my Search/Filter command (obviously.. :)). I have tried to enforcing hiding the ListView for a couple scenarios e.g. if all text is removed from the search bar.

When an item is selected from the now visible list view I used that item to populate the Text property of my SearchBar, after which I cannot hide it within code. All attempts have failed and the ListView remains visible. Note: I explicity created a hide button separately and saw it worked so I am wondering if I cannot tie hiding the view with setting the searchbar Text property.

View

<SearchBar Text="{Binding SearchText}">
                    <SearchBar.Behaviors>
                        <prismBehaviors:EventToCommandBehavior EventName="TextChanged"
                                                               Command="{Binding FilterOccupationsListCommand}"
                                                               EventArgsParameterPath="NewTextValue"/>
                    </SearchBar.Behaviors>
                </SearchBar>
                <ListView ItemsSource="{Binding FilteredOccupations}" IsVisible="{Binding FilteredOccupationsVisible}"  SelectedItem="{Binding Occupation, Mode=TwoWay}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <TextCell Text="{Binding Name}"/>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

Please Note : My ViewModel inherits from BaseViewModel which inherits INotifyPropertyChanged. SetProperty() is what notifies the property. This is quite common with MvvmCross, Prism etc.

ViewModel

public class MyViewModel : BaseViewModel
{
    public DelegateCommand<string> FilterOccupationsListCommand { get; }
    public MyViewModel()
    {
        FilterOccupationsListCommand = new DelegateCommand<string>(FilterOccupationsList);
    }
    private void FilterOccupationsList(string query)
    {
        if (!string.IsNullOrWhiteSpace(query))
        {
            FilteredOccupationsVisible = true;
            var searchResult = Occupations.Where(x => x.Name.ToLower().Contains(query));
            FilteredOccupations = new ObservableCollection<Occupation>(searchResult);
        }
        else
            FilteredOccupationsVisible = false;
    }

    private Occupation _occupation;
    public Occupation Occupation
    {
        get => _occupation;
        set
        {
            SetProperty(ref _occupation, value);
            SearchText = value.Name;
        }
    }

    private string _name;
    public string Name { get => _name; set => SetProperty(ref _name, value); }
    private string _searchText;
    public string SearchText 
    { 
        get => _searchText; 
        set { 
              SetProperty(ref _searchText, value); 
              FilteredOccupationsVisible = false;
            } 
    }

    private bool _filteredOccupationsVisible;
    public bool FilteredOccupationsVisible { get => _filteredOccupationsVisible; set => SetProperty(ref _filteredOccupationsVisible, value); }

    public ObservableCollection<Occupation> _filteredOccupations = new ObservableCollection<Occupation>();
    public ObservableCollection<Occupation> FilteredOccupations { get => _filteredOccupations; set { SetProperty(ref _filteredOccupations, value); } }
}

Upvotes: 0

Views: 246

Answers (1)

Junior Jiang
Junior Jiang

Reputation: 12723

If not using Behaviors in SearchBar , you can have a try with TextChanged method of itself.

<SearchBar x:Name="MySearchBar" Text="SearchText" TextChanged="SearchBar_TextChanged" />

In ContentPage , when text cheanged fire here :

MyViewModel myViewModel = new MyViewModel();    

private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
    Console.WriteLine("new -- " + e.NewTextValue + "-- old -- " + e.OldTextValue);
    Console.WriteLine("MyEntry --" + MySearchBar.Text);
    //Here can invoke FilterOccupationsList of MyViewModel 
    myViewModel.FilterOccupationsList(MySearchBar.Text);
}

Else if using Command to do , you need to add isntance of ICommand in MyViewModel to invoke FilterOccupationsList.

public class MyViewModel : BaseViewModel
{
    public ICommand FilterOccupationsListCommand { private set; get; }
    ...

    public MyViewModel()
    {
       FilterOccupationsListCommand = new Command<string>((NewTextValue) =>
                {
                    // Pass value to FilterOccupationsList.
                    Console.WriteLine("SearchBar new text --" + NewTextValue);
                    FilterOccupationsList(NewTextValue);
                });    
    }
    ...
}

Upvotes: 1

Related Questions