Klausurauswertung (1.5) — Kapitel 1 damit vollständig

Neuer Dialog ExamEvaluationDialog, erreichbar über "Auswertung" im
Klausuren-Tab (Button + Kontextmenü bei ausgewählter Klausur):

- Notenspiegel als Balkendiagramm, Durchschnitt (via bestehendes
  GradingService.WeightedAverage), Median, sowie ein Schwellenwert-
  Anteil ("< 5/4 Punkte" bei Punktesystem, "nicht ausreichend 5/6"
  bei Notensystem 1–6).
- Aufgabenanalyse: durchschnittlicher Erfüllungsgrad je Aufgabe,
  auffällig schwache (Ø < 50 %) rot markiert.
- Notenschlüssel verschieben: gleicher Editor wie im Klausur-Dialog,
  Änderungen wirken sich sofort im Notenspiegel aus; erst
  "Übernehmen" schreibt sie in die Klausur zurück.
- CSV-Export direkt im Dialog, analog zum bestehenden JSON-Export der
  Kompetenzkataloge — ohne die noch fehlende Export-Infrastruktur aus
  Kapitel 11 vorwegzunehmen.
- Abwesende werden konsequent aus allen Statistiken ausgeschlossen
  (löst den in 1.4.3 offen gelassenen Punkt ein).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 01:01:30 +02:00
co-authored by Claude Sonnet 5
parent 725de3813f
commit a22674dc19
7 changed files with 478 additions and 6 deletions
@@ -22,6 +22,7 @@ public partial class GroupDetailView : UserControl
vm.OnDuplicateExam = ShowDuplicateExamDialog;
vm.OnConfirmDeleteExam = ShowDeleteExamDialog;
vm.OnGradeExam = ShowGradeExamDialog;
vm.OnEvaluateExam = ShowEvaluateExamDialog;
}
}
@@ -92,4 +93,19 @@ public partial class GroupDetailView : UserControl
var owner = TopLevel.GetTopLevel(this) as Window;
if (owner is not null) await dialog.ShowDialog(owner);
}
private async Task ShowEvaluateExamDialog(Exam exam)
{
if (DataContext is not GroupDetailViewModel vm || vm.Group is null) return;
var dialogVm = new ExamEvaluationDialogViewModel(
App.Services.GetRequiredService<IExamRepository>(),
App.Services.GetRequiredService<IExamResultRepository>(),
App.Services.GetRequiredService<GradingService>(),
exam, vm.Group.GradingSystem);
var dialog = new ExamEvaluationDialog { DataContext = dialogVm };
var owner = TopLevel.GetTopLevel(this) as Window;
if (owner is not null) await dialog.ShowDialog(owner);
}
}