'Xamarin forms set Picker SelectedItem

I am working with a xamarin Forms. I am using Picker for DropDownList.

How can I set selectedItem to Picker?

My code

<Picker x:Name="VendorName" Title="Select" ItemDisplayBinding="{Binding VendorName}" SelectedItem="{Binding VendorName}" Style="{StaticResource PickerStyle}"></Picker>

and server side code is

Device.BeginInvokeOnMainThread(() =>
{
VendorName.ItemsSource = VendorList;
});

var currentVendor = new List<Vendor>();
currentVendor.Add(new Vendor { VendorID = "111", VendorName = "aaaa" });

VendorName.SelectedItem = currentVendor;


Solution 1:[1]

This may not be the most efficient but you could loop to find the index and set that way.

for (int x = 0; x <  VendorList.Count; x++)
        {
            if (VendorList[x].VendorName == currentVendor .VendorName )
            {
                VendorName.SelectedIndex = x;
            }
        }

Solution 2:[2]

After adding all values as list in Picker

just treat with it as an array

so if you want to set selected item just set selected item index

currentVendor.SelectedIndex = 0;

zero means you make selected item is the first one you added to Picker

Solution 3:[3]

If you are using MVVM, and want to set SelectedItem from the view model, things get tricky. There seems to be a bug in Xamarin that prevents us from using SelectedItem with a two way binding. More info: Xamarin Forms ListView SelectedItem Binding Issue and https://xamarin.github.io/bugzilla-archives/58/58451/bug.html.

Luckily, we can easily write our own Picker.

    public class TwoWayPicker : Picker
    {
        public TwoWayPicker()
        {
            SelectedIndexChanged += (sender, e) => SelectedItem = ItemsSource[SelectedIndex];
        }

        public static new readonly BindableProperty SelectedItemProperty = BindableProperty.Create(
            nameof(SelectedItem), typeof(object), typeof(TwoWayPicker), null, BindingMode.TwoWay, propertyChanged: OnSelectedItemChanged);
        public new object SelectedItem
        {
            get => GetValue(SelectedItemProperty);
            set => SetValue(SelectedItemProperty, value);
        }
        private static void OnSelectedItemChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (TwoWayPicker)bindable;
            control.SetNewValue(newValue);
        }
        private void SetNewValue(object newValue)
        {
            if (newValue == null)
            {
                return;
            }
            for(int i = 0; i < ItemsSource.Count; i++)
            {
                if (ItemsSource[i].Equals(newValue))
                {
                    SelectedIndex = i;
                    return;
                }
            }
        }
    }

Because is uses the same SelectedItem property, it is a drop-in replacement for Picker.

Note that if you want value equality rather than reference equality for the item class, you'll also need to override Equals like this:

        public override bool Equals(object obj)
        {
            var other = obj as YourClass;
            if (other == null)
            {
                return false;
            }
            else
            {
                return other.SomeValue == SomeValue; // implement your own
            }
        }

Solution 4:[4]

If you define the item class as a record instead of a class then it can select the item programmatically using the SelectedItem property.

In your case change

public class Vendor  { // your class properties }

to

public record Vendor  { // your class properties }

This will now work

VendorName.SelectedItem = currentVendor;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sonicbabbler
Solution 2 Mahmoud Kamel
Solution 3
Solution 4 Nulle