Search code examples
xamlxamarinxamarin.formsxamarin.android

XAML forms have second picker sorted based on selection in first picker


I have 2 dropdowns (pickers) on a XAML form. The first is an ObservabelCollection of Territories. The second is an ObservableCollection of type Tracks. When the form loads my ViewModel loads both collections and each collection is bound to a picker. I want to filter and display only those tracks that are associated with the selected territory in the second picker. FYI-the second picker is disabled until a selection is made in the first. Actually I don't require that the second picker's data source be set as the form loads, unless the solution requires it. The selection in the first picker will be the key to filter the data for the second. I have tried to handle the filtering in the Territory picker's SelectedIndexChanged event but my ObservableCollection 'tracks' is not exposed here.

private void territoryPicker_SelectedIndexChanged(object sender, EventArgs e)
    {
        var picker = (Picker)sender;
        string territory = picker.SelectedItem.ToString();

        Tracks _track = tracks.Where(X => X.Territory = territory);<<<==== Does not work
        trackPicker.ItemsSource = _track.Track;<<<==== Does not work

        trackPicker.IsEnabled = true;

    }

I've also tried to not build the Tracks OC until after the Territory is selected like this:

        private void territoryPicker_SelectedIndexChanged(object sender, EventArgs e)
    {
        var picker = (Picker)sender;
        string territory = picker.SelectedItem.ToString();

        TrackViewModel vm = new TrackViewModel(); 
        var _tracks = (Tracks)vm.Tracks;  <<<<<==== This does not work

        trackPicker.IsEnabled = true;

    }

The ViewModel runs and the tracks are loaded via the API but when it returns here Tracks is empty. I'm open to a reasonable solution (not 3rd party controls/packages) that will accomplish this task . Thanks


Solution

  • I figured it out by stumbling over the answer while researching another issue. I have been referencing my viewmodel in the {content].xaml page like this.

        <ContentPage.BindingContext>
        <vm:TrackViewModel />
    </ContentPage.BindingContext>
    

    When doing so the resources of that vm were not available in the code behind. But when I reference the VM in the page constructor Like this:

    public partial class RequestmyTracks : ContentPage
    {
        TrackViewModel trackviewmodel = new TrackViewModel();
    

    And then bind it here:

        public RequestmyTracks()
        {
            InitializeComponent();
            BindingContext = trackviewmodel;
        }
    

    The trackviewmodel is accessible in the SelectedIndexChanged event and everything else was really straight forward, Which looks like this:

        private void territoryPicker_SelectedIndexChanged(object sender, EventArgs e)
        {
            var picker = (Picker)sender;
            string territory = picker.SelectedItem.ToString();
            ObservableCollection<Tracks> dah = (ObservableCollection<Tracks>)trackviewmodel.Tracks;
            List<string> trackNames = new List<string>();
    
            foreach (var track in dah)
            {
                if (track.Territory == territory)
                    trackNames.Add(track.Track);
            }
            trackPicker.ItemsSource = trackNames;
            if(trackNames.Count ==1)
                trackPicker.SelectedIndex = 0;
    
            trackPicker.IsEnabled = true;
        }
    

    Thanks for the help