Search code examples
mvvmdata-bindingmauipicker.net-8.0

.net Maui Not Binding many to many to same table in Picker


I'm creating an app to register Teams for Sportstatistics. In this case I need a View (MVVM) to select two teams and assign the results of a game. The first part of the view (the collectionview) works as expected. My current games show up in the left pane. On the right side is form to add new games and to edit a selected game. My teams are showing up in the pickers but the problem is my View is not showing the selected team in the Picker after selecting an game on the left side.

This is the View:

    <Grid RowDefinitions="*" ColumnDefinitions="*, *">
        <CollectionView Grid.Row="0" Grid.Column="0" SelectionMode="Single" ItemsSource="{Binding Games}" EmptyView="No items to display" SelectedItem="{Binding SelectedGame}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Games">
                    <VerticalStackLayout Padding="5">
                        <Label FontSize="14">
                            <Label.Text>
                                <MultiBinding StringFormat="- {0:d}: {1} - {3} ({2}-{4})">
                                    <Binding Path="Date"/>
                                    <Binding Path="Team1.Name" />
                                    <Binding Path="ResultTeam1" />
                                    <Binding Path="Team2.Name" />
                                    <Binding Path="ResultTeam2" />
                                </MultiBinding>
                            </Label.Text>
                        </Label>
                    </VerticalStackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

        <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" HorizontalOptions="Fill" VerticalOptions="Center" Color="{StaticResource Primary}" Grid.RowSpan="1" Grid.ColumnSpan="1" />
            
        <VerticalStackLayout Grid.Row="0" Grid.Column="1" Spacing="10">
            <Picker Title="Team 1" ItemsSource="{Binding Teams}" SelectedItem="{Binding SelectedGame.Team1}" ItemDisplayBinding="{Binding Name}" />
            <Picker Title="Team 2" ItemsSource="{Binding Teams}" SelectedItem="{Binding SelectedGame.Team2}" ItemDisplayBinding="{Binding Name}" />
            <Label Text="Result team 1" />
            <Entry Placeholder="Result team 1" Text="{Binding SelectedGame.ResultTeam1}" />
            <Label Text="Result team 2" />
            <Entry Placeholder="Result team 2" Text="{Binding SelectedGame.ResultTeam2}" />
  
            <HorizontalStackLayout Spacing="10">
                <Button Text="Add" Command="{Binding AddCommand}"/>
                <Button Text="Edit" Command="{Binding EditCommand}"/>
                <Button Text="Deselect" Command="{Binding DeselectCommand}"/>
            </HorizontalStackLayout>
        </VerticalStackLayout>

ViewModel:

    public partial class GameViewModel : BaseViewModel
    {
        [ObservableProperty]
        public ObservableCollection<Game> games;

        [ObservableProperty]
        public ObservableCollection<Team> teams;


        [ObservableProperty]
        public Game selectedGame;

        private TeamRepository _teamRepository;
        private GameRepository _gameRepository;

        public GameViewModel(TeamRepository teamRepository, GameRepository gameRepository)
        {
            _teamRepository = teamRepository;
            _gameRepository = gameRepository;

            RefreshGames();
            Teams= new ObservableCollection<Team>(_teamRepository.GetTeams());

            SelectedGame = new Game();
            Title = "Games";
        }

        private void RefreshGames()
        {
            Games= new ObservableCollection<Game>(_gameRepository.GetGames());
        }
...

Game Class

    public class Game
    {
        public int Id { get; set; }
        public int Team1Id { get; set; }
        public int Team2Id { get; set; }
        public Team Team1 { get; set;}
        public Team Team2 { get; set; }

        [DataType(DataType.Date)]
        public DateTime Date{ get; set; } = DateTime.Now;
        public int ResultTeam1 { get; set; }
        public int ResultTeam2 { get; set; }
    }

Using this methods I succesfully created Views where my data is retrieved and shown in the Picker after selecting an item on the left side.

This View features selecting two teams from the same entity. And somehow .net Maui does not compute.

The selectedItem returns my object correct but my pickers remains blank. The Entries for the results are filled in properly.

I was expecting to see my SelectedGame.Teams in the Pickers.

Got any ideas?


Solution

  • If you're binding models, you have to add Equals in the model for proper binding.

    Model Team.cs:

    public override bool Equals(object obj)
    {
       return obj is Team team && Id == team.Id;
    }
    

    That does the trick.