Fehlerbehandlung, Logging und feldbezogene Validierung (Kapitel 13.2)

Zentrale Exception-Behandlung (Dispatcher.UIThread.UnhandledException,
AppDomain, TaskScheduler) verhindert Abstürze und protokolliert Fehler
über AppLogger in eine rotierende Log-Datei im App-Datenverzeichnis.
Toast-Benachrichtigungen zeigen Erfolg/Fehler global an. Alle Dialoge
mit Formularfeldern zeigen Validierungsmeldungen jetzt direkt am
betroffenen Feld statt in einem Sammel-Label.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 12:38:30 +02:00
co-authored by Claude Sonnet 5
parent 273f459119
commit db1afff7e4
27 changed files with 578 additions and 102 deletions
@@ -0,0 +1,51 @@
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
namespace LehrerApp.Desktop.Services;
public enum NotificationKind { Success, Error }
/// <summary>
/// Einheitliche Erfolgs-/Fehlermeldungen als Toast (13.2.3). Wird im MainWindow als
/// Overlay über der aktuellen Seite angezeigt und blendet sich nach kurzer Zeit selbst aus.
/// </summary>
public class NotificationService
{
public ObservableCollection<ToastItem> Toasts { get; } = [];
public void ShowSuccess(string message) => Show(message, NotificationKind.Success, TimeSpan.FromSeconds(3));
public void ShowError(string message) => Show(message, NotificationKind.Error, TimeSpan.FromSeconds(6));
private void Show(string message, NotificationKind kind, TimeSpan duration)
{
void AddAndScheduleRemoval()
{
var toast = new ToastItem(message, kind);
Toasts.Add(toast);
_ = RemoveAfter(toast, duration);
}
if (Dispatcher.UIThread.CheckAccess()) AddAndScheduleRemoval();
else Dispatcher.UIThread.Post(AddAndScheduleRemoval);
}
private async Task RemoveAfter(ToastItem toast, TimeSpan duration)
{
await Task.Delay(duration);
Toasts.Remove(toast);
}
}
public partial class ToastItem : ObservableObject
{
public string Message { get; }
public NotificationKind Kind { get; }
public bool IsError => Kind == NotificationKind.Error;
public ToastItem(string message, NotificationKind kind)
{
Message = message;
Kind = kind;
}
}