Picture on first page and more functioning on RoundStartingView

This commit is contained in:
2025-09-16 23:21:22 +02:00
parent 4e2b71af9f
commit a955218c7a
21 changed files with 335 additions and 74 deletions

View File

@ -67,6 +67,9 @@ public class GamePoint : EntityBase
} }
} }
// GameRoundRegNr räknas upp när en spelare får en ny gamepoint inlagd
// Alltså hans/hennes senaste i samma runda uppräknad med 1
[Column("GameRoundRegNr")] [Column("GameRoundRegNr")]
public int GameRoundRegNr public int GameRoundRegNr
{ {

View File

@ -0,0 +1,53 @@
namespace GreadyPoang.EntityLayer;
public class RoundBuilderGroup
{
public RoundBuilderGroup()
{
_gameRoundId = 0;
_gameRoundStartDate = DateTime.MinValue;
_status = GamePointStatus.New;
_elements = new List<RoundBuilderElement>();
}
private int _gameRoundId;
private DateTime _gameRoundStartDate;
private GamePointStatus _status;
private List<RoundBuilderElement> _elements;
public int GameRoundId
{
get { return _gameRoundId; }
set
{
_gameRoundId = value;
// No need to raise property changed for this example
}
}
public DateTime GameRoundStartDate
{
get { return _gameRoundStartDate; }
set
{
_gameRoundStartDate = value;
// No need to raise property changed for this example
}
}
public GamePointStatus Status
{
get { return _status; }
set
{
_status = value;
// No need to raise property changed for this example
}
}
public List<RoundBuilderElement> Elements
{
get { return _elements; }
set
{
_elements = value;
// No need to raise property changed for this example
}
}
}

View File

@ -0,0 +1,39 @@
using Common.Library;
using GreadyPoang.DataLayer;
using GreadyPoang.EntityLayer;
using System.Collections.ObjectModel;
namespace GreadyPoang.ViewModelLayer;
public class RoundRunningViewModel : ViewModelBase
{
public RoundRunningViewModel() : base()
{
}
public RoundRunningViewModel(
IRepository<GameRound> roundsRepo,
IRepository<GamePoint> pointsRepo,
IMethodSharingService<Participant> sharingService,
ICombinedRepository combined
) : base()
{
_roundsRepo = roundsRepo;
_pointsRepo = pointsRepo;
_sharingService = sharingService;
_combined = combined;
}
private readonly IRepository<GameRound>? _roundsRepo;
private readonly IRepository<GamePoint> _pointsRepo;
private readonly IMethodSharingService<Participant> _sharingService;
private readonly ICombinedRepository _combined;
private ObservableCollection<RoundBuilderGroup> _GameRoundList = new();
private ObservableCollection<Participant> _ParticipantList = new();
private ObservableCollection<RoundBuilderElement> _roundElements;
}

View File

@ -15,12 +15,12 @@ public class RoundStartingViewModel : ViewModelBase
} }
public RoundStartingViewModel( public RoundStartingViewModel(
IRepository<GameRound> repo, IRepository<GameRound> roundsRepo,
IRepository<GamePoint> pointsRepo, IRepository<GamePoint> pointsRepo,
IMethodSharingService<Participant> sharingService, IMethodSharingService<Participant> sharingService,
ICombinedRepository combined) : base() ICombinedRepository combined) : base()
{ {
_Repository = repo; _roundsRepo = roundsRepo;
_pointsRepo = pointsRepo; _pointsRepo = pointsRepo;
_sharingService = sharingService; _sharingService = sharingService;
_combined = combined; _combined = combined;
@ -30,9 +30,9 @@ public class RoundStartingViewModel : ViewModelBase
#endregion #endregion
private GameRound? _GameRoundObject = new(); private GameRound? _GameRoundObject = new();
private ObservableCollection<IEnumerable<GameRound>> _GameRoundList = new(); private ObservableCollection<RoundBuilderGroup> _GameRoundList = new();
private ObservableCollection<Participant> _ParticipantList = new(); private ObservableCollection<Participant> _ParticipantList = new();
private readonly IRepository<GameRound>? _Repository; private readonly IRepository<GameRound>? _roundsRepo;
private readonly IRepository<GamePoint> _pointsRepo; private readonly IRepository<GamePoint> _pointsRepo;
private readonly IMethodSharingService<Participant> _sharingService; private readonly IMethodSharingService<Participant> _sharingService;
private readonly ICombinedRepository _combined; private readonly ICombinedRepository _combined;
@ -76,7 +76,7 @@ public class RoundStartingViewModel : ViewModelBase
GameStatus = GamePointStatus.New, GameStatus = GamePointStatus.New,
GameRoundFinished = null GameRoundFinished = null
}; };
var gameRoundId = _Repository?.Save(GameRound).GetAwaiter().GetResult(); var gameRoundId = _roundsRepo?.Save(GameRound).GetAwaiter().GetResult();
if (gameRoundId != null && gameRoundId != -1) if (gameRoundId != null && gameRoundId != -1)
{ {
GameRound.GameRoundId = gameRoundId.Value; GameRound.GameRoundId = gameRoundId.Value;
@ -122,7 +122,7 @@ public class RoundStartingViewModel : ViewModelBase
} }
} }
public ObservableCollection<IEnumerable<GameRound>> GameRoundList public ObservableCollection<RoundBuilderGroup> GameRoundList
{ {
get { return _GameRoundList; } get { return _GameRoundList; }
set set
@ -143,33 +143,36 @@ public class RoundStartingViewModel : ViewModelBase
} }
#region Get Method #region Get Method
public ObservableCollection<GameRound> Get() public ObservableCollection<RoundBuilderGroup> Get()
{ {
//if (_Repository != null)
if (_combined != null) if (_combined != null)
{ {
//var gameRoundsTask = _Repository.Get();
//var gameRounds = gameRoundsTask is Task<IEnumerable<GameRound>> task
// ? task.GetAwaiter().GetResult()
// : (IEnumerable<GameRound>)gameRoundsTask;
var GameRoundSummary = _combined.roundBuilderElements(); var GameRoundSummary = _combined.roundBuilderElements();
var groupedRounds = GameRoundSummary var groupedRounds = GameRoundSummary
.GroupBy(r => r.GameRoundId) .GroupBy(r => r.GameRoundId)
.Select(g => g.ToList()) .Select(g => new RoundBuilderGroup
.ToList(); {
GameRoundId = g.Key,
//OBS ! Här måste jag skapa en ny lista varje gång för att UI ska uppdateras korrekt GameRoundStartDate = g.First().GameRoundStartDate,
Status = g.First().Status,
Elements = g.Select(p => new RoundBuilderElement
{
ParticipantId = p.ParticipantId,
ParticipantName = p.ParticipantName,
GamePointId = p.GamePointId,
GameRoundRegNr = p.GameRoundRegNr,
GameRegPoints = p.GameRegPoints,
GameRoundId = p.GameRoundId,
GameRoundStartDate = p.GameRoundStartDate
}).ToList()
})
.ToList();
//foreach (var gameRound in gameRounds)
//{ GameRoundList = new ObservableCollection<RoundBuilderGroup>(groupedRounds);
// if (!_GameRoundList.Any(p => p.GameRoundId == gameRound.GameRoundId))
// {
// GameRoundList.Add(gameRound);
// }
//}
} }
return GameRoundList; return GameRoundList;
} }
@ -187,7 +190,7 @@ public class RoundStartingViewModel : ViewModelBase
{ {
try try
{ {
GameRoundObject = _Repository?.Get(id).GetAwaiter().GetResult(); GameRoundObject = _roundsRepo?.Get(id).GetAwaiter().GetResult();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -198,11 +201,11 @@ public class RoundStartingViewModel : ViewModelBase
} }
public virtual bool Save() public virtual bool Save()
{ {
if (_Repository == null || GameRoundObject == null) if (_roundsRepo == null || GameRoundObject == null)
{ {
return false; return false;
} }
var tmpTask = _Repository.Save(GameRoundObject); var tmpTask = _roundsRepo.Save(GameRoundObject);
bool tmp = tmpTask.GetAwaiter().GetResult() != -1; bool tmp = tmpTask.GetAwaiter().GetResult() != -1;
if (tmp) if (tmp)
{ {
@ -219,10 +222,20 @@ public class RoundStartingViewModel : ViewModelBase
{ {
_pointsRepo.DeleteById(element.GamePointId); _pointsRepo.DeleteById(element.GamePointId);
} }
_Repository?.DeleteById(GameRoundObject?.GameRoundId ?? 0); _roundsRepo?.DeleteById(GameRoundObject?.GameRoundId ?? 0);
RoundElements.Clear(); RoundElements.Clear();
} }
public void RoundSelected(RoundBuilderElement element)
{
Debug.WriteLine($"Du valde raden med Runda {element.GameRoundId} och spelare: {element.ParticipantName}");
}
public void SelectNewlyAddedParticipant(RoundBuilderElement roundBuilder)
{
Debug.WriteLine($"Du valde raden med Runda {roundBuilder.GameRoundId} och spelare: {roundBuilder.ParticipantName}");
}
#endregion #endregion
} }

View File

@ -21,6 +21,10 @@
Title="Starta Ny Runda" Title="Starta Ny Runda"
ContentTemplate="{DataTemplate views:RoundStartingView}" ContentTemplate="{DataTemplate views:RoundStartingView}"
Route="RoundStartingView" /> Route="RoundStartingView" />
<ShellContent
Title="Påbörja eller fortsätt Runda"
ContentTemplate="{DataTemplate views:RoundRunningView}"
Route="RoundRunningView" />
</TabBar> </TabBar>
</Shell> </Shell>

View File

@ -0,0 +1,31 @@
using Common.Library;
using GreadyPoang.DataLayer;
using GreadyPoang.EntityLayer;
using GreadyPoang.ViewModelLayer;
using System.Windows.Input;
namespace GreadyPoang.CommandClasses;
public class RoundRunningViewModelCommands : RoundRunningViewModel
{
public RoundRunningViewModelCommands() : base()
{
}
public RoundRunningViewModelCommands(
IRepository<GameRound> roundsRepo,
IRepository<GamePoint> pointsRepo,
IMethodSharingService<Participant> sharingService,
ICombinedRepository combined) : base(roundsRepo, pointsRepo, sharingService, combined)
{
}
#region Commands
public ICommand SaveCommand { get; private set; }
public ICommand EditCommand { get; private set; }
public ICommand RensaCommand { get; private set; }
public ICommand ElementTappedCommand { get; private set; }
public ICommand ParticipantTappedCommand { get; private set; }
#endregion
}

View File

@ -13,10 +13,10 @@ public class RoundStartingViewModelCommands : RoundStartingViewModel
} }
public RoundStartingViewModelCommands( public RoundStartingViewModelCommands(
IRepository<GameRound> repo, IRepository<GameRound> roundsRepo,
IRepository<GamePoint> pointsRepo, IRepository<GamePoint> pointsRepo,
IMethodSharingService<Participant> sharingService, IMethodSharingService<Participant> sharingService,
ICombinedRepository combined) : base(repo, pointsRepo, sharingService, combined) ICombinedRepository combined) : base(roundsRepo, pointsRepo, sharingService, combined)
{ {
} }
@ -41,6 +41,8 @@ public class RoundStartingViewModelCommands : RoundStartingViewModel
public ICommand SaveCommand { get; private set; } public ICommand SaveCommand { get; private set; }
public ICommand EditCommand { get; private set; } public ICommand EditCommand { get; private set; }
public ICommand RensaCommand { get; private set; } public ICommand RensaCommand { get; private set; }
public ICommand ElementTappedCommand { get; private set; }
public ICommand ParticipantTappedCommand { get; private set; }
#endregion #endregion
#region Init Method #region Init Method
@ -50,6 +52,9 @@ public class RoundStartingViewModelCommands : RoundStartingViewModel
SaveCommand = new Command(async () => SaveAsync(), () => IsSaveCommandEnabled); SaveCommand = new Command(async () => SaveAsync(), () => IsSaveCommandEnabled);
EditCommand = new Command<int>(async (id) => await EditAsync(id), (id) => id > 0); EditCommand = new Command<int>(async (id) => await EditAsync(id), (id) => id > 0);
RensaCommand = new Command(async () => RensaAsync()); RensaCommand = new Command(async () => RensaAsync());
ParticipantTappedCommand = new Command<RoundBuilderElement>(async (selectedParticipant) => SelectNewlyAddedParticipant(selectedParticipant));
ElementTappedCommand = new Command<RoundBuilderElement>((selectedElement) => RoundSelected(selectedElement));
} }
private async Task RensaAsync() private async Task RensaAsync()
@ -75,4 +80,21 @@ public class RoundStartingViewModelCommands : RoundStartingViewModel
return ret; return ret;
} }
public async Task<bool> RoundSelected(RoundBuilderElement element)
{
bool goneOk = false;
base.RoundSelected(element);
goneOk = true;
return goneOk;
}
public async Task<bool> SelectNewlyAddedParticipant(RoundBuilderElement roundBuilder)
{
bool goneOk = false;
base.SelectNewlyAddedParticipant(roundBuilder);
goneOk = true;
return goneOk;
}
} }

