Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP ComboBox SelectedItem does not bind as expected in flyout

Tags:

uwp

uwp-xaml

I fail to use the SelectedItem property of the Combobox. An item is correctly bound and displayed, but can not be changed to another one. If one tries to select an other item, the item list is correctly closed, but SelectedItem is not called (nor setter or getter) and the shown selected item is not changed.

My XAML is as follows:

<ComboBox
    ItemsSource="{Binding PasswordTypes}"
    ItemTemplate="{StaticResource PasswordTypeTemplate}"
    SelectedItem="{Binding SelectedPasswordType, Mode=TwoWay}"
    />

relevant ViewModel code:

public MyViewModel()
{
    //these are the only two assignments in code of those two properties
    _passwordTypes = new ObservableCollection<PasswordType>(nonEmptyList);
    _selectedPasswordType = PasswordTypes.First();
}

private PasswordType _selectedPasswordType;
public PasswordType SelectedPasswordType
{
    get => _selectedPasswordType;
    set => Set(ref _selectedPasswordType, value);
}

private ObservableCollection<PasswordType> _passwordTypes;
public ObservableCollection<PasswordType> PasswordTypes
{
    get => _passwordTypes;
    set => Set(ref _passwordTypes, value);
}

Calls to the two the properties are as follows:

  1. get PasswordTypes originating from this.InitializeComponent()
  2. get SelectedPasswordType originating from this.InitializeComponent()
  3. set SelectedPasswordType originating from this.InitializeComponent() to null
  4. set SelectedPasswordType originating from this.InitializeComponent() to an instance of PasswordType (_passwordTypes.Contains(value); evaluates to true)
  5. no further calls are made to the two properties afterwards

And here's what I'm seeing: ComboBox behaviour

I've created a branch with the minimal changes I needed to write this question: https://github.com/famoser/Bookmarked/compare/bug-failing-combobox

If I replace ComboBox with ListView, the SelectedItem is set correctly. The setup is therefore working correctly.

Do I need to set additional properties for the ComboBox for this to work, or is this a bug?

like image 377
Florian Moser Avatar asked Sep 06 '17 11:09

Florian Moser


1 Answers

The reason that it's not working is because your ComboBox never gets focus so the SelectionChanged event never gets fired.

This behavior is by design from Windows 10 build 14393 onward. The fix is simple - you just need to manually enable focus on interaction on your AppBarButton.

There's a new property called AllowFocusOnInteraction introduced in 14393 that does just this. So if you target 14393 and later, setting it to false is all you need to do.

If you target anything before that, you will need to do the following in the Loaded event of your AppBarButton .

private void AppBarButton_Loaded(object sender, RoutedEventArgs e)
{
    var allowFocusOnInteractionAvailable =
        Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent(
            "Windows.UI.Xaml.FrameworkElement",
            "AllowFocusOnInteraction");

    if (allowFocusOnInteractionAvailable)
    {
        if (sender is FrameworkElement s)
        {
            s.AllowFocusOnInteraction = true;
        }
    }
}

To read more on this behavior, please refer to Rob Caplan's excellent post "ComboBox on a Flyout attached to an AppBarButton loses mouse input on 1607".

like image 70
Justin XL Avatar answered Sep 17 '22 20:09

Justin XL