Forum Xamarin Xamarin.Forms

Retaining SelectedItem/Index in Picker control when ObservableCollection is cleared and rebuilt

Hi all, I am sorry if this has been asked before. I have searched the forums and can't seem to find what I'm looking for.

I have recreated this in a simple standalone app. On my form I have a Picker control (nothing custom) and bound its ItemsSource to an ObservableCollection:

    <Picker ItemsSource="{Binding Source}" 
            ItemDisplayBinding="{Binding Desc}" 
            Title="Select an Item"
            SelectedIndexChanged="Picker_SelectedIndexChanged" />

A class represents each item in the ObservableCollection:

    public class ListItemModel : IValueDescItem
        public ListItemModel(string value, string desc)
            Value = value;
            Desc = desc;

        public string Value { get; }

        public string Desc { get; }

I have a simple loop to populate this ObservableCollection with 10 ListItemModels.

    for (int i = 0; i < 10; i++)
        Debug.WriteLine($"this.Source.Add() {i}");
        this.Source.Add(new ListItemModel(i.ToString(), "Item " + i.ToString()));

There is a Refresh button that Clears and re-populates the ObservableCollection with the same items by calling the above code. Note: Source is cleared and not re-instantiated.

Unfortunately this Refresh event also clears the SelectedItem/Index (value is blanked out on the screen) in the Picker control even though the previously selected item is still valid in the rebuilt collection.

Internet results seem to only have one solution: That you need to store the selected value away, rebuild the collection, and re-apply the value to the Picker control.

Is this really the only (and best practice) way?

Best Answer


  • cbananascbananas Member ✭✭

    Haha thanks. I understand that different object subtlety. I am just checking I have not missed something obvious/better?

  • JoeMankeJoeManke USMember ✭✭✭✭✭

    I would need to double check the source, but it's possible that if you override the Equals method on your ListItemModel class that the Picker will recognize it as an equivalent item and auto-select it.

  • cbananascbananas Member ✭✭

    Overriding the Equals method did help with storing the SelectedItem into a temp variable and then using that temp variable to re-assign SelectedItem on the Picker after collection refresh. The following code does not work without overriding Equals.

        var temp = this.SelectItemModel;
        await refreshSource();
        this.SelectItemModel = temp;

    but as Spot said earlier :-P you still need to use a temp variable to retain that selected value (or index)

Sign In or Register to comment.