Nu fungerar Popupen och den går att stänga

This commit is contained in:
2025-10-17 11:52:01 +02:00
parent 21eb0d5498
commit bb8f4bd5ed
12 changed files with 272 additions and 23 deletions

View File

@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="12.2.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,39 @@
using CommunityToolkit.Maui.Alerts;
using CommunityToolkit.Mvvm.ComponentModel;
namespace GreadyPoang.Core;
public partial class BaseViewModel : ObservableObject
{
[ObservableProperty]
private bool isBusy;
protected async Task RunAsyncCommand(Func<Task> action, string loadingMessage = null, string errorMessage = "Ett fel inträffade")
{
if (IsBusy) return;
try
{
IsBusy = true;
if (!string.IsNullOrWhiteSpace(loadingMessage))
await Snackbar.Make(
message: loadingMessage,
duration: TimeSpan.FromSeconds(2),
action: null).Show();
await action.Invoke();
}
catch (Exception ex)
{
await Snackbar.Make(
message: $"{errorMessage}: {ex.Message}",
duration: TimeSpan.FromSeconds(3),
action: () => Console.WriteLine("Åtgärd vald")).Show();
}
finally
{
IsBusy = false;
}
}
}

View File

@ -0,0 +1,11 @@
namespace GreadyPoang.Services;
public class PopupEventHub : IPopupEventHub
{
public event EventHandler? InfoPopupCloseRequested;
public void RaiseInfoPopupClose()
{
InfoPopupCloseRequested?.Invoke(this, EventArgs.Empty);
}
}

View File

@ -0,0 +1,8 @@
namespace GreadyPoang.Services;
public interface IPopupEventHub
{
event EventHandler? InfoPopupCloseRequested;
void RaiseInfoPopupClose();
}

View File

@ -0,0 +1,50 @@
using CommunityToolkit.Maui;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GreadyPoang.Services;
namespace GreadyPoang.ViewModelLayer;
public partial class InfoPopupViewModel : ObservableObject, IQueryAttributable
{
private readonly IPopupService _popupService;
private readonly IPopupEventHub _popupEvent;
public event EventHandler ClosePopupRequested;
[ObservableProperty]
private string title;
[ObservableProperty]
private string message;
[ObservableProperty]
private string name;
public InfoPopupViewModel(IPopupService popupService, IPopupEventHub popupEvent)
{
_popupService = popupService;
_popupEvent = popupEvent;
}
[RelayCommand]
private async Task Cancel()
{
//await _popupService.ClosePopupAsync(Shell.Current);
_popupEvent.RaiseInfoPopupClose();
}
[RelayCommand(CanExecute = nameof(CanSave))]
void OnSave()
{
}
bool CanSave() => string.IsNullOrWhiteSpace(Name) is false;
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Title = (string)query[nameof(InfoPopupViewModel.Title)];
Message = (string)query[nameof(InfoPopupViewModel.Message)];
Name = (string)query[nameof(InfoPopupViewModel.Name)];
}
}

View File

