14
votes

I have been looking everywhere to try and solve this issue, I have not been using Xamarin forms for long but I thought it would have been easy. I am trying to bind a picker selecteditemchanged to a command in the view model, I am using FreshMVVM and Xamarin forms version 2.3.4.214-pre5, I am able to bind the data from the view model but there is no Command option in the picker.

Any help would be appreciated. Thank you

5
I think there is a SelectedItem property that change when you select a value. Which command are you searching for?Alessandro Caliaro

5 Answers

19
votes

I have been able to get a working solution:

First off I installed Xamarin Forms version 2.3.4.214-pre5, it is working just fine. Then with the help of the Xamarin Forum, I was given a solution, which is as-follows:

1 - Install the Behaviors.Forms NuGet package by running Install-Package Behaviors.Forms in the NuGet package manager console.

2 - Then include the following namespace in the XAML page:

<ContentPage xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors">
</ContentPage>

3 - Then add the Picker.Behaviors attribute in the Picker tag:

<Picker x:Name="MyPicker"
          ItemsSource="{Binding IdentityProviders}"
          HorizontalOptions="FillAndExpand" Title="Identity Provider"
          Margin="10"
          ItemDisplayBinding="{Binding Description}">
    <Picker.Behaviors>
          <behaviors:EventHandlerBehavior EventName="SelectedIndexChanged">
              <behaviors:InvokeCommandAction Command="{Binding SelectedProviderChanged}" />
          </behaviors:EventHandlerBehavior>
    </Picker.Behaviors>
</Picker>

If you want to pass the data back as a parameter then include the following after the command CommandParameter="{Reference MyPicker}"

That solved my problem, I hope this helps: The help I got was from this post MVVM Light - How to use the selectedIndexChanged event in viewModel

6
votes

All you need to do is monitor the SelectedItem property in your view model.

        private ObservableRangeCollection<UserViewModel> _users = new ObservableRangeCollection<UserViewModel>();
        public ObservableRangeCollection<UserViewModel> Users
        {
            get => _users;
            set { _users = value; OnPropertyChanged(); }
        }

    private User _selectedUser;
        public UserModelView CurrentUser
        {
            get => _selectedUser;
            set { _selectedUser = value; 
                  //Do Some stuff with your new user(); 
                  OnPropertyChanged(); 
}
        }



<Picker WidthRequest="100" 
                ItemsSource="{Binding Users}"
                ItemDisplayBinding="{Binding Name}"
                SelectedItem="{Binding CurrentUser, Mode=TwoWay}" />
1
votes

I found the solution here: https://forums.xamarin.com/discussion/71084/call-command-programmatically-without-binding-to-button

In file.xaml:

<Picker
       SelectedIndexChanged="Handle_SelectedIndexChanged"
       ItemsSource="{Binding FilterOptions}"
       ItemDisplayBinding="{Binding Value}" />

In file.xaml.cs:

TransactionViewModel ViewModel { get => BindingContext as TransactionViewModel; set => BindingContext = value; }

void Handle_SelectedIndexChanged(object sender, System.EventArgs e)
{
    var selectedOption = (sender as Picker).SelectedItem;
    ViewModel.ChangeOptionCommand.Execute(selectedOption);
}

In view-model:

public ICommand ChangeOptionCommand { get; private set; }

public TransactionViewModel()
{
    ChangeOptionCommand = new Command<KeyValuePair<string, string>>(ChangeOption);
}

void ChangeOption(KeyValuePair<string, string> selectedOption)
{
    Debug.WriteLine(selectedOption);
}
0
votes

Not sure of command , but whenever there is change in picker value, "SelectedItem" value is also being changed. We can bind object from viewmodel to "SelectedItem". On setting value for this object, we can perform out required things at property set.In this way no need to write "SelectedIndexChanged" function.

-5
votes

To run code when a picker item is selected, specify the SelectedIndexChanged property of your picker:

<Picker x:Name="myPicker" SelectedIndexChanged="indexChanged"/>

Then in your code behind add your indexChanged method:

void indexChanged(object sender, EventArgs e) 
{
    //Your code here
}

Then, when a user selects a different item from your picker, it will run the indexChanged method.