Loginfenster und deutsche Kommentare

This commit is contained in:
younes elhaddoury 2025-08-31 23:33:31 +02:00
parent cfb405a002
commit 159c783bd6
10 changed files with 458 additions and 205 deletions

View File

@ -12,17 +12,19 @@ Dieses Projekt dient als einfache Verwaltung von Fahrzeugen für ein Autohaus. D
3. Projekt `WpfApp4.sln` mit Visual Studio öffnen und starten 3. Projekt `WpfApp4.sln` mit Visual Studio öffnen und starten
## Funktionen ## Funktionen
- Anmeldung mit Benutzer **admin** und Passwort **admin**
- Fahrzeuge anlegen, bearbeiten, löschen und anzeigen (CRUD) - Fahrzeuge anlegen, bearbeiten, löschen und anzeigen (CRUD)
- Auswahl aus 30 Marken mit jeweils sechs Modellen - Auswahl aus 40 Marken mit jeweils sechs Modellen
- Suche und Filterung über ein DataGrid - Suche und Filterung über ein DataGrid
- Export eines ausgewählten Fahrzeugs als PDF - Export eines ausgewählten Fahrzeugs als PDF
## Bedienung ## Bedienung
1. Marke und Modell aus den Listen wählen 1. Nach dem Start mit den oben genannten Daten anmelden
2. Fahrzeugdaten eingeben und **Hinzufügen** drücken 2. Marke und Modell aus den Listen wählen
3. Eintrag auswählen und über **Bearbeiten** oder **Löschen** ändern 3. Fahrzeugdaten eingeben und **Hinzufügen** drücken
4. **Aktualisieren** lädt die Liste neu, **Alle anzeigen** setzt Filter zurück 4. Eintrag auswählen und über **Bearbeiten** oder **Löschen** ändern
5. **Als PDF speichern** erzeugt ein Informationsblatt 5. **Aktualisieren** lädt die Liste neu, **Alle anzeigen** setzt Filter zurück
6. **Als PDF speichern** erzeugt ein Informationsblatt
## Projektstruktur ## Projektstruktur
- `WpfApp4`: Benutzeroberfläche und Logik - `WpfApp4`: Benutzeroberfläche und Logik
@ -34,4 +36,3 @@ Dieses Projekt wurde im Rahmen einer Übung von **Younes**, **Saad** und **Ayman
- **Younes** kümmerte sich um Datenbank und grundlegende Geschäftslogik. - **Younes** kümmerte sich um Datenbank und grundlegende Geschäftslogik.
- **Saad** gestaltete die Oberfläche und implementierte den PDF-Export. - **Saad** gestaltete die Oberfläche und implementierte den PDF-Export.
- **Ayman** verfasste die Dokumentation und begleitete die Tests. - **Ayman** verfasste die Dokumentation und begleitete die Tests.

View File

