UWP Combobox SelectedItem doesn’t bind

I’ve had problems using UWP ComboBoxes, the symptoms being that even by Binding the SelectedItem, nothing would be selected in the ComboBox when it was displayed. Sometimes this showed as, you could select something go, leave the page and return and the selection would be cleared, or even worse, it works on some visits to a page but not others when you hadn’t changed the selection.

So here’s some causes.

The collection items changes

Illistrated as an example on Stackoverflow. Basically if you re-create your collection items then it is impossible for selected item to be found in it, i.e. it looks like SelectedItem uses ReferenceEquals to find the item in the collection.

So this code has problems because it recreates the collection AND its items on every get,

public Item[] Items => new[] 
    new Item {Index = 1}, 
    new Item {Index = 2}, 
    new Item {Index = 3}, 
    new Item {Index = 4} 

but this is fine as the strings are constant, even though the collection changes

public string[] Strings => new[] {"1", "2", "3", "4"};

You specify a field instead of a property

I have no idea why this doesn’t work, but… if you specify a field

public string[] Strings = {"1", "2", "3", "4"};

then the binding will fail to select the items again, it needs to be specified as

public string[] Strings {get;} = {"1", "2", "3", "4"};

You specify the XAML in the wrong order

This is the massive WTF, and yet it is quite obvious really. I had the following code

<ComboBox SelectedItem="{x:Bind FirstItem}" ItemsSource="{x:Bind Items}"> ….

When you NEED to have

<ComboBox ItemsSource="{x:Bind Items}" SelectedItem="{x:Bind FirstItemMode=TwoWay, Mode=TwoWay}">

In this case, during the bind of the SelectedItem it is checked against an empty collection, and as a result, the selected Item ends up being set to null. Then the Items are bound.


One thing that helps is that if you switch your binding to Mode=OneWay then the binding will display correctly in the ComboBox (but obviously won’t update). Which does at least give us a starting point.