xamarin.formsfreshmvvm

How to populate a picker based on selection in another picker?


I have a Xamarin.Forms application, and it uses FreshMvvm. I have two picker controls for selecting countries and states/provinces. The picker of countries is populated initially, but the list of states/provinces should be populated on the fly based on the selected country. I cannot find how it can be done using command and not code-behind event handling. Here are my controls in MyPage.xaml:

            <Picker Title="Choose Country..."
            ItemsSource="{Binding Countries}"
            ItemDisplayBinding="{Binding Value}"
            SelectedItem="{Binding SelectedCountry}"
            Margin="0, 0, 0, 5" />

            <Picker Title="Choose State..."
            ItemsSource="{Binding States}"
            ItemDisplayBinding="{Binding Value}"
            SelectedItem="{Binding SelectedState}"
            Margin="0, 0, 0, 5" />

What should I put in MyPageModel.cs?


Solution

  • using Freshmvvm you can make use of the WhenAny method and listen to changes on the SelectedCountry property. When this happens you will get filter the collection of the states by country using the SelectedCountry and update your States collection with the result.

    That should look like this:

    [PropertyChanged.AddINotifyPropertyChangedInterface]
    public class MyViewModel : FreshBasePageModel
    {
        public ObservableCollection<Country> Countries { get; set; }
    
        public ObservableCollection<State> States { get; set; }
    
       // This would be the collection where you have all the States
        private List<State> _allStatesCollection = new List<State>();
    
        public Country SelectedCountry { get; set; }
    
        public MyViewModel()
        {
           // Listening for changes on the `SelectedCountry`
            this.WhenAny(OnCountryChanged, o => o.SelectedCountry);
        }
    
        //Method called when a new value is set in the `SelectedCountry` property
        private void OnCountryChanged(string property)
        {   
            //Filter the collection of states and set the results     
            var states = _allStatesCollection.Where(a => a.CountryCode == SelectedCountry.Code).ToList();        
            States = new ObservableCollection<State>(states);
        }
    }
    

    Note: The code above expects you to be using the Fody INotifyPropertyChanged Nuget package. In case you are not using it, you can either install it or implement your properties PropertyChanged manually. That won't change the rest of the code.

    Hope this helps.-