@ -1,8 +1,7 @@
<Application x:Class="FahrzeugVerwaltung.App" <Application x:Class="FahrzeugVerwaltung.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"> StartupUri="LoginWindow.xaml">
<Application.Resources> <Application.Resources>
<!-- Globale Styles können hier definiert werden -->
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@ -1,12 +1,11 @@
using System; using System;
using System.Windows; using System.Windows;
namespace FahrzeugVerwaltung namespace FahrzeugVerwaltung
{ {
public partial class App : Application public partial class App : Application
{ {
// Startet Programm und meldet Fehler // Richtet die globale Fehlerbehandlung ein
protected override void OnStartup(StartupEventArgs e) protected override void OnStartup(StartupEventArgs e)
{ {
base.OnStartup(e); base.OnStartup(e);
@ -14,7 +13,7 @@ namespace FahrzeugVerwaltung
DispatcherUnhandledException += App_UnbehandelteAusnahme; DispatcherUnhandledException += App_UnbehandelteAusnahme;
} }
// Zeigt Fehler in Oberfläche // Zeigt nicht abgefangene Fehler an
private void App_UnbehandelteAusnahme(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) private void App_UnbehandelteAusnahme(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{ {
MessageBox.Show($"Ein unerwarteter Fehler ist aufgetreten:\n{e.Exception.Message}", MessageBox.Show($"Ein unerwarteter Fehler ist aufgetreten:\n{e.Exception.Message}",
@ -22,7 +21,7 @@ namespace FahrzeugVerwaltung
e.Handled = true; e.Handled = true;
} }
// Meldet kritische Ausnahmen // Meldet schwere Ausnahmen
private void Domain_UnbehandelteAusnahme(object sender, UnhandledExceptionEventArgs e) private void Domain_UnbehandelteAusnahme(object sender, UnhandledExceptionEventArgs e)
{ {
MessageBox.Show($"Ein kritischer Fehler ist aufgetreten:\n{((Exception)e.ExceptionObject).Message}", MessageBox.Show($"Ein kritischer Fehler ist aufgetreten:\n{((Exception)e.ExceptionObject).Message}",

View File

@ -17,10 +17,11 @@ namespace FahrzeugVerwaltung
ErstelleDatenbank(); ErstelleDatenbank();
} }
// Erstellt Datenbank und Tabelle // Legt Datenbank und Tabelle an
private void ErstelleDatenbank() private void ErstelleDatenbank()
{ {
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = @" string query = @"
CREATE TABLE IF NOT EXISTS Fahrzeuge ( CREATE TABLE IF NOT EXISTS Fahrzeuge (
@ -34,20 +35,25 @@ namespace FahrzeugVerwaltung
Farbe TEXT NOT NULL, Farbe TEXT NOT NULL,
ErstelltAm DATETIME DEFAULT CURRENT_TIMESTAMP ErstelltAm DATETIME DEFAULT CURRENT_TIMESTAMP
)"; )";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
command.ExecuteNonQuery(); command.ExecuteNonQuery();
} }
}
}
// Speichert Fahrzeug und gibt neue Id zurück // Speichert ein Fahrzeug und liefert die Id
public int SpeichereFahrzeug(Fahrzeug fahrzeug) public int SpeichereFahrzeug(Fahrzeug fahrzeug)
{ {
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = @" string query = @"
INSERT INTO Fahrzeuge (Marke, Modell, Baujahr, Leistung, Kilometerstand, Kaufpreis, Farbe) INSERT INTO Fahrzeuge (Marke, Modell, Baujahr, Leistung, Kilometerstand, Kaufpreis, Farbe)
VALUES (@Marke, @Modell, @Baujahr, @Leistung, @Kilometer, @Kaufpreis, @Farbe); VALUES (@Marke, @Modell, @Baujahr, @Leistung, @Kilometer, @Kaufpreis, @Farbe);
SELECT last_insert_rowid();"; SELECT last_insert_rowid();";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
command.Parameters.AddWithValue("@Marke", fahrzeug.Marke); command.Parameters.AddWithValue("@Marke", fahrzeug.Marke);
command.Parameters.AddWithValue("@Modell", fahrzeug.Modell); command.Parameters.AddWithValue("@Modell", fahrzeug.Modell);
command.Parameters.AddWithValue("@Baujahr", fahrzeug.Baujahr); command.Parameters.AddWithValue("@Baujahr", fahrzeug.Baujahr);
@ -57,16 +63,20 @@ namespace FahrzeugVerwaltung
command.Parameters.AddWithValue("@Farbe", fahrzeug.Farbe); command.Parameters.AddWithValue("@Farbe", fahrzeug.Farbe);
return Convert.ToInt32(command.ExecuteScalar()); return Convert.ToInt32(command.ExecuteScalar());
} }
}
}
// Lädt alle Fahrzeuge // Liefert alle Fahrzeuge
public List<Fahrzeug> LadeAlleFahrzeuge() public List<Fahrzeug> LadeAlleFahrzeuge()
{ {
var fahrzeuge = new List<Fahrzeug>(); List<Fahrzeug> fahrzeuge = new List<Fahrzeug>();
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = "SELECT * FROM Fahrzeuge ORDER BY Marke, Modell"; string query = "SELECT * FROM Fahrzeuge ORDER BY Marke, Modell";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
using var reader = command.ExecuteReader(); using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read()) while (reader.Read())
{ {
fahrzeuge.Add(new Fahrzeug fahrzeuge.Add(new Fahrzeug
@ -81,17 +91,22 @@ namespace FahrzeugVerwaltung
Farbe = reader["Farbe"].ToString() Farbe = reader["Farbe"].ToString()
}); });
} }
}
}
return fahrzeuge; return fahrzeuge;
} }
// Sucht Fahrzeuge mit Text // Sucht Fahrzeuge nach Text
public List<Fahrzeug> SucheFahrzeuge(string suchbegriff) public List<Fahrzeug> SucheFahrzeuge(string suchbegriff)
{ {
if (string.IsNullOrWhiteSpace(suchbegriff)) if (string.IsNullOrWhiteSpace(suchbegriff))
{
return LadeAlleFahrzeuge(); return LadeAlleFahrzeuge();
}
var fahrzeuge = new List<Fahrzeug>(); List<Fahrzeug> fahrzeuge = new List<Fahrzeug>();
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = @" string query = @"
SELECT * FROM Fahrzeuge SELECT * FROM Fahrzeuge
@ -100,9 +115,11 @@ namespace FahrzeugVerwaltung
OR Farbe LIKE @S OR Farbe LIKE @S
OR CAST(Baujahr AS TEXT) LIKE @S OR CAST(Baujahr AS TEXT) LIKE @S
ORDER BY Marke, Modell"; ORDER BY Marke, Modell";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
command.Parameters.AddWithValue("@S", $"%{suchbegriff}%"); command.Parameters.AddWithValue("@S", $"%{suchbegriff}%");
using var reader = command.ExecuteReader(); using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read()) while (reader.Read())
{ {
fahrzeuge.Add(new Fahrzeug fahrzeuge.Add(new Fahrzeug
@ -117,13 +134,17 @@ namespace FahrzeugVerwaltung
Farbe = reader["Farbe"].ToString() Farbe = reader["Farbe"].ToString()
}); });
} }
}
}
}
return fahrzeuge; return fahrzeuge;
} }
// Aktualisiert Fahrzeug // Aktualisiert ein Fahrzeug
public bool AktualisiereFahrzeug(Fahrzeug fahrzeug) public bool AktualisiereFahrzeug(Fahrzeug fahrzeug)
{ {
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = @" string query = @"
UPDATE Fahrzeuge UPDATE Fahrzeuge
@ -135,7 +156,8 @@ namespace FahrzeugVerwaltung
Kaufpreis=@Kaufpreis, Kaufpreis=@Kaufpreis,
Farbe=@Farbe Farbe=@Farbe
WHERE Id=@Id"; WHERE Id=@Id";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
command.Parameters.AddWithValue("@Id", fahrzeug.Id); command.Parameters.AddWithValue("@Id", fahrzeug.Id);
command.Parameters.AddWithValue("@Marke", fahrzeug.Marke); command.Parameters.AddWithValue("@Marke", fahrzeug.Marke);
command.Parameters.AddWithValue("@Modell", fahrzeug.Modell); command.Parameters.AddWithValue("@Modell", fahrzeug.Modell);
@ -146,26 +168,36 @@ namespace FahrzeugVerwaltung
command.Parameters.AddWithValue("@Farbe", fahrzeug.Farbe); command.Parameters.AddWithValue("@Farbe", fahrzeug.Farbe);
return command.ExecuteNonQuery() > 0; return command.ExecuteNonQuery() > 0;
} }
}
}
// Löscht Fahrzeug // Löscht ein Fahrzeug
public bool LoescheFahrzeug(int id) public bool LoescheFahrzeug(int id)
{ {
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = "DELETE FROM Fahrzeuge WHERE Id=@Id"; string query = "DELETE FROM Fahrzeuge WHERE Id=@Id";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
command.Parameters.AddWithValue("@Id", id); command.Parameters.AddWithValue("@Id", id);
return command.ExecuteNonQuery() > 0; return command.ExecuteNonQuery() > 0;
} }
}
}
// Zählt Fahrzeuge // Zählt vorhandene Fahrzeuge
public int HoleAnzahlFahrzeuge() public int HoleAnzahlFahrzeuge()
{ {
using var connection = new SQLiteConnection(_connectionString); using (SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
connection.Open(); connection.Open();
string query = "SELECT COUNT(*) FROM Fahrzeuge"; string query = "SELECT COUNT(*) FROM Fahrzeuge";
using var command = new SQLiteCommand(query, connection); using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
return Convert.ToInt32(command.ExecuteScalar()); return Convert.ToInt32(command.ExecuteScalar());
} }
} }
} }
}
}