@ -1,13 +1,16 @@
using Common.Library; using Common.Library;
using CommunityToolkit.Maui;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using GreadyPoang.Core;
using GreadyPoang.EntityLayer; using GreadyPoang.EntityLayer;
using GreadyPoang.Services;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
namespace GreadyPoang.ViewModelLayer; namespace GreadyPoang.ViewModelLayer;
public partial class ParticipantViewModel : ObservableObject public partial class ParticipantViewModel : BaseViewModel
{ {
#region Constructors #region Constructors
public ParticipantViewModel() : base() public ParticipantViewModel() : base()
@ -15,15 +18,28 @@ public partial class ParticipantViewModel : ObservableObject
} }
public ParticipantViewModel(IRepository<Participant> repo, IMethodSharingService<Participant> sharingService) : base() public ParticipantViewModel(
IRepository<Participant> repo,
IMethodSharingService<Participant> sharingService,
IPopupService popupService,
IPopupEventHub popupEvent
//,
//InfoPopupViewModel infoPopupViewModel
) : base()
{ {
_Repository = repo; _Repository = repo;
_sharingService = sharingService; _sharingService = sharingService;
_popupService = popupService;
_popupEvent = popupEvent;
//_infoPopupViewModel = infoPopupViewModel;
ParticipantObject = new Participant(); ParticipantObject = new Participant();
ParticipantList = new ObservableCollection<Participant>(); ParticipantList = new ObservableCollection<Participant>();
IsSaveCommandEnabled = true; IsSaveCommandEnabled = true;
_popupEvent.InfoPopupCloseRequested += infoPopupViewModel_ClosePopupRequested;
PopupVisad = false;
} }
#endregion #endregion
#region Private Variables #region Private Variables
@ -33,17 +49,40 @@ public partial class ParticipantViewModel : ObservableObject
private ObservableCollection<Participant> participantList; private ObservableCollection<Participant> participantList;
private readonly IRepository<Participant>? _Repository; private readonly IRepository<Participant>? _Repository;
private readonly IMethodSharingService<Participant> _sharingService; private readonly IMethodSharingService<Participant> _sharingService;
private readonly IPopupService _popupService;
private readonly IPopupEventHub _popupEvent;
private readonly InfoPopupViewModel _infoPopupViewModel;
#endregion #endregion
[ObservableProperty] [ObservableProperty]
private bool isSaveCommandEnabled; private bool isSaveCommandEnabled;
public bool PopupVisad { get; set; }
#region Get Method #region Get Method
public ObservableCollection<Participant> Get() public ObservableCollection<Participant> Get()
{ {
ParticipantList = _sharingService.Get(); ParticipantList = _sharingService.Get();
if (!PopupVisad)
{
var queryAttributes = new Dictionary<string, object>
{
[nameof(InfoPopupViewModel.Title)] = "Deltagar bildens infopopup",
[nameof(InfoPopupViewModel.Message)] = "Deltagare laddade",
[nameof(InfoPopupViewModel.Name)] = "Urban",
};
_popupService.ShowPopup<InfoPopupViewModel>(
Shell.Current,
options: PopupOptions.Empty,
shellParameters: queryAttributes);
}
return ParticipantList; return ParticipantList;
} }
@ -68,25 +107,47 @@ public partial class ParticipantViewModel : ObservableObject
#endregion #endregion
[RelayCommand(CanExecute = nameof(IsSaveCommandEnabled))] [RelayCommand(CanExecute = nameof(IsSaveCommandEnabled))]
private async Task<bool> Save() private async Task Save()
{ {
if (_Repository == null || ParticipantObject == null) await RunAsyncCommand(async () =>
{ {
return false; if (_Repository == null || ParticipantObject == null)
} {
var tmpTask = _Repository.Save(ParticipantObject); return;
int tmp = tmpTask.GetAwaiter().GetResult(); }
if (tmp != -1) await Task.Delay(3600); // Simulerar en fördröjning för att visa laddningsindikatorn
{ var tmpTask = _Repository.Save(ParticipantObject);
ParticipantObject = new Participant(); int tmp = await tmpTask;
this.Get(); if (tmp != -1)
await Shell.Current.GoToAsync(".."); {
} ParticipantObject = new Participant();
return tmp != -1; this.Get();
await Shell.Current.GoToAsync("..");
}
}, loadingMessage: "Sparar deltagare...", errorMessage: "Fel vid sparande av deltagare");
} }
//[RelayCommand(CanExecute = nameof(IsSaveCommandEnabled))]
//private async Task<bool> Save()
//{
// if (_Repository == null || ParticipantObject == null)
// {
// return false;
// }
// var tmpTask = _Repository.Save(ParticipantObject);
// int tmp = tmpTask.GetAwaiter().GetResult();
// if (tmp != -1)
// {
// ParticipantObject = new Participant();
// this.Get();
// await Shell.Current.GoToAsync("..");
// }
// return tmp != -1;
//}
[RelayCommand] [RelayCommand]
private void DeleteAsync(Participant pp) private void DeleteAsync(Participant pp)
{ {
@ -99,4 +160,26 @@ public partial class ParticipantViewModel : ObservableObject
this.Get(); this.Get();
Shell.Current.GoToAsync(".."); Shell.Current.GoToAsync("..");
} }
[RelayCommand]
private async Task LoadDataAsync()
{
await RunAsyncCommand(async () =>
{
await Task.Delay(1500); // Simulerar laddning
Console.WriteLine("Data laddad!");
}, loadingMessage: "Laddar data...");
}
//private void ClosePopup()
//{
// _popupService.ClosePopupAsync(Shell.Current).GetAwaiter().GetResult();
//}
private async void infoPopupViewModel_ClosePopupRequested(object? sender, EventArgs e)
{
PopupVisad = true;
await _popupService.ClosePopupAsync(Shell.Current);
}
} }