View File

@ -88,6 +88,9 @@
<MauiXaml Update="Views\ParticipantListView.xaml"> <MauiXaml Update="Views\ParticipantListView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Views\RoundRunningView.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Views\RoundStartingView.xaml"> <MauiXaml Update="Views\RoundStartingView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>

View File

@ -12,5 +12,14 @@
ViewDescription="Välkommen till Gready"> ViewDescription="Välkommen till Gready">
</partial:HeaderView> </partial:HeaderView>
<Image Source="snurrtarning.gif"
IsAnimationPlaying="True"
HorizontalOptions="Center"
VerticalOptions="Center"
Aspect="AspectFit"
Grid.Row="1"
Grid.Column="0"
HeightRequest="250"
Margin="10"/>
</Grid> </Grid>
</ContentPage> </ContentPage>

View File

@ -45,6 +45,9 @@ public static class MauiProgram
builder.Services.AddScoped<RoundStartingViewModelCommands>(); builder.Services.AddScoped<RoundStartingViewModelCommands>();
builder.Services.AddScoped<RoundStartingView>(); builder.Services.AddScoped<RoundStartingView>();
builder.Services.AddScoped<RoundRunningViewModelCommands>();
builder.Services.AddScoped<RoundRunningView>();
builder.Services.AddScoped<IRepository<GamePoint>, GamePointRepository>(); builder.Services.AddScoped<IRepository<GamePoint>, GamePointRepository>();

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,49 @@
<?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:partial="clr-namespace:GreadyPoang.ViewsPartial"
xmlns:model="clr-namespace:GreadyPoang.EntityLayer;assembly=GreadyPoang.EntityLayer"
xmlns:vm ="clr-namespace:GreadyPoang.ViewModelLayer;assembly=GreadyPoang.ViewModelLayer"
x:Class="GreadyPoang.Views.RoundRunningView"
Title="RoundRunningView"
x:DataType="vm:RoundRunningViewModel">
<Border Style="{StaticResource Border.Page}" StrokeThickness="4">
<Grid Style="{StaticResource Grid.Page}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<partial:HeaderView Grid.Row="0"
Grid.ColumnSpan="2"
ViewTitle="Starta eller fortsätt en registrerad Runda"
ViewDescription="Deltagarna visas först!" />
<CollectionView Grid.Row="1"
ItemsSource="{Binding Participants}"
ItemsLayout="HorizontalList"
Margin="5"
Padding="3">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:RoundBuilderElement">
<Border BorderColor="Gray" Padding="10" Margin="5">
<Border.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={RelativeSource AncestorType={x:Type ContentPage}}, Path=BindingContext.ParticipantTappedCommand}"
CommandParameter="{Binding .}" />
</Border.GestureRecognizers>
<VerticalStackLayout>
<Label Text="{Binding ParticipantName}" FontAttributes="Bold" />
<Label Text="{Binding GameRegPoints, StringFormat='Poäng: {0}'}" />
<Label Text="{Binding Status}" />
<Label Text="{Binding GameRoundStartDate, StringFormat='Start: {0:yyyy-MM-dd}'}" />
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</Border>
</ContentPage>

