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
## Funktionen
- Anmeldung mit Benutzer **admin** und Passwort **admin**
- 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
- Export eines ausgewählten Fahrzeugs als PDF
## Bedienung
1. Marke und Modell aus den Listen wählen
2. Fahrzeugdaten eingeben und **Hinzufügen** drücken
3. Eintrag auswählen und über **Bearbeiten** oder **Löschen** ändern
4. **Aktualisieren** lädt die Liste neu, **Alle anzeigen** setzt Filter zurück
5. **Als PDF speichern** erzeugt ein Informationsblatt
1. Nach dem Start mit den oben genannten Daten anmelden
2. Marke und Modell aus den Listen wählen
3. Fahrzeugdaten eingeben und **Hinzufügen** drücken
4. Eintrag auswählen und über **Bearbeiten** oder **Löschen** ändern
5. **Aktualisieren** lädt die Liste neu, **Alle anzeigen** setzt Filter zurück
6. **Als PDF speichern** erzeugt ein Informationsblatt
## Projektstruktur
- `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.
- **Saad** gestaltete die Oberfläche und implementierte den PDF-Export.
- **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:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
StartupUri="LoginWindow.xaml">
<Application.Resources>
<!-- Globale Styles können hier definiert werden -->
</Application.Resources>
</Application>

View File

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

View File

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

View File

@ -14,44 +14,128 @@ namespace FahrzeugVerwaltung
private decimal _kaufpreis;
private string _farbe;
public int Id { get => _id; set { _id = value; MeldeEigenschaft(nameof(Id)); } }
public string Marke { get => _marke; set { _marke = value; MeldeEigenschaft(nameof(Marke)); } }
public string Modell { get => _modell; set { _modell = value; MeldeEigenschaft(nameof(Modell)); } }
public int Baujahr { get => _baujahr; set { _baujahr = value; MeldeEigenschaft(nameof(Baujahr)); MeldeEigenschaft(nameof(AktuellerWert)); MeldeEigenschaft(nameof(AktuellerWertFormatiert)); } }
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 int Id
{
get { return _id; }
set { _id = value; MeldeEigenschaft(nameof(Id)); }
}
public string KilometerstandFormatiert => $"{Kilometerstand:N0} km";
public string KaufpreisFormatiert => $"{Kaufpreis:C}";
public string AktuellerWertFormatiert => $"{AktuellerWert:C}";
public string Marke
{
get { return _marke; }
set { _marke = value; MeldeEigenschaft(nameof(Marke)); }
}
// Geschätzter aktueller Wert
public decimal AktuellerWert => BerechneAktuellenWert();
public string Modell
{
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()
{
if (Kaufpreis <= 0 || Baujahr <= 0) return 0;
if (Kaufpreis <= 0 || Baujahr <= 0)
{
return 0;
}
int alter = DateTime.Now.Year - Baujahr;
decimal wertverlust = 0;
for (int i = 0; i < alter; i++)
{
wertverlust += (i < 3) ? 0.15m : 0.10m;
}
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 mindestwert = Kaufpreis * 0.05m;
if (wert < mindestwert) wert = mindestwert;
if (wert < mindestwert)
{
wert = mindestwert;
}
return Math.Round(wert, 2);
}
// Beschreibung für Anzeige
// Text für die Oberfläche
public string HoleBeschreibung()
{
return $"{Marke} {Modell} ({Baujahr}) - {Leistung} PS - {KilometerstandFormatiert} - {Farbe}";
@ -71,12 +155,15 @@ namespace FahrzeugVerwaltung
public event PropertyChangedEventHandler PropertyChanged;
// Meldet geänderte Eigenschaft
// Meldet geänderte Eigenschaften
private void MeldeEigenschaft(string 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.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFFFFF" Offset="0"/>
<GradientStop Color="#E3F2FD" Offset="1"/>
<GradientStop Color="#F5F5F5" Offset="0"/>
<GradientStop Color="#E1F5FE" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
@ -67,7 +67,7 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</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">
<Grid Margin="10">
<Grid.RowDefinitions>

View File

@ -22,7 +22,8 @@ namespace FahrzeugVerwaltung
MarkenVorbereiten();
FahrzeugeLaden();
}
// Legt Dienste an
// Erzeugt Dienstobjekte
private void DiensteAnlegen()
{
_datenbankDienst = new DatabaseService();
@ -30,7 +31,7 @@ namespace FahrzeugVerwaltung
_fahrzeuge = new List<Fahrzeug>();
}
// Bereitet Marken und Modelle vor
// Füllt die Listen mit Marken und Modellen
private void MarkenVorbereiten()
{
_markenModelle = new Dictionary<string, List<string>>
@ -64,13 +65,23 @@ namespace FahrzeugVerwaltung
{"Porsche", new List<string>{"911","Cayenne","Panamera","Macan","Taycan","Boxster"}},
{"Citroën", new List<string>{"C1","C3","C4","C5","C3 Aircross","Berlingo"}},
{"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;
}
// Lädt Fahrzeuge aus der Datenbank
// Holt Fahrzeuge aus der Datenbank
private void FahrzeugeLaden()
{
_fahrzeuge = _datenbankDienst.LadeAlleFahrzeuge();
@ -78,22 +89,28 @@ namespace FahrzeugVerwaltung
StatusAktualisieren();
}
// Zeigt Anzahl der Fahrzeuge
// Aktualisiert die Statuszeile
private void StatusAktualisieren()
{
if (_fahrzeuge.Count == 0)
{
txtDetails.Text = "Keine Fahrzeuge vorhanden";
}
else
{
txtDetails.Text = $"{_fahrzeuge.Count} Fahrzeug(e) gefunden";
}
}
// Fügt Fahrzeug hinzu
// Speichert ein neues Fahrzeug
private void BtnHinzufuegen_Click(object sender, RoutedEventArgs e)
{
if (!EingabenPruefen())
{
return;
}
var fahrzeug = new Fahrzeug
Fahrzeug fahrzeug = new Fahrzeug
{
Marke = cmbMarke.SelectedItem.ToString(),
Modell = cmbModell.SelectedItem.ToString(),
@ -110,11 +127,13 @@ namespace FahrzeugVerwaltung
FahrzeugeLaden();
}
// Speichert Änderungen
// Übernimmt Änderungen
private void BtnBearbeiten_Click(object sender, RoutedEventArgs e)
{
if (_ausgewaehltesFahrzeug == null || !EingabenPruefen())
{
return;
}
_ausgewaehltesFahrzeug.Marke = cmbMarke.SelectedItem.ToString();
_ausgewaehltesFahrzeug.Modell = cmbModell.SelectedItem.ToString();
@ -125,15 +144,19 @@ namespace FahrzeugVerwaltung
_ausgewaehltesFahrzeug.Farbe = txtFarbe.Text.Trim();
if (_datenbankDienst.AktualisiereFahrzeug(_ausgewaehltesFahrzeug))
{
MessageBox.Show("Fahrzeug aktualisiert.", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information);
}
FahrzeugeLaden();
}
// Löscht ausgewähltes Fahrzeug
// Entfernt das gewählte Fahrzeug
private void BtnLoeschen_Click(object sender, RoutedEventArgs e)
{
if (_ausgewaehltesFahrzeug == null)
{
return;
}
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()
{
var fehler = new List<string>();
List<string> fehler = new List<string>();
if (cmbMarke.SelectedItem == null)
{
fehler.Add("Marke wählen");
}
if (cmbModell.SelectedItem == null)
{
fehler.Add("Modell wählen");
}
if (!int.TryParse(txtBaujahr.Text, out int baujahr) || baujahr < 1900 || baujahr > DateTime.Now.Year)
{
fehler.Add($"Baujahr zwischen 1900 und {DateTime.Now.Year}");
}
if (!int.TryParse(txtLeistung.Text, out int leistung) || leistung <= 0)
{
fehler.Add("Leistung muss positiv sein");
}
if (!int.TryParse(txtKilometer.Text, out int kilometer) || kilometer < 0)
{
fehler.Add("Kilometerstand muss 0 oder größer sein");
}
if (!decimal.TryParse(txtKaufpreis.Text, out decimal kaufpreis) || kaufpreis <= 0)
{
fehler.Add("Kaufpreis muss positiv sein");
}
if (string.IsNullOrWhiteSpace(txtFarbe.Text))
{
fehler.Add("Farbe angeben");
}
if (fehler.Any())
{
@ -175,7 +212,7 @@ namespace FahrzeugVerwaltung
return true;
}
// Leert Eingaben
// Leert alle Eingabefelder
private void EingabenLeeren()
{
cmbMarke.SelectedIndex = -1;
@ -188,12 +225,14 @@ namespace FahrzeugVerwaltung
cmbMarke.Focus();
}
// Sucht Fahrzeuge
// Sucht nach einem Begriff
private void BtnSuchen_Click(object sender, RoutedEventArgs e)
{
var suchbegriff = txtSuche.Text.Trim();
string suchbegriff = txtSuche.Text.Trim();
if (string.IsNullOrWhiteSpace(suchbegriff))
{
return;
}
_fahrzeuge = _datenbankDienst.SucheFahrzeuge(suchbegriff);
dgFahrzeuge.ItemsSource = _fahrzeuge;
@ -207,7 +246,7 @@ namespace FahrzeugVerwaltung
FahrzeugeLaden();
}
// Reagiert auf Tabellen-Auswahl
// Reagiert auf Auswahl in der Tabelle
private void Liste_AuswahlGeaendert(object sender, SelectionChangedEventArgs e)
{
_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)
{
if (_ausgewaehltesFahrzeug == null)
{
return;
}
var dialog = new SaveFileDialog
SaveFileDialog dialog = new SaveFileDialog
{
Filter = "PDF-Dateien (*.pdf)|*.pdf",
FileName = $"Fahrzeug_{_ausgewaehltesFahrzeug.Marke}_{_ausgewaehltesFahrzeug.Modell}_{DateTime.Now:yyyyMMdd_HHmmss}.pdf"
@ -247,17 +288,19 @@ namespace FahrzeugVerwaltung
if (dialog.ShowDialog() == true)
{
if (_pdfDienst.ErstelleFahrzeugPdf(_ausgewaehltesFahrzeug, dialog.FileName))
{
MessageBox.Show("PDF erstellt.", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
}
// Aktualisiert Liste
// Lädt die Daten neu
private void BtnAktualisieren_Click(object sender, RoutedEventArgs e)
{
FahrzeugeLaden();
}
// Tastenkürzel
// Tastenkürzel für Aktionen
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)
@ -284,7 +327,7 @@ namespace FahrzeugVerwaltung
base.OnKeyDown(e);
}
// Passt Modelle zur Marke an
// Zeigt Modelle zur gewählten Marke
private void CmbMarke_AuswahlGeaendert(object sender, SelectionChangedEventArgs e)
{
if (cmbMarke.SelectedItem == null)
@ -293,7 +336,7 @@ namespace FahrzeugVerwaltung
return;
}
var marke = cmbMarke.SelectedItem.ToString();
string marke = cmbMarke.SelectedItem.ToString();
cmbModell.ItemsSource = _markenModelle[marke];
}
}

View File

@ -7,23 +7,24 @@ namespace FahrzeugVerwaltung
{
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)
{
try
{
using var document = new Document(PageSize.A4);
using (Document document = new Document(PageSize.A4))
{
PdfWriter.GetInstance(document, new FileStream(dateiPfad, FileMode.Create));
document.Open();
var titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16);
Font titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16);
document.Add(new Paragraph("Fahrzeugdaten", titelSchrift)
{
Alignment = Element.ALIGN_CENTER,
SpacingAfter = 20f
});
var tabelle = new PdfPTable(2) { WidthPercentage = 80 };
PdfPTable tabelle = new PdfPTable(2) { WidthPercentage = 80 };
tabelle.SetWidths(new float[] { 1f, 2f });
void Zeile(string text, string wert)
@ -45,37 +46,39 @@ namespace FahrzeugVerwaltung
document.Close();
return true;
}
}
catch
{
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)
{
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));
document.Open();
var titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16);
Font titelSchrift = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16);
document.Add(new Paragraph("Fahrzeugliste", titelSchrift)
{
Alignment = Element.ALIGN_CENTER,
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" };
foreach (var u in ueberschriften)
foreach (string u in ueberschriften)
{
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.Modell);
@ -91,6 +94,7 @@ namespace FahrzeugVerwaltung
document.Close();
return true;
}
}
catch
{
return false;