View File

@ -14,44 +14,128 @@ namespace FahrzeugVerwaltung
private decimal _kaufpreis; private decimal _kaufpreis;
private string _farbe; private string _farbe;
public int Id { get => _id; set { _id = value; MeldeEigenschaft(nameof(Id)); } } public int Id
public string Marke { get => _marke; set { _marke = value; MeldeEigenschaft(nameof(Marke)); } } {
public string Modell { get => _modell; set { _modell = value; MeldeEigenschaft(nameof(Modell)); } } get { return _id; }
public int Baujahr { get => _baujahr; set { _baujahr = value; MeldeEigenschaft(nameof(Baujahr)); MeldeEigenschaft(nameof(AktuellerWert)); MeldeEigenschaft(nameof(AktuellerWertFormatiert)); } } set { _id = value; MeldeEigenschaft(nameof(Id)); }
public int Leistung { get => _leistung; set { _leistung = value; MeldeEigenschaft(nameof(Leistung)); } } }
public int Kilometerstand { get => _kilometerstand; set { _kilometerstand = value; MeldeEigenschaft(nameof(Kilometerstand)); MeldeEigenschaft(nameof(KilometerstandFormatiert)); MeldeEigenschaft(nameof(AktuellerWert)); MeldeEigenschaft(nameof(AktuellerWertFormatiert)); } }
public decimal Kaufpreis { get => _kaufpreis; set { _kaufpreis = value; MeldeEigenschaft(nameof(Kaufpreis)); MeldeEigenschaft(nameof(KaufpreisFormatiert)); MeldeEigenschaft(nameof(AktuellerWert)); MeldeEigenschaft(nameof(AktuellerWertFormatiert)); } }
public string Farbe { get => _farbe; set { _farbe = value; MeldeEigenschaft(nameof(Farbe)); } }
public string KilometerstandFormatiert => $"{Kilometerstand:N0} km"; public string Marke
public string KaufpreisFormatiert => $"{Kaufpreis:C}"; {
public string AktuellerWertFormatiert => $"{AktuellerWert:C}"; get { return _marke; }
set { _marke = value; MeldeEigenschaft(nameof(Marke)); }
}
// Geschätzter aktueller Wert public string Modell
public decimal AktuellerWert => BerechneAktuellenWert(); {
get { return _modell; }
set { _modell = value; MeldeEigenschaft(nameof(Modell)); }
}
// Berechnet aktuellen Wert public int Baujahr
{
get { return _baujahr; }
set
{
_baujahr = value;
MeldeEigenschaft(nameof(Baujahr));
MeldeEigenschaft(nameof(AktuellerWert));
MeldeEigenschaft(nameof(AktuellerWertFormatiert));
}
}
public int Leistung
{
get { return _leistung; }
set { _leistung = value; MeldeEigenschaft(nameof(Leistung)); }
}
public int Kilometerstand
{
get { return _kilometerstand; }
set
{
_kilometerstand = value;
MeldeEigenschaft(nameof(Kilometerstand));
MeldeEigenschaft(nameof(KilometerstandFormatiert));
MeldeEigenschaft(nameof(AktuellerWert));
MeldeEigenschaft(nameof(AktuellerWertFormatiert));
}
}
public decimal Kaufpreis
{
get { return _kaufpreis; }
set
{
_kaufpreis = value;
MeldeEigenschaft(nameof(Kaufpreis));
MeldeEigenschaft(nameof(KaufpreisFormatiert));
MeldeEigenschaft(nameof(AktuellerWert));
MeldeEigenschaft(nameof(AktuellerWertFormatiert));
}
}
public string Farbe
{
get { return _farbe; }
set { _farbe = value; MeldeEigenschaft(nameof(Farbe)); }
}
public string KilometerstandFormatiert
{
get { return $"{Kilometerstand:N0} km"; }
}
public string KaufpreisFormatiert
{
get { return $"{Kaufpreis:C}"; }
}
public string AktuellerWertFormatiert
{
get { return $"{AktuellerWert:C}"; }
}
// Berechneter aktueller Wert
public decimal AktuellerWert
{
get { return BerechneAktuellenWert(); }
}
// Ermittelt einen Schätzwert
public decimal BerechneAktuellenWert() public decimal BerechneAktuellenWert()
{ {
if (Kaufpreis <= 0 || Baujahr <= 0) return 0; if (Kaufpreis <= 0 || Baujahr <= 0)
{
return 0;
}
int alter = DateTime.Now.Year - Baujahr; int alter = DateTime.Now.Year - Baujahr;
decimal wertverlust = 0; decimal wertverlust = 0;
for (int i = 0; i < alter; i++) for (int i = 0; i < alter; i++)
{
wertverlust += (i < 3) ? 0.15m : 0.10m; wertverlust += (i < 3) ? 0.15m : 0.10m;
}
wertverlust += (Kilometerstand / 10000m) * 0.02m; wertverlust += (Kilometerstand / 10000m) * 0.02m;
if (wertverlust > 0.90m) wertverlust = 0.90m; if (wertverlust > 0.90m)
{
wertverlust = 0.90m;
}
decimal wert = Kaufpreis * (1 - wertverlust); decimal wert = Kaufpreis * (1 - wertverlust);
decimal mindestwert = Kaufpreis * 0.05m; decimal mindestwert = Kaufpreis * 0.05m;
if (wert < mindestwert) wert = mindestwert; if (wert < mindestwert)
{
wert = mindestwert;
}
return Math.Round(wert, 2); return Math.Round(wert, 2);
} }
// Beschreibung für Anzeige // Text für die Oberfläche
public string HoleBeschreibung() public string HoleBeschreibung()
{ {
return $"{Marke} {Modell} ({Baujahr}) - {Leistung} PS - {KilometerstandFormatiert} - {Farbe}"; return $"{Marke} {Modell} ({Baujahr}) - {Leistung} PS - {KilometerstandFormatiert} - {Farbe}";
@ -71,12 +155,15 @@ namespace FahrzeugVerwaltung
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
// Meldet geänderte Eigenschaft // Meldet geänderte Eigenschaften
private void MeldeEigenschaft(string eigenschaft) private void MeldeEigenschaft(string eigenschaft)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(eigenschaft)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(eigenschaft));
} }
public override string ToString() => $"{Marke} {Modell} ({Baujahr})"; public override string ToString()
{
return $"{Marke} {Modell} ({Baujahr})";
}
} }
} }

