6
votes

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;
3
SelectedItem should be an Object, not a List<Object>Alessandro Caliaro
very very thanks. Working successfullyajoy

3 Answers

6
votes

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;
            }
        }
2
votes

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

0
votes

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
            }
        }