Search code examples
data-bindingbindinguicollectionviewmaui

The "Picker" in the "Collection view" does not pre-select any values in MAUI while the binding is working on the label


I'm trying to make the liaison between 2 observable collections : Milestones, Categories

On the model "Milestone", I've got a property "SelectedCategory"

public Category SelectedCategory
{
    get => selectedCategory;
    set
    {
        if (selectedCategory != value)
        {
            selectedCategory = value;
            OnPropertyChanged(nameof(SelectedCategory));
        }
    }
}

And I select it on the code-behind for each milestone :

foreach (var m in Milestones)
{
    m.SelectedCategory = Categories.FirstOrDefault(c => c.IdCategory == m.IdCategory);
}

However, the problem is that when I try to pre-select this category in my selector, nothing has been pre-selected. After checking all the code behind, I'm pretty sure the problem comes from the XAML :

<CollectionView Grid.Row="1" Margin="25,10,0,0" ItemsSource="{Binding Milestones}" VerticalOptions="FillAndExpand">
    <CollectionView.ItemTemplate>
        <DataTemplate>

                <Picker Grid.Column="2"
                ItemsSource="{Binding Path=BindingContext.Categories, Source={RelativeSource AncestorType={x:Type local:ModifyProjectPage}}}"
                ItemDisplayBinding="{Binding CategoryName}"
                SelectedItem="{Binding SelectedCategory, Mode=TwoWay}" />   

        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

By the way, the binding is working, I can see all category names and when I'm trying to do it with a label everything is working perfectly. And there is no error in the console

<Label Text="{Binding SelectedCategory.CategoryName}" />

Binding doesn't work without Source={RelativeSource AncestorType={x:Type local:ModifyProjectPage}}} :

<Picker Grid.Column="2"
ItemsSource="{Binding Categories}"
ItemDisplayBinding="{Binding CategoryName}"
SelectedItem="{Binding SelectedCategory, Mode=TwoWay}" /> 

Solution

  • The code of binding looks good. The Picker control is placed in the DataTemplate and the ItemsSource Property binds to Categories in ViewModel. So you may use Relative Bindings for ItemsSource of Picker.

    Another reason that I believe it's not a binding issue is that if I set a small delay, the PreSelected Picker Item will be displayed successfully.

    protected async override void OnAppearing()
    {
        base.OnAppearing();
        await Task.Delay(50);
    
        foreach (var m in viewModel.Milestones)
        {
            m.SelectedCategory = viewModel.Categories.FirstOrDefault(c => c.IdCategory == m.IdCategory);         
        }
    }
    

    However it's not a good solution. I can also reproduce this issue and you may consider raising an issue on Github.