56
WpfApp4/LoginWindow.xaml Normal file
View File

@ -0,0 +1,56 @@
<Window x:Class="FahrzeugVerwaltung.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Anmeldung" Height="300" Width="400" WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="BorderBrush" Value="#FF1976D2"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="#FF2196F3"/>
<Setter Property="Padding" Value="10,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF1976D2"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Margin="20">
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFFFFF" Offset="0"/>
<GradientStop Color="#E3F2FD" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Anmeldung" FontSize="28" FontWeight="SemiBold" Foreground="#FF1976D2" HorizontalAlignment="Center" Margin="0,0,0,20"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,10">
<Label Content="Benutzername:" Width="110" VerticalAlignment="Center"/>
<TextBox x:Name="txtBenutzer" Width="200"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Label Content="Passwort:" Width="110" VerticalAlignment="Center"/>
<PasswordBox x:Name="txtPasswort" Width="200"/>
</StackPanel>
<Button Grid.Row="3" Content="Einloggen" Width="120" Height="35" HorizontalAlignment="Center" Margin="0,20,0,0" Click="BtnLogin_Click"/>
</Grid>
</Window>

View File

@ -0,0 +1,32 @@
using System.Windows;
namespace FahrzeugVerwaltung
{
public partial class LoginWindow : Window
{
public LoginWindow()
{
InitializeComponent();
}
// Prüft Zugangsdaten und öffnet Hauptfenster
private void BtnLogin_Click(object sender, RoutedEventArgs e)
{
string benutzer = txtBenutzer.Text.Trim();
string passwort = txtPasswort.Password;
if (benutzer == "admin" && passwort == "admin")
{
MainWindow haupt = new MainWindow();
haupt.Show();
Close();
}
else
{
MessageBox.Show("Falsche Zugangsdaten", "Fehler", MessageBoxButton.OK, MessageBoxImage.Warning);
txtPasswort.Clear();
txtBenutzer.Focus();
}
}
}
}

