Das Suffix ".Avalonia" gab es nur, weil daneben ein WinForms-IBKRTrader.App
stand. Das ist seit L5 weg, also faellt auch das Suffix. Git erkennt alle
Dateien als Umbenennung; Assembly, Wurzel-Namensraum und die
avares://-Ressourcen-URI sind mitgezogen.
Nebeneffekt der Umbenennung: die global::Avalonia-Qualifizierungen entfallen.
Sie waren noetig, weil der Namensraum IBKRTrader.App.Avalonia das
Avalonia-Paket verdeckt hat - ein Ueberbleibsel genau der Namensgebung, die
jetzt weg ist.
Inhaltlich falsch gewordene Aussagen berichtigt - das waren die eigentlichen
Ueberbleibsel, nicht die Kommentare:
- .agents/rules/grundregeln.md schrieb weiterhin "C# .NET 10 WinForms",
RichTextBox-Logging, LauncherForm und PropertyGrid vor. Das ist die Regel,
nach der kuenftig gearbeitet wird - sie haette die Portierung Stueck fuer
Stueck rueckgaengig gemacht. Jetzt: Avalonia, keine Plattform-Suffixe, die
11er-Pinnung mit Begruendung, dazu die beiden Regeln, die uns in L1b am
meisten gekostet haben (UTC persistieren + AppTimeZone statt DateTime.Now;
jede Formatierung mit ausdruecklichem IFormatProvider).
- Core: LogEntry ("wird in RichTextBox geschrieben"), IWorker/WorkerEngine/
WorkerInfo ("DataGridView-Zeile"/"-Binding"), ModuleView ("die
WinForms-Shell castet auf Form").
- Doku: ARCHITECTURE (Modul-Ui-Ordner, "designbare Forms mit Initialize"),
KONZEPT-Modul-Accounting ("UI (WinForms, ein Fenster mit Tabs)").
BEWUSST STEHEN GEBLIEBEN sind die Kommentare, die WinForms nur als
Begruendung nennen - warum LoggingService ein Ereignis hat statt einer
RichTextBox, warum ModuleView Func<object> liefert, warum es benannte
Record-Zeilentypen gibt, warum die Einstellungsmaske aus Attributen entsteht.
Das ist die Herleitung des heutigen Entwurfs; ohne sie sieht spaeter jede
dieser Stellen nach Umstaendlichkeit ohne Grund aus.
KONZEPT-Linux-Portierung.md bekommt einen Statusvermerk: umgesetzt, die
Pfadangaben im Fundstellenverzeichnis beziehen sich auf den alten Aufbau.
Zwei Abweichungen von der Schaetzung sind dort festgehalten - der geringere
Aufwand dank der PolytraderSharp-Vorlage, und dass die dort empfohlene
InvariantGlobalization ein Fehler gewesen waere.
Verifiziert: Build 0 Fehler/0 Warnungen, 193 Tests gruen, Smoke-UI
konstruiert alle 7 Ansichten + Launcher + Dialog, Daemon-Prueflauf OK,
publish -r linux-x64 fuer beide Einstiegspunkte fehlerfrei.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
69 lines
3.1 KiB
C#
69 lines
3.1 KiB
C#
namespace IBKRTrader.Core.Modularity;
|
||
|
||
/// <summary>
|
||
/// Eine vom Core oder einem Modul beigesteuerte Fenster-Ansicht. Die Shell zeigt je View höchstens
|
||
/// eine Instanz und holt ein offenes Fenster wieder nach vorne.
|
||
///
|
||
/// <para><b>Bewusst toolkit-neutral:</b> <see cref="CreateView"/> liefert ein <see cref="object"/>,
|
||
/// keinen konkreten Fenstertyp, und <see cref="IconKey"/> ist ein Schlüssel statt eines Bildes.
|
||
/// Dadurch trägt der Core keine UI-Abhängigkeit und bleibt plattformneutral – Voraussetzung für den
|
||
/// kopflosen Linux-Betrieb. Insbesondere hängt hier kein <c>System.Drawing.Image</c> mehr:
|
||
/// <c>System.Drawing.Common</c> ist seit .NET 7 Windows-only und wirft auf Linux. Die jeweilige
|
||
/// Shell kennt ihr Toolkit und castet – die Avalonia-Shell auf <c>Window</c>.</para>
|
||
/// </summary>
|
||
public sealed class ModuleView
|
||
{
|
||
/// <summary>Stabile ID für Einzelinstanz-Handling (nur ein Fenster je View).</summary>
|
||
public string Id { get; init; } = Guid.NewGuid().ToString();
|
||
|
||
/// <summary>Titel (Fallback-Fenstertitel, falls das Fenster keinen eigenen setzt).</summary>
|
||
public string Title { get; init; } = "Fenster";
|
||
|
||
/// <summary>Optionale Gruppierung (z. B. "Core", "CongressTrading").</summary>
|
||
public string? Group { get; init; }
|
||
|
||
/// <summary>Optionale Sortierreihenfolge in Menü/Buttons.</summary>
|
||
public int Order { get; init; } = 0;
|
||
|
||
/// <summary>
|
||
/// Logischer Schlüssel des Symbols für Menü/Buttons (z. B. "dashboard", "logs"). Die Shell löst
|
||
/// ihn gegen ihre eigenen Bildressourcen auf. Settable, damit die Shell den von Modulen
|
||
/// registrierten Views zentral ein Symbol zuweisen kann – Module kennen die Shell-Ressourcen nicht.
|
||
/// </summary>
|
||
public string? IconKey { get; set; }
|
||
|
||
/// <summary>
|
||
/// Erzeugt das anzuzeigende Fenster (frische Instanz je Öffnung). Rückgabetyp ist
|
||
/// <see cref="object"/> – siehe Klassen-Doku zur Toolkit-Neutralität.
|
||
/// </summary>
|
||
public Func<object> CreateView { get; init; } = () => new object();
|
||
}
|
||
|
||
/// <summary>
|
||
/// Wird der Shell beim Start übergeben; Core und Module registrieren hier ihre Ansichten.
|
||
/// Über die Navigations-Mitglieder kann JEDES Fenster (auch Modul-Fenster, die nur den Core kennen)
|
||
/// das gemeinsame „Fenster"-Menü bauen.
|
||
/// </summary>
|
||
public interface IModuleUiHost
|
||
{
|
||
void RegisterView(ModuleView view);
|
||
|
||
/// <summary>Alle registrierten Ansichten (Core + Module).</summary>
|
||
IReadOnlyList<ModuleView> Views { get; }
|
||
|
||
/// <summary>Ist das Fenster dieser View gerade offen?</summary>
|
||
bool IsOpen(string viewId);
|
||
|
||
/// <summary>Öffnet die View bzw. holt ein bereits offenes Fenster in den Vordergrund.</summary>
|
||
void OpenView(string viewId);
|
||
|
||
/// <summary>Holt das Hauptfenster (Launcher) in den Vordergrund.</summary>
|
||
void ActivateMain();
|
||
|
||
/// <summary>Leitet das (bestätigte) Herunterfahren der App ein. Aus jedem Fenster aufrufbar.</summary>
|
||
void RequestShutdown();
|
||
|
||
/// <summary>Feuert, wenn sich der Offen-Status irgendeiner View ändert.</summary>
|
||
event Action? OpenStateChanged;
|
||
}
|