View File

@ -60,6 +60,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="12.2.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.100" /> <PackageReference Include="Microsoft.Maui.Controls" Version="9.0.100" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
@ -76,6 +77,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Popups\InfoPopup.xaml.cs">
<DependentUpon>InfoPopup.xaml</DependentUpon>
</Compile>
<Compile Update="Views\ParticipantListView.xaml.cs"> <Compile Update="Views\ParticipantListView.xaml.cs">
<DependentUpon>ParticipantListView.xaml</DependentUpon> <DependentUpon>ParticipantListView.xaml</DependentUpon>
</Compile> </Compile>
@ -88,6 +92,9 @@
<MauiXaml Update="ViewsPartial\HeaderView.xaml"> <MauiXaml Update="ViewsPartial\HeaderView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Popups\InfoPopup.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Views\ParticipantListView.xaml"> <MauiXaml Update="Views\ParticipantListView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>

View File

@ -1,7 +1,9 @@
using Common.Library; using Common.Library;
using CommunityToolkit.Maui;
using GreadyPoang.DataLayer; using GreadyPoang.DataLayer;
using GreadyPoang.DataLayer.Database; using GreadyPoang.DataLayer.Database;
using GreadyPoang.EntityLayer; using GreadyPoang.EntityLayer;
using GreadyPoang.Popups;
using GreadyPoang.Services; using GreadyPoang.Services;
using GreadyPoang.ViewModelLayer; using GreadyPoang.ViewModelLayer;
using GreadyPoang.Views; using GreadyPoang.Views;
@ -18,6 +20,8 @@ public static class MauiProgram
builder builder
.UseMauiApp<App>() .UseMauiApp<App>()
.UseMauiCommunityToolkit(options =>
options.SetShouldEnableSnackbarOnWindows(true))
.ConfigureFonts(fonts => .ConfigureFonts(fonts =>
{ {
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
@ -52,6 +56,8 @@ public static class MauiProgram
builder.Services.AddScoped<IMethodSharingService<Participant>, MethodSharingService>(); builder.Services.AddScoped<IMethodSharingService<Participant>, MethodSharingService>();
builder.Services.AddScoped<ICombinedRepository, CombinedRepository>(); builder.Services.AddScoped<ICombinedRepository, CombinedRepository>();
builder.Services.AddSingleton<IObjectMessageService, ObjectMessageService>(); builder.Services.AddSingleton<IObjectMessageService, ObjectMessageService>();
builder.Services.AddTransientPopup<InfoPopup, InfoPopupViewModel>();
builder.Services.AddSingleton<IPopupEventHub, PopupEventHub>();
#if DEBUG #if DEBUG
builder.Logging.AddDebug(); builder.Logging.AddDebug();

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:GreadyPoang.ViewModelLayer;assembly=GreadyPoang.ViewModelLayer"
x:Class="GreadyPoang.Popups.InfoPopup"
HorizontalOptions="Center"
VerticalOptions="Center"
Padding="0"
x:DataType="viewModels:InfoPopupViewModel"
BackgroundColor="Transparent">
<VerticalStackLayout BackgroundColor="Aquamarine" Padding="5" Margin="0">
<Label TextColor="BlueViolet" Text="{Binding Title}" Style="{StaticResource Headline}" />
<Label Text="{Binding Message}" Style="{StaticResource SubHeadline}"/>
<!--<Label Text="What is your name?" />
<Entry Text="{Binding Name}" />
<Button Text="Save" Command="{Binding SaveCommand}" />-->
<Button Margin="10" Text="Cancel" Command="{Binding CancelCommand}" Style="{StaticResource HoverButtonBlueStyle}" />
</VerticalStackLayout>
</ContentView>

View File

@ -0,0 +1,13 @@
using GreadyPoang.ViewModelLayer;
namespace GreadyPoang.Popups;
public partial class InfoPopup : ContentView
{
public InfoPopup(InfoPopupViewModel ipViewModel)
{
InitializeComponent();
BindingContext = ipViewModel;
}
}

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:partial="clr-namespace:GreadyPoang.ViewsPartial" xmlns:partial="clr-namespace:GreadyPoang.ViewsPartial"
xmlns:vm="clr-namespace:GreadyPoang.ViewModelLayer;assembly=GreadyPoang.ViewModelLayer" xmlns:vm="clr-namespace:GreadyPoang.ViewModelLayer;assembly=GreadyPoang.ViewModelLayer"
xmlns:model="clr-namespace:GreadyPoang.EntityLayer;assembly=GreadyPoang.EntityLayer" xmlns:model="clr-namespace:GreadyPoang.EntityLayer;assembly=GreadyPoang.EntityLayer"
@ -10,10 +11,10 @@
Title="Deltagar Lista"> Title="Deltagar Lista">
<!--xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"--> <!--xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"-->
<Border Style="{StaticResource Border.Page}" StrokeThickness="4"> <Border Style="{StaticResource Border.Page}" StrokeThickness="4">
<Grid Style="{StaticResource Grid.Page}"> <Grid Style="{StaticResource Grid.Page}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@ -22,7 +23,12 @@
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
ViewTitle="Deltagare" ViewTitle="Deltagare"
ViewDescription="Lägg till deltagare här" /> ViewDescription="Lägg till deltagare här" />
<Border Stroke="Gold" StrokeThickness="2" BackgroundColor="LemonChiffon" Grid.Row="1"> <ActivityIndicator Grid.Row="1" IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
Color="DarkBlue"
HeightRequest="40" />
<Border Stroke="Gold" StrokeThickness="2" BackgroundColor="LemonChiffon" Grid.Row="2">
<VerticalStackLayout Spacing="4" > <VerticalStackLayout Spacing="4" >
<!--<Label Style="{StaticResource SubHeadline}" <!--<Label Style="{StaticResource SubHeadline}"
Text="Deltagare " Text="Deltagare "
@ -60,7 +66,7 @@
</Grid> </Grid>
</VerticalStackLayout> </VerticalStackLayout>
</Border> </Border>
<Border Grid.Row="2" Stroke="Gold" BackgroundColor="Ivory" StrokeThickness="2" Padding="5"> <Border Grid.Row="3" Stroke="Gold" BackgroundColor="Ivory" StrokeThickness="2" Padding="5">
<CollectionView <CollectionView
x:Name="participants" x:Name="participants"
SelectionMode="Single" SelectionMode="Single"
@ -92,6 +98,7 @@
</CollectionView.ItemTemplate> </CollectionView.ItemTemplate>
</CollectionView> </CollectionView>
</Border> </Border>
</Grid> </Grid>
</Border> </Border>
</ContentPage> </ContentPage>

View File

@ -20,8 +20,11 @@ public partial class ParticipantListView : ContentPage
ViewModel.Get(); ViewModel.Get();
} }
protected override void OnDisappearing()
{
base.OnDisappearing();
ViewModel.PopupVisad = false;
}
} }