View File

@ -54,8 +54,8 @@
<Grid Margin="10"> <Grid Margin="10">
<Grid.Background> <Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFFFFF" Offset="0"/> <GradientStop Color="#F5F5F5" Offset="0"/>
<GradientStop Color="#E3F2FD" Offset="1"/> <GradientStop Color="#E1F5FE" Offset="1"/>
</LinearGradientBrush> </LinearGradientBrush>
</Grid.Background> </Grid.Background>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -67,7 +67,7 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.ColumnSpan="2" Grid.Row="0" Text="Fahrzeugverwaltung" FontSize="32" FontWeight="SemiBold" FontFamily="Segoe UI" Foreground="#FF1976D2" HorizontalAlignment="Center" Margin="0,0,0,10"/> <TextBlock Grid.ColumnSpan="2" Grid.Row="0" Text="Fahrzeugverwaltung" FontSize="32" FontWeight="SemiBold" FontFamily="Segoe UI" Foreground="#FF0D47A1" HorizontalAlignment="Center" Margin="0,0,0,10"/>
<GroupBox Grid.Column="0" Grid.Row="1" Header="Neues Fahrzeug" Margin="5"> <GroupBox Grid.Column="0" Grid.Row="1" Header="Neues Fahrzeug" Margin="5">
<Grid Margin="10"> <Grid Margin="10">
<Grid.RowDefinitions> <Grid.RowDefinitions>

View File

