diff --git a/.gitignore b/.gitignore index a0e1d32..24b618c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ */bin/Debug/* /SewerStammGen/bin/Release/* /Shared/bin/Release/* +*/bin/* diff --git a/SewerStammGen.EntityFramework/Migrations/20230330100444_AddedNullValue.Designer.cs b/SewerStammGen.EntityFramework/Migrations/20230330100444_AddedNullValue.Designer.cs new file mode 100644 index 0000000..ee19a3d --- /dev/null +++ b/SewerStammGen.EntityFramework/Migrations/20230330100444_AddedNullValue.Designer.cs @@ -0,0 +1,220 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using SewerStammGen.EntityFramework; + +#nullable disable + +namespace SewerStammGen.EntityFramework.Migrations +{ + [DbContext(typeof(SewerStammGenDbContext))] + [Migration("20230330100444_AddedNullValue")] + partial class AddedNullValue + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Shared.Domain.Auftraggeber", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Ansprechpartner") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Ort") + .HasColumnType("text"); + + b.Property("Postleitzahl") + .HasColumnType("text"); + + b.Property("Strasse") + .HasColumnType("text"); + + b.Property("Telefonnummer") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Auftraggebers"); + }); + + modelBuilder.Entity("Shared.Domain.Kanal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DN") + .HasColumnType("integer"); + + b.Property("EndSchachtId") + .HasColumnType("integer"); + + b.Property("Entwaesserung") + .HasColumnType("integer"); + + b.Property("Haltungslaenge") + .HasColumnType("numeric"); + + b.Property("Material") + .HasColumnType("text"); + + b.Property("Objektbezeichnung") + .HasColumnType("text"); + + b.Property("ProjektId") + .HasColumnType("integer"); + + b.Property("StartSchachtId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EndSchachtId"); + + b.HasIndex("ProjektId"); + + b.HasIndex("StartSchachtId"); + + b.ToTable("Kanaele"); + }); + + modelBuilder.Entity("Shared.Domain.Projekt", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuftraggeberId") + .HasColumnType("integer"); + + b.Property("Erstelldatum") + .HasColumnType("text"); + + b.Property("ExportType") + .HasColumnType("integer"); + + b.Property("Kodierungssystem") + .HasColumnType("integer"); + + b.Property("Ort") + .HasColumnType("text"); + + b.Property("Projektname") + .HasColumnType("text"); + + b.Property("Strasse") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AuftraggeberId"); + + b.ToTable("Projekte"); + }); + + modelBuilder.Entity("Shared.Domain.Schacht", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DeckelHoehe") + .HasColumnType("decimal(18,4)"); + + b.Property("Entwaesserung") + .HasColumnType("integer"); + + b.Property("HochWert") + .HasColumnType("decimal(18,4)"); + + b.Property("Objektbezeichnung") + .HasColumnType("text"); + + b.Property("ProjektId") + .HasColumnType("integer"); + + b.Property("RechtsWert") + .HasColumnType("decimal(18,4)"); + + b.Property("SohlHoehe") + .HasColumnType("decimal(18,4)"); + + b.HasKey("Id"); + + b.HasIndex("ProjektId"); + + b.ToTable("Schaechte"); + }); + + modelBuilder.Entity("Shared.Domain.Kanal", b => + { + b.HasOne("Shared.Domain.Schacht", "EndSchacht") + .WithMany() + .HasForeignKey("EndSchachtId"); + + b.HasOne("Shared.Domain.Projekt", null) + .WithMany("Kanaele") + .HasForeignKey("ProjektId"); + + b.HasOne("Shared.Domain.Schacht", "StartSchacht") + .WithMany() + .HasForeignKey("StartSchachtId"); + + b.Navigation("EndSchacht"); + + b.Navigation("StartSchacht"); + }); + + modelBuilder.Entity("Shared.Domain.Projekt", b => + { + b.HasOne("Shared.Domain.Auftraggeber", "Auftraggeber") + .WithMany() + .HasForeignKey("AuftraggeberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Auftraggeber"); + }); + + modelBuilder.Entity("Shared.Domain.Schacht", b => + { + b.HasOne("Shared.Domain.Projekt", null) + .WithMany("Schaechte") + .HasForeignKey("ProjektId"); + }); + + modelBuilder.Entity("Shared.Domain.Projekt", b => + { + b.Navigation("Kanaele"); + + b.Navigation("Schaechte"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SewerStammGen.EntityFramework/Migrations/20230330100444_AddedNullValue.cs b/SewerStammGen.EntityFramework/Migrations/20230330100444_AddedNullValue.cs new file mode 100644 index 0000000..bb1f0dd --- /dev/null +++ b/SewerStammGen.EntityFramework/Migrations/20230330100444_AddedNullValue.cs @@ -0,0 +1,252 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace SewerStammGen.EntityFramework.Migrations +{ + /// + public partial class AddedNullValue : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Objektbezeichnung", + table: "Schaechte", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Strasse", + table: "Projekte", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Projektname", + table: "Projekte", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Ort", + table: "Projekte", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Erstelldatum", + table: "Projekte", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Objektbezeichnung", + table: "Kanaele", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Material", + table: "Kanaele", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Telefonnummer", + table: "Auftraggebers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Strasse", + table: "Auftraggebers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Postleitzahl", + table: "Auftraggebers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Ort", + table: "Auftraggebers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Auftraggebers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Ansprechpartner", + table: "Auftraggebers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "text"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Objektbezeichnung", + table: "Schaechte", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Strasse", + table: "Projekte", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Projektname", + table: "Projekte", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Ort", + table: "Projekte", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Erstelldatum", + table: "Projekte", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Objektbezeichnung", + table: "Kanaele", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Material", + table: "Kanaele", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Telefonnummer", + table: "Auftraggebers", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Strasse", + table: "Auftraggebers", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Postleitzahl", + table: "Auftraggebers", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Ort", + table: "Auftraggebers", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Auftraggebers", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Ansprechpartner", + table: "Auftraggebers", + type: "text", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + } + } +} diff --git a/SewerStammGen.EntityFramework/Migrations/SewerStammGenDbContextModelSnapshot.cs b/SewerStammGen.EntityFramework/Migrations/SewerStammGenDbContextModelSnapshot.cs index ed5e0be..f90d818 100644 --- a/SewerStammGen.EntityFramework/Migrations/SewerStammGenDbContextModelSnapshot.cs +++ b/SewerStammGen.EntityFramework/Migrations/SewerStammGenDbContextModelSnapshot.cs @@ -31,27 +31,21 @@ namespace SewerStammGen.EntityFramework.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Ansprechpartner") - .IsRequired() .HasColumnType("text"); b.Property("Name") - .IsRequired() .HasColumnType("text"); b.Property("Ort") - .IsRequired() .HasColumnType("text"); b.Property("Postleitzahl") - .IsRequired() .HasColumnType("text"); b.Property("Strasse") - .IsRequired() .HasColumnType("text"); b.Property("Telefonnummer") - .IsRequired() .HasColumnType("text"); b.HasKey("Id"); @@ -80,11 +74,9 @@ namespace SewerStammGen.EntityFramework.Migrations .HasColumnType("numeric"); b.Property("Material") - .IsRequired() .HasColumnType("text"); b.Property("Objektbezeichnung") - .IsRequired() .HasColumnType("text"); b.Property("ProjektId") @@ -116,7 +108,6 @@ namespace SewerStammGen.EntityFramework.Migrations .HasColumnType("integer"); b.Property("Erstelldatum") - .IsRequired() .HasColumnType("text"); b.Property("ExportType") @@ -126,15 +117,12 @@ namespace SewerStammGen.EntityFramework.Migrations .HasColumnType("integer"); b.Property("Ort") - .IsRequired() .HasColumnType("text"); b.Property("Projektname") - .IsRequired() .HasColumnType("text"); b.Property("Strasse") - .IsRequired() .HasColumnType("text"); b.HasKey("Id"); @@ -162,7 +150,6 @@ namespace SewerStammGen.EntityFramework.Migrations .HasColumnType("decimal(18,4)"); b.Property("Objektbezeichnung") - .IsRequired() .HasColumnType("text"); b.Property("ProjektId") diff --git a/SewerStammGen.EntityFramework/Services/Common/NonQueryDataService.cs b/SewerStammGen.EntityFramework/Services/Common/NonQueryDataService.cs index 06bc73b..857a3b4 100644 --- a/SewerStammGen.EntityFramework/Services/Common/NonQueryDataService.cs +++ b/SewerStammGen.EntityFramework/Services/Common/NonQueryDataService.cs @@ -36,7 +36,8 @@ namespace SewerStammGen.EntityFramework.Services.Common public async Task Delete(int id) { using SewerStammGenDbContext context = _contextFactory.CreateDbContext(); - T entity = await context.Set().FirstOrDefaultAsync((e) => e.Id == id); + T? entity = await context.Set().FirstOrDefaultAsync((e) => e.Id == id); + if (entity == null) return false; context.Set().Remove(entity); await context.SaveChangesAsync(); return true; diff --git a/SewerStammGen/App.xaml.cs b/SewerStammGen/App.xaml.cs index 08d80e0..2f2c9e7 100644 --- a/SewerStammGen/App.xaml.cs +++ b/SewerStammGen/App.xaml.cs @@ -1,5 +1,7 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using SewerStammGen.EntityFramework; using SewerStammGen.HostBuilders; using SewerStammGen.WPF.ViewModel; using System; @@ -40,6 +42,12 @@ namespace SewerStammGen.WPF _host.Start(); + SewerStammGenDbContextFactory contextFactory = _host.Services.GetRequiredService(); + using(SewerStammGenDbContext context = contextFactory.CreateDbContext()) + { + context.Database.Migrate(); + } + MainWindow? window = new MainWindow() { DataContext = _host.Services.GetRequiredService() }; window.Show(); diff --git a/SewerStammGen/Commands/ProjektAddCommand.cs b/SewerStammGen/Commands/ProjektAddCommand.cs new file mode 100644 index 0000000..d951dc8 --- /dev/null +++ b/SewerStammGen/Commands/ProjektAddCommand.cs @@ -0,0 +1,44 @@ +using SewerStammGen.WPF.Interface.Navigator; +using SewerStammGen.WPF.ViewModel.State; +using Shared.Contracts; +using Shared.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.Commands +{ + internal class ProjektAddCommand : AsyncCommandBase + { + private readonly IActualState _actualState; + private readonly IDataService _generic; + private readonly IRenavigator _renavigator; + + public ProjektAddCommand(IDataService generic, IActualState actualState, IRenavigator renavigator) + { + _renavigator = renavigator; + _generic = generic; + _actualState = actualState; + } + + public override async Task ExecuteAsync(object? parameter) + { + Projekt newProjekt = new Projekt() + { + Erstelldatum = "", + Strasse = "", + Ort = "", + Projektname = "", + Auftraggeber = new Auftraggeber(), + Schaechte = new List(), + Kanaele = new List() + }; + //newProjekt = await _generic.Create(newProjekt); + _actualState.SetProjekt(newProjekt); + _renavigator.Renavigate(); + + } + } +} diff --git a/SewerStammGen/Commands/ProjektEditCommand.cs b/SewerStammGen/Commands/ProjektEditCommand.cs new file mode 100644 index 0000000..9c564e8 --- /dev/null +++ b/SewerStammGen/Commands/ProjektEditCommand.cs @@ -0,0 +1,35 @@ +using SewerStammGen.WPF.Interface.Navigator; +using SewerStammGen.WPF.ViewModel; +using SewerStammGen.WPF.ViewModel.State; +using Shared.Contracts; +using Shared.Domain; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.Commands +{ + internal class ProjektEditCommand : AsyncCommandBase + { + private IDataService _dataService; + private IActualState _actualState; + private IRenavigator _renavigator; + private ProjektListViewModel _projektListViewModel; + + + public ProjektEditCommand(IDataService dataService, IActualState actualState, IRenavigator renavigator, ProjektListViewModel projektListViewModel) + { + _dataService = dataService; + _actualState = actualState; + _renavigator = renavigator; + _projektListViewModel = projektListViewModel; + } + + public override async Task ExecuteAsync(object? parameter) + { + + _actualState.SetProjekt(_projektListViewModel.SelectedProjekt); + _renavigator.Renavigate(); + + } + } +} diff --git a/SewerStammGen/Commands/ProjektSelectCommand.cs b/SewerStammGen/Commands/ProjektSelectCommand.cs new file mode 100644 index 0000000..e7a72de --- /dev/null +++ b/SewerStammGen/Commands/ProjektSelectCommand.cs @@ -0,0 +1,26 @@ +using SewerStammGen.WPF.ViewModel; +using SewerStammGen.WPF.ViewModel.State; +using Shared.Domain; +using System; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.Commands +{ + internal class ProjektSelectCommand : AsyncCommandBase + { + private readonly IActualState _actualState; + private readonly ProjektListViewModel _projektListViewModel; + + public ProjektSelectCommand(IActualState actualState, ProjektListViewModel projektListViewModel) + { + _actualState = actualState; + _projektListViewModel = projektListViewModel; + } + + public override async Task ExecuteAsync(object? parameter) + { + if (_projektListViewModel.SelectedProjekt == null) return; + _actualState.SetProjekt(_projektListViewModel.SelectedProjekt); + } + } +} diff --git a/SewerStammGen/HostBuilders/AddDBContextHostBuilderExtensions.cs b/SewerStammGen/HostBuilders/AddDBContextHostBuilderExtensions.cs index 2e02f2f..542ae59 100644 --- a/SewerStammGen/HostBuilders/AddDBContextHostBuilderExtensions.cs +++ b/SewerStammGen/HostBuilders/AddDBContextHostBuilderExtensions.cs @@ -18,24 +18,28 @@ namespace SewerStammGen.HostBuilders { hostBuilder.ConfigureServices((context, services) => { - string connectionString = ""; - Action configureDbContext = null; - string databaseToUse = context.Configuration.GetConnectionString("databaseToUse"); - Trace.WriteLine(databaseToUse); - if (databaseToUse.Equals("default")) + string? connectionString = ""; + Action? configureDbContext = null; + string? databaseToUse = context.Configuration.GetConnectionString("databaseToUse"); + if (databaseToUse != null) { - connectionString = context.Configuration.GetConnectionString("default"); - configureDbContext = o => o.UseNpgsql(connectionString); - } - else if (databaseToUse.Equals("sqlite")) - { - connectionString = context.Configuration.GetConnectionString("sqlite"); - configureDbContext = o => o.UseSqlite(connectionString); + + if (databaseToUse.Equals("default")) + { + connectionString = context.Configuration.GetConnectionString("default"); + configureDbContext = o => o.UseNpgsql(connectionString); + } + else if (databaseToUse.Equals("sqlite")) + { + connectionString = context.Configuration.GetConnectionString("sqlite"); + configureDbContext = o => o.UseSqlite(connectionString); + } + services.AddDbContext(configureDbContext); + services.AddSingleton(new SewerStammGenDbContextFactory(configureDbContext)); } - services.AddDbContext(configureDbContext); - services.AddSingleton(new SewerStammGenDbContextFactory(configureDbContext)); + }); return hostBuilder; } diff --git a/SewerStammGen/HostBuilders/AddServicesHostBuilderExtensions.cs b/SewerStammGen/HostBuilders/AddServicesHostBuilderExtensions.cs index 0c302e3..c0ebc8e 100644 --- a/SewerStammGen/HostBuilders/AddServicesHostBuilderExtensions.cs +++ b/SewerStammGen/HostBuilders/AddServicesHostBuilderExtensions.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Hosting; using SewerStammGen.EntityFramework.Services; using SewerStammGen.WPF.Interface.Navigator; +using SewerStammGen.WPF.ViewModel; using SewerStammGen.WPF.ViewModel.State.Navigation; using Shared.Contracts; using Shared.Domain; @@ -21,7 +22,7 @@ namespace SewerStammGen.HostBuilders host.ConfigureServices(services => { services.AddSingleton(); - + services.AddSingleton>(); services.AddSingleton, GenericDataService>(); }); return host; diff --git a/SewerStammGen/HostBuilders/AddStoresHostBuilderExtensions.cs b/SewerStammGen/HostBuilders/AddStoresHostBuilderExtensions.cs index 6fe3add..5fe5035 100644 --- a/SewerStammGen/HostBuilders/AddStoresHostBuilderExtensions.cs +++ b/SewerStammGen/HostBuilders/AddStoresHostBuilderExtensions.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using SewerStammGen.WPF.ViewModel.State; using System; using System.Collections.Generic; using System.Linq; @@ -13,7 +15,7 @@ namespace SewerStammGen.HostBuilders { hostBuilder.ConfigureServices(services => { - + services.AddSingleton(); }); return hostBuilder; } diff --git a/SewerStammGen/HostBuilders/AddViewModelsHostBuilderExtensions.cs b/SewerStammGen/HostBuilders/AddViewModelsHostBuilderExtensions.cs index e5c06f2..0bc966a 100644 --- a/SewerStammGen/HostBuilders/AddViewModelsHostBuilderExtensions.cs +++ b/SewerStammGen/HostBuilders/AddViewModelsHostBuilderExtensions.cs @@ -1,7 +1,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using SewerStammGen.WPF.Commands; using SewerStammGen.WPF.Interface; using SewerStammGen.WPF.ViewModel; +using SewerStammGen.WPF.ViewModel.State.Navigation; using SewerStammGen.WPF.ViewModel.Factories; using Shared.Contracts; using Shared.Domain; @@ -11,6 +13,7 @@ using System.Linq; using System.Net.Security; using System.Text; using System.Threading.Tasks; +using SewerStammGen.WPF.ViewModel.State; namespace SewerStammGen.HostBuilders { @@ -20,7 +23,12 @@ namespace SewerStammGen.HostBuilders { hostBuilder.ConfigureServices(services => { + services.AddTransient(); + + services.AddSingleton>(); + services.AddSingleton>(); + services.AddSingleton>(services => { return () => new HomeViewModel(); @@ -36,10 +44,21 @@ namespace SewerStammGen.HostBuilders return () => new SewerConnectorViewModel(); }); + services.AddSingleton>(services => + { + return () => new ProjektEditViewModel( + services.GetRequiredService>(), + services.GetRequiredService>(), + services.GetRequiredService() + ); + }); + services.AddSingleton>(services => { return () => new ProjektListViewModel( - services.GetRequiredService>() + services.GetRequiredService>(), + services.GetRequiredService>(), + services.GetRequiredService() ); }); diff --git a/SewerStammGen/Interface/Navigator/IRenavigator.cs b/SewerStammGen/Interface/Navigator/IRenavigator.cs new file mode 100644 index 0000000..b9c01f8 --- /dev/null +++ b/SewerStammGen/Interface/Navigator/IRenavigator.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.Interface.Navigator +{ + public interface IRenavigator + { + void Renavigate(); + } +} diff --git a/SewerStammGen/MainWindow.xaml b/SewerStammGen/MainWindow.xaml index 38730b9..2ab9e10 100644 --- a/SewerStammGen/MainWindow.xaml +++ b/SewerStammGen/MainWindow.xaml @@ -9,7 +9,9 @@ xmlns:viewmodel="clr-namespace:SewerStammGen.WPF.ViewModel" xmlns:controls="clr-namespace:SewerStammGen.WPF.Views.Controls" mc:Ignorable="d" - Title="{Binding ApplicationTitle}" Height="450" Width="800"> + Title="{Binding ApplicationTitle}" Height="450" Width="800" FontSize="20" + WindowState="Maximized" + > @@ -23,15 +25,23 @@ + + + - - + + + + + + + diff --git a/SewerStammGen/SewerStammGen.WPF.csproj.user b/SewerStammGen/SewerStammGen.WPF.csproj.user index 480d87c..5a0dffe 100644 --- a/SewerStammGen/SewerStammGen.WPF.csproj.user +++ b/SewerStammGen/SewerStammGen.WPF.csproj.user @@ -13,6 +13,9 @@ Code + + Code + Code @@ -36,6 +39,9 @@ Designer + + Designer + Designer diff --git a/SewerStammGen/ViewModel/MainWindowViewModel.cs b/SewerStammGen/ViewModel/MainWindowViewModel.cs index fd62346..4797ab2 100644 --- a/SewerStammGen/ViewModel/MainWindowViewModel.cs +++ b/SewerStammGen/ViewModel/MainWindowViewModel.cs @@ -9,12 +9,15 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Input; +using SewerStammGen.WPF.ViewModel.State; namespace SewerStammGen.WPF.ViewModel { public class MainWindowViewModel : BaseViewModel { public IMainWindowNavigator Navigator { get; set; } + public string? Projektnummer { get; set; } + private readonly IActualState _actualState; public BaseViewModel CurrentViewModel => Navigator.CurrentViewModel; public ICommand UpdateCurrentViewModelCommand { get; } @@ -26,7 +29,8 @@ namespace SewerStammGen.WPF.ViewModel public MainWindowViewModel( IMainWindowNavigator navigator, - IViewModelAbstractFactory viewModelFactory + IViewModelAbstractFactory viewModelFactory, + IActualState actualState ) { @@ -35,11 +39,20 @@ namespace SewerStammGen.WPF.ViewModel UpdateCurrentViewModelCommand = new UpdateCurrentViewModelCommand(navigator, viewModelFactory); UpdateCurrentViewModelCommand.Execute(EMainWindowViewType.Home); + _actualState = actualState; + + _actualState.ProjektChanged += ActualState_ProjektChanged; Navigator.StateChanged += Navigator_StateChanged; } + private void ActualState_ProjektChanged(object? sender, EventArgs e) + { + Projektnummer = _actualState.ProjektID.ToString(); + OnPropertyChanged(nameof(Projektnummer)); + } + private void Navigator_StateChanged() { OnPropertyChanged(nameof(CurrentViewModel)); diff --git a/SewerStammGen/ViewModel/Projekt/ProjektEditViewModel.cs b/SewerStammGen/ViewModel/Projekt/ProjektEditViewModel.cs new file mode 100644 index 0000000..28bff52 --- /dev/null +++ b/SewerStammGen/ViewModel/Projekt/ProjektEditViewModel.cs @@ -0,0 +1,117 @@ +using SewerStammGen.WPF.Interface.Navigator; +using SewerStammGen.WPF.ViewModel.State; +using Shared.Contracts; +using Shared.Domain; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Security.RightsManagement; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace SewerStammGen.WPF.ViewModel +{ + internal class ProjektEditViewModel : BaseViewModel + { + private Projekt _model; + private int ProjektID; + private readonly IDataService _dataService; + private readonly IRenavigator _renavigator; + + public ICommand Speichern { get; set; } + public string ProjektName + { + get => _model.Projektname; + set + { + if(_model.Projektname != value) + { + _model.Projektname = value; + OnPropertyChanged(); + } + } + } + public string Erstelldatum + { + get => _model.Erstelldatum; + set + { + if (_model.Erstelldatum != value) + { + _model.Erstelldatum = value; + OnPropertyChanged(); + } + } + } + public string Strasse + { + get => _model.Strasse; + set + { + if (_model.Strasse != value) + { + _model.Strasse = value; + OnPropertyChanged(); + } + } + } + public string Ort + { + get => _model.Ort; + set + { + if (_model.Ort != value) + { + _model.Ort = value; + OnPropertyChanged(); + } + } + } + + public ProjektEditViewModel(IDataService dataService, IRenavigator renavigator, IActualState actualState) + { + _dataService = dataService; + _renavigator = renavigator; + + ProjektID = actualState.ProjektID; + + _model = new Projekt(); + Speichern = new RelayCommand((x) => this.SaveProject()); + + LoadProjekt(); + } + + private async void LoadProjekt() + { + + _model = await _dataService.Get(ProjektID); + if(_model == null) + { + _model = new Projekt() + { + Auftraggeber = new Auftraggeber(), + }; + } + OnPropertyChanged(nameof(ProjektName)); + OnPropertyChanged(nameof(Erstelldatum)); + OnPropertyChanged(nameof(Strasse)); + OnPropertyChanged(nameof(Ort)); + } + + private void SaveProject() + { + if (_model.Id == 0) // Handelt sich um ein neuen Eintrag + { + _dataService.Create(_model); + } + else + { + _dataService.Update(_model.Id, _model); + } + _renavigator.Renavigate(); + } + } +} diff --git a/SewerStammGen/ViewModel/Projekt/ProjektListViewModel.cs b/SewerStammGen/ViewModel/Projekt/ProjektListViewModel.cs index 707b8ed..2f8194d 100644 --- a/SewerStammGen/ViewModel/Projekt/ProjektListViewModel.cs +++ b/SewerStammGen/ViewModel/Projekt/ProjektListViewModel.cs @@ -1,5 +1,8 @@ using SewerStammGen.EntityFramework.Services; +using SewerStammGen.WPF.Commands; +using SewerStammGen.WPF.Interface.Navigator; using SewerStammGen.WPF.ViewModel; +using SewerStammGen.WPF.ViewModel.State; using Shared.Contracts; using Shared.Domain; using System; @@ -8,19 +11,49 @@ using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Input; namespace SewerStammGen.WPF.ViewModel { public class ProjektListViewModel : BaseViewModel { private IDataService genericDataService; - private readonly ObservableCollection Projekte; + private readonly ObservableCollection _projekte; + private readonly IActualState _actualState; + public ObservableCollection Projekte { get => _projekte; } + public bool CanSelectProjekt => _selectedProjekt != null; - public ProjektListViewModel(IDataService generic) + public ICommand SelectCommand { get; set; } + public ICommand AddCommand { get; set; } + public ICommand EditCommand { get; set; } + + private Projekt? _selectedProjekt; + + + + public Projekt? SelectedProjekt { - Projekte = new ObservableCollection(); + get => _selectedProjekt; + set + { + if(_selectedProjekt != value) + { + _selectedProjekt = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(CanSelectProjekt)); + } + } + } + + public ProjektListViewModel(IDataService generic, IRenavigator renavigator,IActualState actualState) + { + _projekte = new ObservableCollection(); if (generic == null) throw new ArgumentNullException(nameof(generic)); this.genericDataService = generic; + _actualState = actualState; + AddCommand = new ProjektAddCommand(generic,actualState, renavigator); + SelectCommand = new ProjektSelectCommand(actualState,this); + EditCommand = new ProjektEditCommand(generic, actualState, renavigator, this); LoadProjekte(); } @@ -28,7 +61,7 @@ namespace SewerStammGen.WPF.ViewModel private async void LoadProjekte() { var projects = await genericDataService.GetAll(); - InitCollection(Projekte, projects); + InitCollection(_projekte, projects); } private void InitCollection(ObservableCollection projekte, IEnumerable projects) diff --git a/SewerStammGen/ViewModel/State/ActualState.cs b/SewerStammGen/ViewModel/State/ActualState.cs new file mode 100644 index 0000000..70f1cfb --- /dev/null +++ b/SewerStammGen/ViewModel/State/ActualState.cs @@ -0,0 +1,30 @@ +using Shared.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.ViewModel.State +{ + internal class ActualState : IActualState + { + public int ProjektID { get; private set; } + + public void SetProjekt(Projekt projekt, bool notification = true) + { + ProjektID = projekt.Id; + if(notification) + { + OnProjektChanged(); + } + } + + + public event EventHandler? ProjektChanged; + private void OnProjektChanged() + { + ProjektChanged?.Invoke(this, new EventArgs()); + } + } +} diff --git a/SewerStammGen/ViewModel/State/IActualState.cs b/SewerStammGen/ViewModel/State/IActualState.cs new file mode 100644 index 0000000..7b77e8b --- /dev/null +++ b/SewerStammGen/ViewModel/State/IActualState.cs @@ -0,0 +1,18 @@ +using Shared.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.ViewModel.State +{ + public interface IActualState + { + event EventHandler? ProjektChanged; + + int ProjektID { get; } + + void SetProjekt(Projekt projekt, bool notification = true); + } +} diff --git a/SewerStammGen/ViewModel/State/Navigation/ViewModelDelegateRenavigator.cs b/SewerStammGen/ViewModel/State/Navigation/ViewModelDelegateRenavigator.cs new file mode 100644 index 0000000..8fcb6c9 --- /dev/null +++ b/SewerStammGen/ViewModel/State/Navigation/ViewModelDelegateRenavigator.cs @@ -0,0 +1,25 @@ +using SewerStammGen.WPF.Interface.Navigator; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SewerStammGen.WPF.ViewModel.State.Navigation +{ + internal class ViewModelDelegateRenavigator : IRenavigator where TViewModel : BaseViewModel + { + private readonly IMainWindowNavigator _navigator; + private readonly CreateViewModel _createViewModel; + + public ViewModelDelegateRenavigator(IMainWindowNavigator navigator, CreateViewModel createViewModel) + { + _navigator = navigator; + _createViewModel = createViewModel; + } + public void Renavigate() + { + _navigator.CurrentViewModel = _createViewModel(); + } + } +} diff --git a/SewerStammGen/Views/Controls/UCMainWindowNavigationBar.xaml b/SewerStammGen/Views/Controls/UCMainWindowNavigationBar.xaml index b3e0b2c..82dc03a 100644 --- a/SewerStammGen/Views/Controls/UCMainWindowNavigationBar.xaml +++ b/SewerStammGen/Views/Controls/UCMainWindowNavigationBar.xaml @@ -18,7 +18,7 @@ - + diff --git a/SewerStammGen/Views/Projekte/ProjektEditView.xaml b/SewerStammGen/Views/Projekte/ProjektEditView.xaml new file mode 100644 index 0000000..1e0fb55 --- /dev/null +++ b/SewerStammGen/Views/Projekte/ProjektEditView.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + +