Search code examples
c#.netmaui

Multi-Collection Views - Display .NET MAUI CollectionView within a CollectionView


I am developing a c# .NET Maui application that creates a bowling app that maintains a recap of scores for bowling team. The requirements are that it is a general application that supports leagues that have bowlers that are supporting 2 to many team members. In addition, the amount of games per match can support multiple games based on league rules. Typically, most leagues have a 3 game requirenment for each bowler but there are leagues that support more than 3. Bottom line, there is a requirement to support 2 to many bowlers with 1 to many games.

I am currently experiencing problems with my code that I am unable to solve. Specifically, after dislaying bowler - Name, Average, Handicap, I attempt to display a horizontal line with games played, Line truncates and I only get a partial display. Below is my code. Any help is greatly appreciated.

type here

Results

using CollectionView2022.Models;
namespace CollectionView2022
{
    public partial class MainViewModel : ObservableObject
    {
        [ObservableProperty]
        int rows;
        [ObservableProperty]
        int cols;
        [ObservableProperty]
        ObservableCollection<Bowler> bowlers;
        [ObservableProperty]
        List<Game> scores;
        List<string> gameNames = new List<string> { "Rick", "Bob", "Colton", "Jeff" };
        public MainViewModel()
        {
            Rows = 1;
            Cols = 1;
            Bowlers = new ObservableCollection<Bowler>();
        }
        [RelayCommand]
        private void Generate()
        {
            int dr = 0;
            int dc = 0;
            int s = 200;
            //Scores = new List<Game>();
            //if (cols > 1)
            //{
            //    do
            //    {
            //        Scores.Add(new Game { game=0});
            //        dc++;
            //    } while (dc < cols);
                
            //    dc++;
            //}
            do
            {
                Bowlers.Add(new Bowler
                {
                    Average = 0,
                    Name = gameNames[dr],
                    Handicap = 0

                });
                Bowlers[dr].Scores = new List<Game>();
                do
                {
                    Bowlers[dr].Scores.Add((Game)new Game { score = s });
                    dc++;
                    s=s+10;
                } while (dc < cols);
                dc = 0;
                dr++;
            } while (dr < rows);
            
        }
        
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:model="clr-namespace:CollectionView2022.Models"
             xmlns:viewmodel="clr-namespace:CollectionView2022"
             x:DataType="viewmodel:MainViewModel"
             x:Class="CollectionView2022.MainPage">

    <ScrollView>
        <VerticalStackLayout
        Padding="30,0"
        Spacing="25">

            <HorizontalStackLayout>
                <Label
                Text="Enter Bowlers: "
                
                SemanticProperties.HeadingLevel="Level1"/>
                <Entry 
                   x:Name="EnterRows" Text="{Binding Rows}" Keyboard="Numeric" ReturnType="Next"/>
                <Label
                Text="Enter Games: "
                
                SemanticProperties.HeadingLevel="Level1"/>
                <Entry ReturnCommand="{Binding GenerateCommand}"
                x:Name="EnterCols" Text="{Binding Cols}" Keyboard="Numeric" ReturnType="Send"/>
                <Button Text="Generate" Command="{Binding GenerateCommand}"/>
                
            </HorizontalStackLayout>
            <CollectionView ItemsSource="{Binding Bowlers}" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged">
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="model:Bowler">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="100" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Entry Grid.Column="0" Text="{Binding Name}" Keyboard="Text" ReturnType="Next"/>
                            <Entry Grid.Column="1" Text="{Binding Average}" Keyboard="Numeric" ReturnType="Next"/>
                            <Entry Grid.Column="2" Text="{Binding Handicap}" Keyboard="Numeric" ReturnType="Next"/>
                            <CollectionView Grid.Row="1" Grid.ColumnSpan="8" ItemsLayout="HorizontalList" ItemsSource="{Binding Scores}">
                                <CollectionView.ItemTemplate>
                                    <DataTemplate x:DataType="model:Game">
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                                <ColumnDefinition Width="Auto" />
                                            </Grid.ColumnDefinitions>
                                            
                                            <HorizontalStackLayout>
                                                <Entry Text="{Binding score}" Keyboard="Numeric" ReturnType="Next"/>
                                            </HorizontalStackLayout>

                                            <!--<Entry Grid.Column="4" Text="{Binding score}" Keyboard="Numeric" ReturnType="Next"/>
                                <Entry Grid.Column="5" Text="{Binding score}" Keyboard="Numeric" ReturnType="Next"/>
                                <Entry Grid.Column="6" Text="{Binding score}" Keyboard="Numeric" ReturnType="Next"/>-->
                                        </Grid>

                                    </DataTemplate>
                                </CollectionView.ItemTemplate>
                            </CollectionView>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            
                            <!--<Entry Grid.Column="3" Text="{Binding Games}"/>-->
                        
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

using CollectionView2022.Models;
namespace CollectionView2022
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            BindingContext=new MainViewModel();
        }

        private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }

}

namespace CollectionView2022.Models
{
    public class Game
    {
        public int score { get; set; }
    }
}

namespace CollectionView2022.Models
{
    public class Bowler
    {
        public string Name { get; set; }
        public int Average { get; set; }
        public int Handicap { get; set; }
        public List<Game> Scores { get; set; }
    }
}

global using CommunityToolkit.Mvvm.ComponentModel;
global using CommunityToolkit.Mvvm.Input;
global using System.Collections.ObjectModel;
global using System.ComponentModel;
global using System.Diagnostics;
global using System.Runtime.CompilerServices;
global using System.Text.Json;

Solution

  • Thanks to Sir Rufo, I added Grid.ColumnSpan="8" to my CollectionView relative to the score line of my XAML code and it corrected my truncation issue.