@ -22,7 +22,8 @@ namespace FahrzeugVerwaltung
MarkenVorbereiten(); MarkenVorbereiten();
FahrzeugeLaden(); FahrzeugeLaden();
} }
// Legt Dienste an
// Erzeugt Dienstobjekte
private void DiensteAnlegen() private void DiensteAnlegen()
{ {
_datenbankDienst = new DatabaseService(); _datenbankDienst = new DatabaseService();
@ -30,7 +31,7 @@ namespace FahrzeugVerwaltung
_fahrzeuge = new List<Fahrzeug>(); _fahrzeuge = new List<Fahrzeug>();
} }
// Bereitet Marken und Modelle vor // Füllt die Listen mit Marken und Modellen
private void MarkenVorbereiten() private void MarkenVorbereiten()
{ {
_markenModelle = new Dictionary<string, List<string>> _markenModelle = new Dictionary<string, List<string>>
@ -64,13 +65,23 @@ namespace FahrzeugVerwaltung
{"Porsche", new List<string>{"911","Cayenne","Panamera","Macan","Taycan","Boxster"}}, {"Porsche", new List<string>{"911","Cayenne","Panamera","Macan","Taycan","Boxster"}},
{"Citroën", new List<string>{"C1","C3","C4","C5","C3 Aircross","Berlingo"}}, {"Citroën", new List<string>{"C1","C3","C4","C5","C3 Aircross","Berlingo"}},
{"Alfa Romeo", new List<string>{"Giulia","Giulietta","Stelvio","MiTo","4C","Tonale"}}, {"Alfa Romeo", new List<string>{"Giulia","Giulietta","Stelvio","MiTo","4C","Tonale"}},
{"Mini", new List<string>{"One","Cooper","Clubman","Countryman","Cabrio","Paceman"}} {"Mini", new List<string>{"One","Cooper","Clubman","Countryman","Cabrio","Paceman"}},
{"Dodge", new List<string>{"Charger","Challenger","Durango","Journey","Ram","Viper"}},
{"Chrysler", new List<string>{"200","300","Pacifica","Voyager","Aspen","Sebring"}},
{"Buick", new List<string>{"Encore","Enclave","LaCrosse","Regal","Verano","Envision"}},
{"Cadillac", new List<string>{"ATS","CTS","Escalade","XT5","XT4","CT6"}},
{"Infiniti", new List<string>{"Q50","Q60","Q70","QX50","QX60","QX80"}},
{"Acura", new List<string>{"ILX","TLX","RLX","MDX","RDX","NSX"}},
{"Suzuki", new List<string>{"Swift","Vitara","Baleno","Jimny","SX4","Ignis"}},
{"Saab", new List<string>{"9-3","9-5","900","9-4X","9-7X","96"}},
{"Lincoln", new List<string>{"MKZ","MKX","Continental","Navigator","Corsair","Aviator"}},
{"Bentley", new List<string>{"Continental GT","Flying Spur","Bentayga","Mulsanne","Arnage","Azure"}}
}; };
cmbMarke.ItemsSource = _markenModelle.Keys; cmbMarke.ItemsSource = _markenModelle.Keys;
} }
// Lädt Fahrzeuge aus der Datenbank // Holt Fahrzeuge aus der Datenbank
private void FahrzeugeLaden() private void FahrzeugeLaden()
{ {
_fahrzeuge = _datenbankDienst.LadeAlleFahrzeuge(); _fahrzeuge = _datenbankDienst.LadeAlleFahrzeuge();
@ -78,22 +89,28 @@ namespace FahrzeugVerwaltung
StatusAktualisieren(); StatusAktualisieren();
} }
// Zeigt Anzahl der Fahrzeuge // Aktualisiert die Statuszeile
private void StatusAktualisieren() private void StatusAktualisieren()
{ {
if (_fahrzeuge.Count == 0) if (_fahrzeuge.Count == 0)
{
txtDetails.Text = "Keine Fahrzeuge vorhanden"; txtDetails.Text = "Keine Fahrzeuge vorhanden";
}
else else
{
txtDetails.Text = $"{_fahrzeuge.Count} Fahrzeug(e) gefunden"; txtDetails.Text = $"{_fahrzeuge.Count} Fahrzeug(e) gefunden";
} }
}
// Fügt Fahrzeug hinzu // Speichert ein neues Fahrzeug
private void BtnHinzufuegen_Click(object sender, RoutedEventArgs e) private void BtnHinzufuegen_Click(object sender, RoutedEventArgs e)
{ {
if (!EingabenPruefen()) if (!EingabenPruefen())
{
return; return;
}
var fahrzeug = new Fahrzeug Fahrzeug fahrzeug = new Fahrzeug
{ {
Marke = cmbMarke.SelectedItem.ToString(), Marke = cmbMarke.SelectedItem.ToString(),
Modell = cmbModell.SelectedItem.ToString(), Modell = cmbModell.SelectedItem.ToString(),
@ -110,11 +127,13 @@ namespace FahrzeugVerwaltung
FahrzeugeLaden(); FahrzeugeLaden();
} }
// Speichert Änderungen // Übernimmt Änderungen
private void BtnBearbeiten_Click(object sender, RoutedEventArgs e) private void BtnBearbeiten_Click(object sender, RoutedEventArgs e)
{ {
if (_ausgewaehltesFahrzeug == null || !EingabenPruefen()) if (_ausgewaehltesFahrzeug == null || !EingabenPruefen())
{
return; return;
}
_ausgewaehltesFahrzeug.Marke = cmbMarke.SelectedItem.ToString(); _ausgewaehltesFahrzeug.Marke = cmbMarke.SelectedItem.ToString();
_ausgewaehltesFahrzeug.Modell = cmbModell.SelectedItem.ToString(); _ausgewaehltesFahrzeug.Modell = cmbModell.SelectedItem.ToString();
@ -125,15 +144,19 @@ namespace FahrzeugVerwaltung
_ausgewaehltesFahrzeug.Farbe = txtFarbe.Text.Trim(); _ausgewaehltesFahrzeug.Farbe = txtFarbe.Text.Trim();
if (_datenbankDienst.AktualisiereFahrzeug(_ausgewaehltesFahrzeug)) if (_datenbankDienst.AktualisiereFahrzeug(_ausgewaehltesFahrzeug))
{
MessageBox.Show("Fahrzeug aktualisiert.", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information); MessageBox.Show("Fahrzeug aktualisiert.", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information);
}
FahrzeugeLaden(); FahrzeugeLaden();
} }
// Löscht ausgewähltes Fahrzeug // Entfernt das gewählte Fahrzeug
private void BtnLoeschen_Click(object sender, RoutedEventArgs e) private void BtnLoeschen_Click(object sender, RoutedEventArgs e)
{ {
if (_ausgewaehltesFahrzeug == null) if (_ausgewaehltesFahrzeug == null)
{
return; return;
}
if (MessageBox.Show("Fahrzeug wirklich löschen?", "Bestätigung", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) if (MessageBox.Show("Fahrzeug wirklich löschen?", "Bestätigung", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{ {
@ -146,25 +169,39 @@ namespace FahrzeugVerwaltung
} }
} }
// Prüft Eingaben // Prüft alle Eingaben
private bool EingabenPruefen() private bool EingabenPruefen()
{ {
var fehler = new List<string>(); List<string> fehler = new List<string>();
if (cmbMarke.SelectedItem == null) if (cmbMarke.SelectedItem == null)
{
fehler.Add("Marke wählen"); fehler.Add("Marke wählen");
}
if (cmbModell.SelectedItem == null) if (cmbModell.SelectedItem == null)
{
fehler.Add("Modell wählen"); fehler.Add("Modell wählen");
}
if (!int.TryParse(txtBaujahr.Text, out int baujahr) || baujahr < 1900 || baujahr > DateTime.Now.Year) if (!int.TryParse(txtBaujahr.Text, out int baujahr) || baujahr < 1900 || baujahr > DateTime.Now.Year)
{
fehler.Add($"Baujahr zwischen 1900 und {DateTime.Now.Year}"); fehler.Add($"Baujahr zwischen 1900 und {DateTime.Now.Year}");
}
if (!int.TryParse(txtLeistung.Text, out int leistung) || leistung <= 0) if (!int.TryParse(txtLeistung.Text, out int leistung) || leistung <= 0)
{
fehler.Add("Leistung muss positiv sein"); fehler.Add("Leistung muss positiv sein");
}
if (!int.TryParse(txtKilometer.Text, out int kilometer) || kilometer < 0) if (!int.TryParse(txtKilometer.Text, out int kilometer) || kilometer < 0)
{
fehler.Add("Kilometerstand muss 0 oder größer sein"); fehler.Add("Kilometerstand muss 0 oder größer sein");
}
if (!decimal.TryParse(txtKaufpreis.Text, out decimal kaufpreis) || kaufpreis <= 0) if (!decimal.TryParse(txtKaufpreis.Text, out decimal kaufpreis) || kaufpreis <= 0)
{
fehler.Add("Kaufpreis muss positiv sein"); fehler.Add("Kaufpreis muss positiv sein");
}
if (string.IsNullOrWhiteSpace(txtFarbe.Text)) if (string.IsNullOrWhiteSpace(txtFarbe.Text))
{
fehler.Add("Farbe angeben"); fehler.Add("Farbe angeben");
}
if (fehler.Any()) if (fehler.Any())
{ {
@ -175,7 +212,7 @@ namespace FahrzeugVerwaltung
return true; return true;
} }
// Leert Eingaben // Leert alle Eingabefelder
private void EingabenLeeren() private void EingabenLeeren()
{ {
cmbMarke.SelectedIndex = -1; cmbMarke.SelectedIndex = -1;
@ -188,12 +225,14 @@ namespace FahrzeugVerwaltung
cmbMarke.Focus(); cmbMarke.Focus();
} }
// Sucht Fahrzeuge // Sucht nach einem Begriff
private void BtnSuchen_Click(object sender, RoutedEventArgs e) private void BtnSuchen_Click(object sender, RoutedEventArgs e)
{ {
var suchbegriff = txtSuche.Text.Trim(); string suchbegriff = txtSuche.Text.Trim();
if (string.IsNullOrWhiteSpace(suchbegriff)) if (string.IsNullOrWhiteSpace(suchbegriff))
{
return; return;
}
_fahrzeuge = _datenbankDienst.SucheFahrzeuge(suchbegriff); _fahrzeuge = _datenbankDienst.SucheFahrzeuge(suchbegriff);
dgFahrzeuge.ItemsSource = _fahrzeuge; dgFahrzeuge.ItemsSource = _fahrzeuge;
@ -207,7 +246,7 @@ namespace FahrzeugVerwaltung
FahrzeugeLaden(); FahrzeugeLaden();
} }
// Reagiert auf Tabellen-Auswahl // Reagiert auf Auswahl in der Tabelle
private void Liste_AuswahlGeaendert(object sender, SelectionChangedEventArgs e) private void Liste_AuswahlGeaendert(object sender, SelectionChangedEventArgs e)
{ {
_ausgewaehltesFahrzeug = dgFahrzeuge.SelectedItem as Fahrzeug; _ausgewaehltesFahrzeug = dgFahrzeuge.SelectedItem as Fahrzeug;
@ -232,13 +271,15 @@ namespace FahrzeugVerwaltung
} }
} }
// Exportiert Fahrzeug als PDF // Erstellt ein PDF für das gewählte Fahrzeug
private void BtnPdf_Click(object sender, RoutedEventArgs e) private void BtnPdf_Click(object sender, RoutedEventArgs e)
{ {
if (_ausgewaehltesFahrzeug == null) if (_ausgewaehltesFahrzeug == null)
{
return; return;
}
var dialog = new SaveFileDialog SaveFileDialog dialog = new SaveFileDialog
{ {
Filter = "PDF-Dateien (*.pdf)|*.pdf", Filter = "PDF-Dateien (*.pdf)|*.pdf",
FileName = $"Fahrzeug_{_ausgewaehltesFahrzeug.Marke}_{_ausgewaehltesFahrzeug.Modell}_{DateTime.Now:yyyyMMdd_HHmmss}.pdf" FileName = $"Fahrzeug_{_ausgewaehltesFahrzeug.Marke}_{_ausgewaehltesFahrzeug.Modell}_{DateTime.Now:yyyyMMdd_HHmmss}.pdf"
@ -247,17 +288,19 @@ namespace FahrzeugVerwaltung
if (dialog.ShowDialog() == true) if (dialog.ShowDialog() == true)
{ {
if (_pdfDienst.ErstelleFahrzeugPdf(_ausgewaehltesFahrzeug, dialog.FileName)) if (_pdfDienst.ErstelleFahrzeugPdf(_ausgewaehltesFahrzeug, dialog.FileName))
{
MessageBox.Show("PDF erstellt.", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information); MessageBox.Show("PDF erstellt.", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information);
} }
} }
}
// Aktualisiert Liste // Lädt die Daten neu
private void BtnAktualisieren_Click(object sender, RoutedEventArgs e) private void BtnAktualisieren_Click(object sender, RoutedEventArgs e)
{ {
FahrzeugeLaden(); FahrzeugeLaden();
} }
// Tastenkürzel // Tastenkürzel für Aktionen
protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e) protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
{ {
if (e.Key == System.Windows.Input.Key.S && System.Windows.Input.Keyboard.Modifiers == System.Windows.Input.ModifierKeys.Control) if (e.Key == System.Windows.Input.Key.S && System.Windows.Input.Keyboard.Modifiers == System.Windows.Input.ModifierKeys.Control)
@ -284,7 +327,7 @@ namespace FahrzeugVerwaltung
base.OnKeyDown(e); base.OnKeyDown(e);
} }
// Passt Modelle zur Marke an // Zeigt Modelle zur gewählten Marke
private void CmbMarke_AuswahlGeaendert(object sender, SelectionChangedEventArgs e) private void CmbMarke_AuswahlGeaendert(object sender, SelectionChangedEventArgs e)
{ {
if (cmbMarke.SelectedItem == null) if (cmbMarke.SelectedItem == null)
@ -293,7 +336,7 @@ namespace FahrzeugVerwaltung
return; return;
} }
var marke = cmbMarke.SelectedItem.ToString(); string marke = cmbMarke.SelectedItem.ToString();
cmbModell.ItemsSource = _markenModelle[marke]; cmbModell.ItemsSource = _markenModelle[marke];
} }
} }

View File

@ -7,23 +7,24 @@ namespace FahrzeugVerwaltung
{ {
public class PdfService public class PdfService
{ {
// Erstellt ein PDF mit formatierten Daten eines Fahrzeugs // Erstellt ein PDF für ein einzelnes Fahrzeug
public bool ErstelleFahrzeugPdf(Fahrzeug fahrzeug, string dateiPfad) public bool ErstelleFahrzeugPdf(Fahrzeug fahrzeug, string dateiPfad)
{ {
try try
{ {
using var document = new Document(PageSize.A4); using (Document document = new Document(PageSize.A4))
{
PdfWriter.GetInstance(document, new FileStream(dateiPfad, FileMode.Create)); PdfWriter.GetInstance(document, new FileStream(dateiPfad, FileMode.Create));
document.Open(); document.Open();
var titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16); Font titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16);
document.Add(new Paragraph("Fahrzeugdaten", titelSchrift) document.Add(new Paragraph("Fahrzeugdaten", titelSchrift)
{ {
Alignment = Element.ALIGN_CENTER, Alignment = Element.ALIGN_CENTER,
SpacingAfter = 20f SpacingAfter = 20f
}); });
var tabelle = new PdfPTable(2) { WidthPercentage = 80 }; PdfPTable tabelle = new PdfPTable(2) { WidthPercentage = 80 };
tabelle.SetWidths(new float[] { 1f, 2f }); tabelle.SetWidths(new float[] { 1f, 2f });
void Zeile(string text, string wert) void Zeile(string text, string wert)
@ -45,37 +46,39 @@ namespace FahrzeugVerwaltung
document.Close(); document.Close();
return true; return true;
} }
}
catch catch
{ {
return false; return false;
} }
} }
// Erstellt eine übersichtliche Liste aller Fahrzeuge als PDF // Erstellt eine Liste aller Fahrzeuge als PDF
public bool ErstelleFahrzeuglistePdf(List<Fahrzeug> fahrzeuge, string dateiPfad) public bool ErstelleFahrzeuglistePdf(List<Fahrzeug> fahrzeuge, string dateiPfad)
{ {
try try
{ {
using var document = new Document(PageSize.A4.Rotate()); using (Document document = new Document(PageSize.A4.Rotate()))
{
PdfWriter.GetInstance(document, new FileStream(dateiPfad, FileMode.Create)); PdfWriter.GetInstance(document, new FileStream(dateiPfad, FileMode.Create));
document.Open(); document.Open();
var titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16); Font titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16);
document.Add(new Paragraph("Fahrzeugliste", titelSchrift) document.Add(new Paragraph("Fahrzeugliste", titelSchrift)
{ {
Alignment = Element.ALIGN_CENTER, Alignment = Element.ALIGN_CENTER,
SpacingAfter = 20f SpacingAfter = 20f
}); });
var tabelle = new PdfPTable(8) { WidthPercentage = 100 }; PdfPTable tabelle = new PdfPTable(8) { WidthPercentage = 100 };
string[] ueberschriften = { "Marke", "Modell", "Baujahr", "Leistung", "Kilometer", "Kaufpreis", "Farbe", "Aktueller Wert" }; string[] ueberschriften = { "Marke", "Modell", "Baujahr", "Leistung", "Kilometer", "Kaufpreis", "Farbe", "Aktueller Wert" };
foreach (var u in ueberschriften) foreach (string u in ueberschriften)
{ {
tabelle.AddCell(new PdfPCell(new Phrase(u)) { BackgroundColor = BaseColor.LIGHT_GRAY }); tabelle.AddCell(new PdfPCell(new Phrase(u)) { BackgroundColor = BaseColor.LIGHT_GRAY });
} }
foreach (var f in fahrzeuge) foreach (Fahrzeug f in fahrzeuge)
{ {
tabelle.AddCell(f.Marke); tabelle.AddCell(f.Marke);
tabelle.AddCell(f.Modell); tabelle.AddCell(f.Modell);
@ -91,6 +94,7 @@ namespace FahrzeugVerwaltung
document.Close(); document.Close();
return true; return true;
} }
}
catch catch
{ {
return false; return false;