Compare commits
No commits in common. "5654ed83eaf06d63d1457cc35edac23b44ec9795" and "93b55021123cb742e188ce84e5b1de5dec4d89e7" have entirely different histories.
5654ed83ea
...
93b5502112
@ -48,18 +48,6 @@ namespace Project_Periodensystem.Controller
|
||||
_elements = elements ?? new List<Element>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extrahiert alle Atomgewichte als Array - demonstriert klassische Array-Erstellung
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Array-Initialisierung: new double[size]
|
||||
/// - For-Schleife: Imperative Programmierung
|
||||
/// - Property-Zugriff: element.AtomicWeight
|
||||
///
|
||||
/// ALTERNATIVE (LINQ): return _elements.Select(e => e.AtomicWeight).ToArray();
|
||||
/// Zeigt Unterschied zwischen imperativem und funktionalem Stil
|
||||
/// </summary>
|
||||
/// <returns>Array aller Atomgewichte in g/mol</returns>
|
||||
public double[] GetAtomicWeights()
|
||||
{
|
||||
double[] weights = new double[_elements.Count];
|
||||
@ -70,17 +58,6 @@ namespace Project_Periodensystem.Controller
|
||||
return weights;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet das durchschnittliche Atomgewicht aller Elemente
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Early Return Pattern: if (!_elements.Any()) return 0.0;
|
||||
/// - Method Reuse: Nutzt GetAtomicWeights()
|
||||
/// - Klassische Iteration: for-Schleife für Summe
|
||||
///
|
||||
/// MATHEMATIK: Arithmetisches Mittel = Summe / Anzahl
|
||||
/// </summary>
|
||||
/// <returns>Durchschnittliches Atomgewicht oder 0.0 bei leerer Liste</returns>
|
||||
public double GetAverageAtomicWeight()
|
||||
{
|
||||
if (!_elements.Any()) return 0.0;
|
||||
@ -94,39 +71,15 @@ namespace Project_Periodensystem.Controller
|
||||
return sum / weights.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sammelt alle einzigartigen Element-Serien - demonstriert LINQ-Pipeline
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - LINQ Select(): Projektion (e => e.Series)
|
||||
/// - LINQ Distinct(): Entfernt Duplikate
|
||||
/// - LINQ Where(): Filtert leere/null Werte
|
||||
/// - LINQ OrderBy(): Alphabetische Sortierung
|
||||
/// - Method Chaining: Verkettung mehrerer Operationen
|
||||
///
|
||||
/// RÜCKGABE: Sortierte Liste aller chemischen Serien
|
||||
/// </summary>
|
||||
/// <returns>Liste aller Element-Serien (Alkalimetall, Edelgas, etc.)</returns>
|
||||
public List<string> GetAllSeries()
|
||||
{
|
||||
return _elements.Select(e => e.Series) // Projektion
|
||||
.Distinct() // Duplikate entfernen
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s)) // Null/Empty filtern
|
||||
.OrderBy(s => s) // Alphabetisch sortieren
|
||||
.ToList(); // Zu Liste konvertieren
|
||||
return _elements.Select(e => e.Series)
|
||||
.Distinct()
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.OrderBy(s => s)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sammelt wichtige Statistiken in einem Tuple - demonstriert strukturierte Rückgaben
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Tuple Return Type: (int, int, double)
|
||||
/// - Method Delegation: Ruft andere Methoden auf
|
||||
/// - Tuple Creation: (value1, value2, value3)
|
||||
///
|
||||
/// VERWENDUNG: var (total, series, avg) = statistics.GetStatistics();
|
||||
/// </summary>
|
||||
/// <returns>Tuple mit (Anzahl Elemente, Anzahl Serien, Durchschnittsgewicht)</returns>
|
||||
public (int totalElements, int uniqueSeries, double avgWeight) GetStatistics()
|
||||
{
|
||||
var seriesCount = GetAllSeries().Count;
|
||||
@ -135,18 +88,6 @@ namespace Project_Periodensystem.Controller
|
||||
return (_elements.Count, seriesCount, avgWeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Findet das leichteste und schwerste Element - demonstriert LINQ Ordering
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - LINQ OrderBy() / OrderByDescending(): Sortierung
|
||||
/// - LINQ First(): Erstes Element nach Sortierung
|
||||
/// - Tuple mit nullable Types: (Element?, Element?)
|
||||
/// - Guard Clause: Early return bei leerer Liste
|
||||
///
|
||||
/// CHEMIE: Wasserstoff ist leichtestes (1.008), schwerste variieren
|
||||
/// </summary>
|
||||
/// <returns>Tuple mit (leichtestes Element, schwerstes Element) oder (null, null)</returns>
|
||||
public (Element? lightest, Element? heaviest) GetWeightExtremes()
|
||||
{
|
||||
if (!_elements.Any()) return (null, null);
|
||||
@ -157,18 +98,6 @@ namespace Project_Periodensystem.Controller
|
||||
return (lightest, heaviest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extrahiert Element-Informationen nach Ordnungszahl - demonstriert Tuple-basierte APIs
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - LINQ FirstOrDefault(): Sichere Suche (kann null zurückgeben)
|
||||
/// - Conditional Operator: condition ? trueValue : falseValue
|
||||
/// - Tuple mit Mixed Types: (string, string, double)
|
||||
///
|
||||
/// FALLBACK: Bei nicht gefundenem Element ("?", "Unknown", 0.0)
|
||||
/// </summary>
|
||||
/// <param name="atomicNumber">Ordnungszahl des gesuchten Elements (1-118)</param>
|
||||
/// <returns>Tuple mit (Symbol, Name, Atomgewicht)</returns>
|
||||
public (string symbol, string name, double weight) GetElementInfo(int atomicNumber)
|
||||
{
|
||||
var element = _elements.FirstOrDefault(e => e.AtomicNumber == atomicNumber);
|
||||
@ -177,18 +106,6 @@ namespace Project_Periodensystem.Controller
|
||||
: ("?", "Unknown", 0.0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ermittelt die Position eines Elements im Periodensystem-Grid
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Konsistente API: Gleiche Suchmuster wie GetElementInfo()
|
||||
/// - Tuple für Koordinaten: (int row, int column)
|
||||
/// - Fallback-Werte: (-1, -1) für "nicht gefunden"
|
||||
///
|
||||
/// VERWENDUNG: var (row, col) = statistics.GetElementPosition(1); // Wasserstoff
|
||||
/// </summary>
|
||||
/// <param name="atomicNumber">Ordnungszahl des gesuchten Elements</param>
|
||||
/// <returns>Tuple mit (Zeile, Spalte) oder (-1, -1) wenn nicht gefunden</returns>
|
||||
public (int row, int column) GetElementPosition(int atomicNumber)
|
||||
{
|
||||
var element = _elements.FirstOrDefault(e => e.AtomicNumber == atomicNumber);
|
||||
|
||||
@ -7,21 +7,42 @@ using Project_Periodensystem.Persistence;
|
||||
namespace Project_Periodensystem.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// Haupt-Controller für das Periodensystem - implementiert MVC-Pattern.
|
||||
/// Koordiniert Geschäftslogik zwischen View und Model/Persistence.
|
||||
/// Delegiert komplexe Aufgaben an spezialisierte Helper-Klassen.
|
||||
/// Haupt-Controller für das Periodensystem - implementiert das MVC-Pattern
|
||||
///
|
||||
/// ZWECK UND ARCHITEKTUR:
|
||||
/// - Zentrale Kontrollschicht zwischen View (UI) und Model/Persistence (Daten)
|
||||
/// - Koordiniert alle Geschäftslogik-Operationen für das Periodensystem
|
||||
/// - Delegiert komplexe Aufgaben an spezialisierte Helper-Klassen (Single Responsibility Principle)
|
||||
/// - Bietet eine einheitliche API für alle UI-Komponenten
|
||||
///
|
||||
/// DESIGN PATTERN:
|
||||
/// - MVC (Model-View-Controller): Trennt Präsentation von Geschäftslogik
|
||||
/// - Delegation Pattern: Überträgt Verantwortlichkeiten an spezialisierte Klassen
|
||||
/// - Dependency Injection: Nimmt INavigationService als abhängige Komponente entgegen
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Nullable Reference Types (INavigationService?, ElementValidator?)
|
||||
/// - LINQ für Datenoperationen (FirstOrDefault, Where, ToArray)
|
||||
/// - Exception Handling mit try-catch-Blöcken
|
||||
/// - Lambda Expressions für Delegation an Helper-Klassen
|
||||
/// - Tuple-Rückgabewerte für strukturierte Daten
|
||||
/// </summary>
|
||||
public class PeriodensystemController
|
||||
{
|
||||
// ===== PRIVATE FELDER =====
|
||||
|
||||
/// <summary>
|
||||
/// Liste aller chemischen Elemente
|
||||
/// Zentrale Liste aller chemischen Elemente
|
||||
/// List<T> ermöglicht dynamisches Hinzufügen/Entfernen von Elementen
|
||||
/// Private Field mit Underscore-Notation (_elements) nach C#-Konvention
|
||||
/// </summary>
|
||||
private List<Element> _elements = new List<Element>();
|
||||
|
||||
/// <summary>
|
||||
/// Navigation Service für Seitenwechsel (optional, da Interface-basiert)
|
||||
/// Navigation Service für Seitenwechsel in der Avalonia-Anwendung
|
||||
/// Readonly: Kann nur im Konstruktor zugewiesen werden (Immutability)
|
||||
/// Nullable (?): Kann null sein, da Navigation optional ist
|
||||
/// Interface-basiert: Ermöglicht verschiedene Implementierungen (Dependency Inversion)
|
||||
/// </summary>
|
||||
private readonly INavigationService? _navigationService;
|
||||
|
||||
@ -42,8 +63,22 @@ namespace Project_Periodensystem.Controller
|
||||
private ElementStatistics? _statistics;
|
||||
|
||||
// ===== KONSTRUKTOR =====
|
||||
|
||||
/// <summary>
|
||||
/// Konstruktor mit optionaler Navigation
|
||||
/// Konstruktor mit optionaler Dependency Injection
|
||||
///
|
||||
/// PARAMETER:
|
||||
/// - navigationService: Optional (null by default), ermöglicht Navigation zwischen Seiten
|
||||
///
|
||||
/// C# FEATURES:
|
||||
/// - Default Parameter (= null): Macht den Parameter optional
|
||||
/// - Nullable Reference Types: navigationService kann null sein
|
||||
/// - Constructor Chaining: Ruft LoadElements() zur Initialisierung auf
|
||||
///
|
||||
/// ABLAUF:
|
||||
/// 1. Navigation Service speichern (kann null sein)
|
||||
/// 2. Elemente aus Persistence-Layer laden
|
||||
/// 3. Helper-Klassen mit geladenen Daten initialisieren
|
||||
/// </summary>
|
||||
public PeriodensystemController(INavigationService? navigationService = null)
|
||||
{
|
||||
@ -51,28 +86,52 @@ namespace Project_Periodensystem.Controller
|
||||
LoadElements(); // Daten sofort beim Erstellen laden
|
||||
}
|
||||
|
||||
// ===== PRIVATE INITIALISIERUNGSMETHODEN =====
|
||||
|
||||
/// <summary>
|
||||
/// Lädt alle chemischen Elemente und initialisiert Helper-Klassen
|
||||
/// Lädt alle chemischen Elemente aus dem Persistence-Layer
|
||||
///
|
||||
/// ZWECK:
|
||||
/// - Zentrale Initialisierung aller Elementdaten
|
||||
/// - Fehlerbehandlung beim Laden der Daten
|
||||
/// - Initialisierung der Helper-Klassen nach erfolgreichem Laden
|
||||
/// - Ausführliches Logging für Debugging und Monitoring
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Exception Handling: try-catch für robuste Fehlerbehandlung
|
||||
/// - LINQ: Take(10) für die ersten 10 Elemente
|
||||
/// - Tuple Deconstruction: (totalElements, uniqueSeries, avgWeight) = GetStatistics()
|
||||
/// - Null-Conditional Operator: lightest?.Symbol verhindert NullReferenceException
|
||||
/// - String Interpolation: $"Text {variable}" für lesbare Ausgaben
|
||||
///
|
||||
/// FEHLERBEHANDLUNG:
|
||||
/// - Bei Exceptions wird eine leere Liste initialisiert (Graceful Degradation)
|
||||
/// - Alle Fehler werden geloggt für spätere Analyse
|
||||
/// </summary>
|
||||
private void LoadElements()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Elemente aus DataManager laden
|
||||
// Elemente aus DataManager laden (Persistence Layer)
|
||||
_elements = DataManager.LoadElements();
|
||||
Logger.Log($"Controller: {_elements.Count} Elemente erfolgreich geladen");
|
||||
Logger.Log($"Controller: {_elements.Count} Elemente erfolgreich geladen (via DataManager)");
|
||||
|
||||
// Helper-Klassen initialisieren
|
||||
// Helper-Klassen mit den geladenen Daten initialisieren
|
||||
// Delegation Pattern: Spezialisierte Klassen für verschiedene Aufgaben
|
||||
_validator = new ElementValidator(_elements);
|
||||
_statistics = new ElementStatistics(_elements);
|
||||
|
||||
// Demonstrative Logging der geladenen Daten
|
||||
// ===== DEMONSTRATIVE LOGGING VON C#-FEATURES =====
|
||||
|
||||
// Arrays: Alle Element-Symbole als Array
|
||||
var symbols = GetAllSymbols();
|
||||
Logger.LogArray("Element-Symbole (erste 10)", symbols.Take(10).ToArray());
|
||||
|
||||
// Tuples: Strukturierte Rückgabe mehrerer Werte
|
||||
var (totalElements, uniqueSeries, avgWeight) = GetStatistics();
|
||||
Logger.LogTuple("Statistiken", $"Elemente: {totalElements}, Serien: {uniqueSeries}, Ø-Gewicht: {avgWeight:F2}");
|
||||
|
||||
// Tuples mit Objekten: Extremwerte finden
|
||||
var (lightest, heaviest) = GetWeightExtremes();
|
||||
if (lightest != null && heaviest != null)
|
||||
{
|
||||
|
||||
@ -1,25 +1,76 @@
|
||||
namespace Project_Periodensystem.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Repräsentiert ein chemisches Element im Periodensystem.
|
||||
/// Zentrale Datenstruktur für alle Elementinformationen und -eigenschaften.
|
||||
/// Repräsentiert ein chemisches Element im Periodensystem
|
||||
///
|
||||
/// ZWECK UND DATENMODELL:
|
||||
/// - Zentrale Datenstruktur für alle Elementinformationen
|
||||
/// - Kapselt alle relevanten chemischen Eigenschaften
|
||||
/// - Bildet die Grundlage für Periodensystem-Darstellung und -Berechnungen
|
||||
///
|
||||
/// DESIGN PRINCIPLES:
|
||||
/// - Data Transfer Object (DTO): Reine Datenklasse ohne Geschäftslogik
|
||||
/// - Immutable nach Konstruktion: Alle Properties haben nur Setter (könnten readonly sein)
|
||||
/// - Rich Object: Enthält alle relevanten Eigenschaften in einer Klasse
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Auto-Properties: { get; set; } automatische Getter/Setter
|
||||
/// - Constructor mit mehreren Parametern: Vollständige Initialisierung
|
||||
/// - Value Types (int, double): Primitive Datentypen für Zahlen
|
||||
/// - Reference Types (string): Referenzdatentypen für Text
|
||||
///
|
||||
/// VERWENDUNG IM PERIODENSYSTEM:
|
||||
/// - Gespeichert in List<Element> Collections
|
||||
/// - Sortiert nach AtomicNumber für Periodensystem-Darstellung
|
||||
/// - Gruppiert nach Series für chemische Klassifizierung
|
||||
/// - Positioniert nach Row/Column im UI-Grid
|
||||
/// </summary>
|
||||
public class Element
|
||||
{
|
||||
// ===== IDENTIFIKATIONS-EIGENSCHAFTEN =====
|
||||
|
||||
/// <summary>
|
||||
/// Ordnungszahl (Protonenzahl) des Elements - eindeutige Identifikation (1-118)
|
||||
/// Ordnungszahl (Protonenzahl) des Elements
|
||||
///
|
||||
/// CHEMISCHE BEDEUTUNG:
|
||||
/// - Eindeutige Identifikation jedes Elements (1-118)
|
||||
/// - Bestimmt Position im Periodensystem
|
||||
/// - Entspricht der Anzahl Protonen im Atomkern
|
||||
///
|
||||
/// BEISPIELE:
|
||||
/// - 1 = Wasserstoff (H)
|
||||
/// - 6 = Kohlenstoff (C)
|
||||
/// - 79 = Gold (Au)
|
||||
/// </summary>
|
||||
public int AtomicNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Chemisches Symbol (z.B. H, C, Au) - kurze Bezeichnung (1-2 Buchstaben)
|
||||
/// Chemisches Symbol (Kurzbezeichnung) des Elements
|
||||
///
|
||||
/// KONVENTIONEN:
|
||||
/// - 1-2 Buchstaben, erster Buchstabe groß
|
||||
/// - Oft lateinischen/griechischen Ursprungs
|
||||
/// - International standardisiert (IUPAC)
|
||||
///
|
||||
/// BEISPIELE:
|
||||
/// - "H" = Hydrogen (Wasserstoff)
|
||||
/// - "Au" = Aurum (Gold)
|
||||
/// - "Fe" = Ferrum (Eisen)
|
||||
/// </summary>
|
||||
public string Symbol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vollständiger wissenschaftlicher Name des Elements
|
||||
///
|
||||
/// NAMENSGEBUNG:
|
||||
/// - Offizielle IUPAC-Bezeichnung
|
||||
/// - Meist englische Namen in der internationalen Wissenschaft
|
||||
/// - Historische, mythologische oder wissenschaftliche Herkunft
|
||||
///
|
||||
/// BEISPIELE:
|
||||
/// - "Hydrogen" (griechisch: Wasser-bildend)
|
||||
/// - "Californium" (nach Kalifornien benannt)
|
||||
/// - "Einsteinium" (nach Albert Einstein)
|
||||
/// </summary>
|
||||
public string ElementName { get; set; }
|
||||
|
||||
@ -27,62 +78,154 @@ namespace Project_Periodensystem.Model
|
||||
|
||||
/// <summary>
|
||||
/// Relative Atommasse in atomaren Masseneinheiten (u)
|
||||
///
|
||||
/// CHEMISCHE BEDEUTUNG:
|
||||
/// - Durchschnittliche Masse aller Isotope eines Elements
|
||||
/// - Gewichtet nach natürlicher Häufigkeit der Isotope
|
||||
/// - Basis für stöchiometrische Berechnungen
|
||||
///
|
||||
/// EINHEIT: u (atomic mass unit)
|
||||
/// - 1 u ≈ 1.66054 × 10⁻²⁷ kg
|
||||
/// - Relative Skala (Kohlenstoff-12 = 12.000 u)
|
||||
///
|
||||
/// BEISPIELE:
|
||||
/// - Wasserstoff: ~1.008 u
|
||||
/// - Kohlenstoff: ~12.011 u
|
||||
/// - Uran: ~238.029 u
|
||||
/// </summary>
|
||||
public double AtomicWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Elektronegativität nach Pauling-Skala (0.7 bis 4.0)
|
||||
/// Elektronegativität nach Pauling-Skala
|
||||
///
|
||||
/// CHEMISCHE BEDEUTUNG:
|
||||
/// - Fähigkeit eines Atoms, Bindungselektronen anzuziehen
|
||||
/// - Bestimmt Art der chemischen Bindung (ionisch vs. kovalent)
|
||||
/// - Wichtig für Vorhersage chemischer Reaktionen
|
||||
///
|
||||
/// PAULING-SKALA:
|
||||
/// - Dimensionslose Größe von 0.7 bis 4.0
|
||||
/// - Fluor hat den höchsten Wert (4.0)
|
||||
/// - Trends: Steigt in Perioden von links nach rechts
|
||||
///
|
||||
/// BEISPIELE:
|
||||
/// - Fluor: 4.0 (höchste Elektronegativität)
|
||||
/// - Sauerstoff: 3.5
|
||||
/// - Wasserstoff: 2.1
|
||||
/// - Cäsium: 0.7 (niedrigste)
|
||||
/// </summary>
|
||||
public double Electronegativity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dichte bei Standardbedingungen in g/cm³
|
||||
///
|
||||
/// PHYSIKALISCHE BEDEUTUNG:
|
||||
/// - Masse pro Volumeneinheit
|
||||
/// - Abhängig von Atomgröße und Kristallstruktur
|
||||
/// - Wichtig für technische Anwendungen
|
||||
///
|
||||
/// TRENDS IM PERIODENSYSTEM:
|
||||
/// - Generell zunehmend mit steigender Ordnungszahl
|
||||
/// - Maximum bei Osmium (~22.6 g/cm³)
|
||||
/// - Gase haben sehr geringe Dichten
|
||||
///
|
||||
/// BEISPIELE:
|
||||
/// - Wasserstoff (Gas): ~0.0000899 g/cm³
|
||||
/// - Wasser (Referenz): 1.0 g/cm³
|
||||
/// - Gold: ~19.3 g/cm³
|
||||
/// - Osmium: ~22.6 g/cm³ (dichtestes Element)
|
||||
/// </summary>
|
||||
public double Density { get; set; }
|
||||
|
||||
// ===== KLASSIFIKATIONS-EIGENSCHAFTEN =====
|
||||
|
||||
/// <summary>
|
||||
/// Chemische Serie/Gruppe für Klassifikation und UI-Farbkodierung
|
||||
/// Chemische Serie/Gruppe des Elements
|
||||
///
|
||||
/// KLASSIFIKATION:
|
||||
/// - Gruppiert Elemente nach ähnlichen chemischen Eigenschaften
|
||||
/// - Basis für Periodensystem-Farben und -Organisation
|
||||
/// - Ermöglicht Vorhersage chemischen Verhaltens
|
||||
///
|
||||
/// WICHTIGE SERIEN:
|
||||
/// - "Alkali metal": Li, Na, K, Rb, Cs, Fr (sehr reaktiv)
|
||||
/// - "Noble gas": He, Ne, Ar, Kr, Xe, Rn (inert)
|
||||
/// - "Halogen": F, Cl, Br, I, At (7 Valenzelektronen)
|
||||
/// - "Transition metal": Fe, Cu, Au, etc. (d-Block)
|
||||
/// - "Lanthanoid": Seltene Erden (f-Block)
|
||||
///
|
||||
/// UI-VERWENDUNG:
|
||||
/// - Farbkodierung im Periodensystem
|
||||
/// - Filterung und Gruppierung
|
||||
/// - Tooltip-Informationen
|
||||
/// </summary>
|
||||
public string Series { get; set; }
|
||||
|
||||
// ===== POSITIONIERUNGS-EIGENSCHAFTEN =====
|
||||
|
||||
/// <summary>
|
||||
/// Zeile (Periode) im Periodensystem (1-7)
|
||||
/// Zeile (Periode) im Periodensystem
|
||||
///
|
||||
/// CHEMISCHE BEDEUTUNG:
|
||||
/// - Entspricht der Anzahl Elektronenschalen
|
||||
/// - Bestimmt vertikale Position im Periodensystem
|
||||
/// - 1-7 für natürliche Elemente
|
||||
///
|
||||
/// TRENDS:
|
||||
/// - Atomradius nimmt innerhalb einer Periode ab
|
||||
/// - Ionisierungsenergie steigt innerhalb einer Periode
|
||||
/// </summary>
|
||||
public int Row { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Spalte (Gruppe) im Periodensystem (1-18)
|
||||
/// Spalte (Gruppe) im Periodensystem
|
||||
///
|
||||
/// CHEMISCHE BEDEUTUNG:
|
||||
/// - Entspricht der Anzahl Valenzelektronen (vereinfacht)
|
||||
/// - Bestimmt horizontale Position im Periodensystem
|
||||
/// - 1-18 nach IUPAC-Nummerierung
|
||||
///
|
||||
/// TRENDS:
|
||||
/// - Elemente derselben Gruppe haben ähnliche Eigenschaften
|
||||
/// - Chemische Reaktivität folgt Gruppenmustern
|
||||
/// </summary>
|
||||
public int Column { get; set; }
|
||||
|
||||
// ===== KONSTRUKTOR =====
|
||||
|
||||
/// <summary>
|
||||
/// Konstruktor - erstellt Element-Objekt mit allen erforderlichen Eigenschaften
|
||||
/// Vollständiger Konstruktor für die Erstellung eines Element-Objekts
|
||||
///
|
||||
/// ZWECK:
|
||||
/// - Stellt sicher, dass alle Eigenschaften beim Erstellen gesetzt werden
|
||||
/// - Verhindert unvollständig initialisierte Element-Objekte
|
||||
/// - Ermöglicht direkte Erstellung aus Datenquellen (CSV, JSON, Database)
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Constructor Overloading: Könnte mehrere Konstruktoren haben
|
||||
/// - Parameter Validation: Könnte Validierung der Eingabewerte enthalten
|
||||
/// - Immutable Object: Nach Konstruktion unveränderlich (wenn Properties readonly wären)
|
||||
///
|
||||
/// PARAMETER:
|
||||
/// - Alle 9 Eigenschaften müssen beim Erstellen angegeben werden
|
||||
/// - Reihenfolge entspricht logischer Gruppierung (ID, Name, Physik, Position)
|
||||
///
|
||||
/// VERWENDUNG:
|
||||
/// var hydrogen = new Element(1, "H", "Hydrogen", 1.008, 2.1, 0.0000899, "Nonmetal", 1, 1);
|
||||
/// </summary>
|
||||
/// <param name="atomicNumber">Ordnungszahl (1-118)</param>
|
||||
/// <param name="symbol">Chemisches Symbol (z.B. "H", "Au")</param>
|
||||
/// <param name="elementname">Vollständiger Elementname</param>
|
||||
/// <param name="atomicWeight">Atommasse in u</param>
|
||||
/// <param name="electronegativity">Elektronegativität (Pauling-Skala)</param>
|
||||
/// <param name="density">Dichte in g/cm³</param>
|
||||
/// <param name="series">Chemische Serie/Gruppe</param>
|
||||
/// <param name="row">Periodensystem-Zeile</param>
|
||||
/// <param name="column">Periodensystem-Spalte</param>
|
||||
public Element(int atomicNumber, string symbol, string elementname, double atomicWeight,
|
||||
double electronegativity, double density, string series, int row, int column)
|
||||
{
|
||||
AtomicNumber = atomicNumber;
|
||||
Symbol = symbol;
|
||||
ElementName = elementname;
|
||||
AtomicWeight = atomicWeight;
|
||||
Electronegativity = electronegativity;
|
||||
Density = density;
|
||||
Series = series;
|
||||
Row = row;
|
||||
Column = column;
|
||||
// Eigenschafts-Zuweisungen mit Selbst-Dokumentation
|
||||
AtomicNumber = atomicNumber; // Eindeutige Identifikation
|
||||
Symbol = symbol; // Kurze chemische Bezeichnung
|
||||
ElementName = elementname; // Vollständiger Name
|
||||
AtomicWeight = atomicWeight; // Relative Atommasse
|
||||
Electronegativity = electronegativity; // Bindungsverhalten
|
||||
Density = density; // Physikalische Eigenschaft
|
||||
Series = series; // Chemische Klassifikation
|
||||
Row = row; // Periodensystem-Position vertikal
|
||||
Column = column; // Periodensystem-Position horizontal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,43 +6,26 @@ using Project_Periodensystem.Controller;
|
||||
namespace Project_Periodensystem.View
|
||||
{
|
||||
/// <summary>
|
||||
/// Hauptfenster der Avalonia-Anwendung - implementiert MVC-Pattern.
|
||||
/// Koordiniert NavigationService und PeriodensystemController.
|
||||
/// Löst zirkuläre Abhängigkeiten durch zweistufige Initialisierung.
|
||||
/// MainWindow mit sauberem MVC-Pattern und Interface-basierter Navigation
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Hauptbereich für Seitenwechsel zwischen PeriodicTablePage, AboutPage, etc.
|
||||
/// </summary>
|
||||
private ContentControl? mainContent;
|
||||
|
||||
/// <summary>
|
||||
/// Zentrale Geschäftslogik für Periodensystem-Daten und -Operationen
|
||||
/// </summary>
|
||||
private readonly PeriodensystemController _dataController;
|
||||
|
||||
/// <summary>
|
||||
/// Service für Navigation zwischen verschiedenen Anwendungsseiten
|
||||
/// </summary>
|
||||
private readonly NavigationService _navigationService;
|
||||
|
||||
/// <summary>
|
||||
/// Konstruktor - initialisiert Avalonia-Komponenten und MVC-Architektur
|
||||
/// </summary>
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent(); // Avalonia UI initialisieren
|
||||
InitializeComponent();
|
||||
mainContent = this.FindControl<ContentControl>("MainContent");
|
||||
|
||||
// Zweistufige Initialisierung wegen zirkulärer Abhängigkeiten:
|
||||
// 1. NavigationService mit MainWindow erstellen
|
||||
// Erstelle Navigation Service mit this (MainWindow)
|
||||
_navigationService = new NavigationService(this);
|
||||
|
||||
// 2. Controller mit NavigationService erstellen
|
||||
// Controller mit Navigation Service initialisieren (Dependency Injection)
|
||||
_dataController = new PeriodensystemController(_navigationService);
|
||||
|
||||
// 3. Controller an NavigationService zurückgeben (löst Zirkularität)
|
||||
// Data Controller an Navigation Service setzen
|
||||
_navigationService.SetDataController(_dataController);
|
||||
|
||||
// Landing Page anzeigen
|
||||
|
||||
@ -8,48 +8,130 @@ using Project_Periodensystem.Controller;
|
||||
namespace Project_Periodensystem.View
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementiert die Navigation zwischen verschiedenen Seiten der Avalonia-Anwendung.
|
||||
/// Trennt die Navigation-Logik (WAS) vom UI-Framework (WIE) durch Interface-Implementation.
|
||||
/// Löst zirkuläre Abhängigkeiten durch zweistufige Initialisierung.
|
||||
/// Concrete Implementation des Navigation Service für Avalonia UI
|
||||
///
|
||||
/// ZWECK UND ARCHITEKTUR:
|
||||
/// - Implementiert INavigationService Interface aus dem Controller-Layer
|
||||
/// - Trennt sauber "WAS navigiert wird" (Controller) von "WIE navigiert wird" (View)
|
||||
/// - Kapselt alle Avalonia-spezifische Navigation-Logik
|
||||
/// - Ermöglicht verschiedene UI-Frameworks ohne Controller-Änderungen
|
||||
///
|
||||
/// DESIGN PATTERNS:
|
||||
/// - Interface Implementation: Konkrete Umsetzung der abstrakten Navigation
|
||||
/// - Dependency Injection: MainWindow wird von außen injiziert
|
||||
/// - Facade Pattern: Vereinfacht komplexe UI-Navigation für Controller
|
||||
/// - Bridge Pattern: Verbindet Controller (Abstraktion) mit View (Implementation)
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Interface Implementation: public class NavigationService : INavigationService
|
||||
/// - Constructor Injection: MainWindow als Dependency
|
||||
/// - Null-Conditional Checks: Robuste Parameter-Validierung
|
||||
/// - Exception Handling: Try-Catch für alle UI-Operationen
|
||||
/// - Method Delegation: Weiterleitung von Interface-Aufrufen an UI-Code
|
||||
///
|
||||
/// AVALONIA-INTEGRATION:
|
||||
/// - MainWindow.Content: Zentrale Inhaltsbereich für Page-Wechsel
|
||||
/// - UserControl-basierte Pages: PeriodicTablePage, AboutPage, LandingPage
|
||||
/// - Theme-Management: Avalonia Application Resources
|
||||
/// - Application.Current: Globaler Zugriff auf App-Instance
|
||||
///
|
||||
/// ZIRKULÄRE ABHÄNGIGKEITEN:
|
||||
/// - Problem: Controller braucht NavigationService, NavigationService braucht Controller
|
||||
/// - Lösung: Zweistufige Initialisierung mit SetDataController()
|
||||
/// - Constructor nimmt MainWindow, SetDataController() löst Zirkularität auf
|
||||
/// </summary>
|
||||
public class NavigationService : INavigationService
|
||||
{
|
||||
// ===== PRIVATE FELDER =====
|
||||
|
||||
/// <summary>
|
||||
/// Referenz zum Hauptfenster für Navigation zwischen Seiten
|
||||
/// Referenz zum Hauptfenster der Avalonia-Anwendung
|
||||
///
|
||||
/// ZWECK:
|
||||
/// - Zentrale Kontrolle über den Hauptinhaltsbereich
|
||||
/// - Zugriff auf MainWindow.Content für Page-Wechsel
|
||||
/// - Window-Eigenschaften (Titel, Größe, etc.) ändern
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Readonly Field: Kann nur im Konstruktor gesetzt werden
|
||||
/// - Reference Type: Hält Verweis auf MainWindow-Objekt
|
||||
/// - Encapsulation: Private field mit controlled access
|
||||
/// </summary>
|
||||
private readonly MainWindow _mainWindow;
|
||||
|
||||
/// <summary>
|
||||
/// Data Controller für Datenzugriff (wird nach Konstruktion gesetzt)
|
||||
/// Referenz zum Data Controller (für Daten-Zugriff)
|
||||
///
|
||||
/// ZWECK:
|
||||
/// - Navigation-Pages benötigen Zugriff auf Element-Daten
|
||||
/// - Vermeidung direkter Model/Persistence-Zugriffe aus View
|
||||
/// - Konsistente Daten-API für alle UI-Komponenten
|
||||
///
|
||||
/// ZIRKULÄRE ABHÄNGIGKEIT:
|
||||
/// - Controller erstellt NavigationService
|
||||
/// - NavigationService braucht Controller für Daten
|
||||
/// - Lösung: Nullable field + SetDataController() nach Konstruktion
|
||||
/// </summary>
|
||||
private PeriodensystemController? _dataController;
|
||||
|
||||
// ===== KONSTRUKTOR UND INITIALISIERUNG =====
|
||||
|
||||
/// <summary>
|
||||
/// Initialisiert den NavigationService mit dem Hauptfenster
|
||||
/// Konstruktor mit Dependency Injection des MainWindow
|
||||
///
|
||||
/// ZWECK:
|
||||
/// - Initialisiert Navigation Service mit UI-Kontext
|
||||
/// - Stellt sicher, dass MainWindow verfügbar ist
|
||||
/// - Validiert kritische Dependencies
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Constructor Dependency Injection: MainWindow als Parameter
|
||||
/// - ArgumentNullException: Robuste Parameter-Validierung
|
||||
/// - Null-Coalescing Throw: mainWindow ?? throw new ArgumentNullException()
|
||||
/// - Self-Documenting Code: Logging der Initialisierung
|
||||
///
|
||||
/// PARAMETER-VALIDIERUNG:
|
||||
/// - Null-Check mit Exception: Verhindert spätere NullReferenceExceptions
|
||||
/// - Early Fail Principle: Probleme sofort erkennbar
|
||||
/// - Descriptive Exception: nameof() für präzise Fehlermeldung
|
||||
/// </summary>
|
||||
/// <param name="mainWindow">Das Hauptfenster der Avalonia-Anwendung</param>
|
||||
/// <exception cref="ArgumentNullException">Wenn mainWindow null ist</exception>
|
||||
public NavigationService(MainWindow mainWindow)
|
||||
{
|
||||
_mainWindow = mainWindow ?? throw new ArgumentNullException(nameof(mainWindow));
|
||||
Logger.Log("NavigationService initialisiert");
|
||||
Logger.Log("NavigationService initialisiert - implementiert Interface-basierte Navigation");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setzt den Data Controller nach der Konstruktion (löst zirkuläre Abhängigkeit)
|
||||
///
|
||||
/// ZWECK:
|
||||
/// - Zweistufige Initialisierung zur Auflösung zirkulärer Dependencies
|
||||
/// - Ermöglicht Controller-Access für datenabhängige Navigation
|
||||
/// - Trennt UI-Initialisierung von Daten-Initialisierung
|
||||
///
|
||||
/// ZIRKULÄRES ABHÄNGIGKEITS-PROBLEM:
|
||||
/// 1. MainWindow erstellt PeriodensystemController
|
||||
/// 2. Controller braucht NavigationService (this)
|
||||
/// 3. NavigationService braucht Controller für Daten
|
||||
/// 4. Lösung: Controller nach NavigationService-Konstruktion setzen
|
||||
///
|
||||
/// C# KONZEPTE:
|
||||
/// - Two-Phase Construction: Konstruktor + Setter für komplexe Dependencies
|
||||
/// - Null-Conditional Assignment: _dataController wird aus null zu gültigem Objekt
|
||||
/// - Method Chaining möglich: SetDataController() könnte 'this' zurückgeben
|
||||
/// </summary>
|
||||
/// <param name="dataController">Der PeriodensystemController für Datenzugriff</param>
|
||||
/// <exception cref="ArgumentNullException">Wenn dataController null ist</exception>
|
||||
public void SetDataController(PeriodensystemController dataController)
|
||||
{
|
||||
_dataController = dataController ?? throw new ArgumentNullException(nameof(dataController));
|
||||
Logger.Log("DataController in NavigationService gesetzt");
|
||||
Logger.Log("DataController in NavigationService gesetzt - zirkuläre Abhängigkeit aufgelöst");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigation zum Periodensystem - zeigt PeriodicTablePage im MainContent an
|
||||
/// Navigation zum Periodensystem (Interface Implementation)
|
||||
/// </summary>
|
||||
public void NavigateToPeriodicTable()
|
||||
{
|
||||
@ -61,11 +143,9 @@ namespace Project_Periodensystem.View
|
||||
return;
|
||||
}
|
||||
|
||||
// PeriodicTablePage erstellen und Controller setzen
|
||||
var periodicTablePage = new PeriodicTablePage();
|
||||
periodicTablePage.SetController(_dataController);
|
||||
|
||||
// MainContent Control finden und neue Seite anzeigen
|
||||
var mainContent = _mainWindow.FindControl<ContentControl>("MainContent");
|
||||
if (mainContent != null)
|
||||
{
|
||||
@ -84,7 +164,7 @@ namespace Project_Periodensystem.View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigation zur About-Seite - zeigt Projektinformationen und Credits
|
||||
/// Navigation zur About-Seite (Interface Implementation)
|
||||
/// </summary>
|
||||
public void NavigateToAbout()
|
||||
{
|
||||
@ -96,11 +176,9 @@ namespace Project_Periodensystem.View
|
||||
return;
|
||||
}
|
||||
|
||||
// AboutPage erstellen und Controller setzen
|
||||
var aboutPage = new AboutPage();
|
||||
aboutPage.SetController(_dataController);
|
||||
|
||||
// MainContent Control finden und neue Seite anzeigen
|
||||
var mainContent = _mainWindow.FindControl<ContentControl>("MainContent");
|
||||
if (mainContent != null)
|
||||
{
|
||||
@ -119,7 +197,7 @@ namespace Project_Periodensystem.View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigation zur Landing Page - Startseite der Anwendung
|
||||
/// Navigation zur Landing Page (Interface Implementation)
|
||||
/// </summary>
|
||||
public void NavigateToLanding()
|
||||
{
|
||||
@ -131,11 +209,9 @@ namespace Project_Periodensystem.View
|
||||
return;
|
||||
}
|
||||
|
||||
// LandingPage erstellen und Controller setzen
|
||||
var landingPage = new LandingPage();
|
||||
landingPage.SetController(_dataController);
|
||||
|
||||
// MainContent Control finden und neue Seite anzeigen
|
||||
var mainContent = _mainWindow.FindControl<ContentControl>("MainContent");
|
||||
if (mainContent != null)
|
||||
{
|
||||
@ -154,7 +230,7 @@ namespace Project_Periodensystem.View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wechselt zwischen Dark- und Light-Theme der Avalonia-Anwendung
|
||||
/// Theme-Wechsel (Interface Implementation)
|
||||
/// </summary>
|
||||
public void ToggleTheme()
|
||||
{
|
||||
@ -163,16 +239,14 @@ namespace Project_Periodensystem.View
|
||||
var app = Application.Current;
|
||||
if (app != null)
|
||||
{
|
||||
// Aktuelles Theme ermitteln und umschalten
|
||||
var currentTheme = app.ActualThemeVariant;
|
||||
var newTheme = currentTheme == Avalonia.Styling.ThemeVariant.Dark
|
||||
? Avalonia.Styling.ThemeVariant.Light
|
||||
: Avalonia.Styling.ThemeVariant.Dark;
|
||||
|
||||
// Neues Theme anwenden
|
||||
app.RequestedThemeVariant = newTheme;
|
||||
|
||||
// Theme-Einstellung persistent speichern
|
||||
// Settings speichern
|
||||
var settings = new AppSettings
|
||||
{
|
||||
LastTheme = newTheme.ToString() ?? "Dark",
|
||||
@ -191,14 +265,14 @@ namespace Project_Periodensystem.View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Zeigt eine Export-Bestätigung an (aktuell nur Logging)
|
||||
/// Export-Bestätigung anzeigen (Interface Implementation)
|
||||
/// </summary>
|
||||
public void ShowExportConfirmation()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Log("NavigationService: Export-Bestätigung angezeigt");
|
||||
// TODO: Hier könnte ein Dialog oder Notification angezeigt werden
|
||||
// Hier könnte ein Dialog oder Notification angezeigt werden
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user