View File

@ -0,0 +1,20 @@
using GreadyPoang.CommandClasses;
namespace GreadyPoang.Views;
public partial class RoundRunningView : ContentPage
{
public RoundRunningView(RoundRunningViewModelCommands viewModel)
{
InitializeComponent();
ViewModel = viewModel;
}
protected override void OnAppearing()
{
base.OnAppearing();
BindingContext = ViewModel;
}
public RoundRunningViewModelCommands ViewModel { get; set; }
public int GameRoundId { get; set; }
}

View File

@ -39,6 +39,7 @@
<CollectionView <CollectionView
ItemsSource="{Binding RoundElements}" ItemsSource="{Binding RoundElements}"
ItemsLayout="HorizontalList" ItemsLayout="HorizontalList"
x:Name="ParticipantList"
SelectionMode="None"> SelectionMode="None">
<CollectionView.ItemTemplate> <CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:RoundBuilderElement"> <DataTemplate x:DataType="model:RoundBuilderElement">
@ -54,7 +55,7 @@
StrokeShape="RoundRectangle 10"> StrokeShape="RoundRectangle 10">
<Border.GestureRecognizers> <Border.GestureRecognizers>
<TapGestureRecognizer <TapGestureRecognizer
Command="{Binding BindingContext.ParticipantTappedCommand, Source={x:Reference Name=GameRoundStartingPage}}" Command="{Binding BindingContext.ParticipantTappedCommand, Source={x:Reference Name=ParticipantList}}"
CommandParameter="{Binding .}" /> CommandParameter="{Binding .}" />
</Border.GestureRecognizers> </Border.GestureRecognizers>
<Border.Triggers> <Border.Triggers>
@ -106,53 +107,64 @@
</HorizontalStackLayout> </HorizontalStackLayout>
</Border> </Border>
<Border Grid.Row="2" Stroke="Gold" BackgroundColor="Ivory" StrokeThickness="2" Padding="5"> <Border Grid.Row="2" Stroke="Gold" BackgroundColor="Ivory" StrokeThickness="2" Padding="5">
<CollectionView <CollectionView ItemsSource="{Binding GameRoundList}" x:Name="OuterList">
ItemsSource="{Binding GameRoundList}"
ItemsLayout="VerticalList"
SelectionMode="Single">
<CollectionView.ItemTemplate> <CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:GameRound"> <DataTemplate x:DataType="model:RoundBuilderGroup">
<Border <VerticalStackLayout Padding="10">
Padding="2" <!-- Gruppens rubrik -->
Margin="5" <HorizontalStackLayout>
WidthRequest="150" <Label Text="{Binding GameRoundId, StringFormat='Runda: {0}'}" FontAttributes="Bold" FontSize="18" />
HeightRequest="100" <Label Text="{Binding GameRoundStartDate, StringFormat='Startdatum: {0}'}" FontAttributes="Bold" FontSize="18" />
Stroke="LightGray" <Label Text="{Binding Status, StringFormat='Status: {0}'}" FontAttributes="Bold" FontSize="18" />
StrokeThickness="1" </HorizontalStackLayout>
x:Name="RoundElementBorderList" <!-- Horisontell lista med deltagare -->
StrokeShape="RoundRectangle 10"> <CollectionView ItemsSource="{Binding Elements}"
<!--BackgroundColor="{Binding Status, Converter={StaticResource StatusToColorConverter}}"--> ItemsLayout="HorizontalList"
<!--<Border.GestureRecognizers> x:Name="InnerList"
<TapGestureRecognizer Margin="0,10,0,10"
Command="{Binding BindingContext.ParticipantTappedCommand, Source={x:Reference Name=GameRoundStartingPage}}" ItemSizingStrategy="MeasureAllItems">
CommandParameter="{Binding .}" /> <CollectionView.ItemTemplate>
</Border.GestureRecognizers>--> <DataTemplate x:DataType="model:RoundBuilderElement">
<!--<Border.Triggers> <Border
<DataTrigger TargetType="Border" Binding="{Binding Status}" Value="New"> Stroke="Gray"
<Setter Property="BackgroundColor" Value="LightGreen" /> Padding="5"
</DataTrigger> Margin="5,0"
<DataTrigger TargetType="Border" Binding="{Binding Status}" Value="InProgress"> BackgroundColor="{Binding Status, Converter={StaticResource StatusToColorConverter}}" >
<Setter Property="BackgroundColor" Value="LightYellow" /> <Border.Triggers>
</DataTrigger> <DataTrigger TargetType="Border" Binding="{Binding Status}" Value="New">
<DataTrigger TargetType="Border" Binding="{Binding Status}" Value="Completed"> <Setter Property="BackgroundColor" Value="LightGreen" />
<Setter Property="BackgroundColor" Value="DarkGreen" /> </DataTrigger>
</DataTrigger> <DataTrigger TargetType="Border" Binding="{Binding Status}" Value="InProgress">
<DataTrigger TargetType="Border" Binding="{Binding Status}" Value="Cancelled"> <Setter Property="BackgroundColor" Value="LightYellow" />
<Setter Property="BackgroundColor" Value="LightCoral" /> </DataTrigger>
</DataTrigger> <DataTrigger TargetType="Border" Binding="{Binding Status}" Value="Completed">
</Border.Triggers>--> <Setter Property="BackgroundColor" Value="DarkGreen" />
<Border Margin="1" Padding="2" StrokeThickness="3" > </DataTrigger>
<VerticalStackLayout> <DataTrigger TargetType="Border" Binding="{Binding Status}" Value="Cancelled">
<Label Text="{Binding GameRoundId}" FontAttributes="Bold" FontSize="14" TextColor="Black"/> <Setter Property="BackgroundColor" Value="LightCoral" />
<Label Text="{Binding GameRoundStartDateString}" FontAttributes="Bold" FontSize="14" TextColor="Black"/> </DataTrigger>
<Label Text="{Binding GameRoundFinished}" FontSize="14" TextColor="White" /> </Border.Triggers>
</VerticalStackLayout> <Border.GestureRecognizers>
</Border> <TapGestureRecognizer
</Border> Command="{Binding Path=BindingContext.ElementTappedCommand,Source={x:Reference OuterList}}"
CommandParameter="{Binding .}" />
</Border.GestureRecognizers>
<VerticalStackLayout>
<Label Text="{Binding ParticipantName}" FontAttributes="Bold" />
<Label Text="{Binding GameRegPoints, StringFormat='Poäng: {0}'}" />
<Label Text="{Binding GameRoundRegNr, StringFormat='RegNr: {0}'}" />
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</DataTemplate> </DataTemplate>
</CollectionView.ItemTemplate> </CollectionView.ItemTemplate>
</CollectionView> </CollectionView>
</Border> </Border>
</Grid> </Grid>
</Border> </Border>

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
zBilder/snurrtarning.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
zBilder/unnamed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB