From 1781d71983045def58051ac0c5fbd2e0c48bb28e Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 2 Jul 2026 11:23:23 +0200 Subject: [PATCH] =?UTF-8?q?Phase=205-UI:=20Designer-first=20=E2=80=94=20La?= =?UTF-8?q?uncher=20+=20TerminalView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LauncherForm ist jetzt ein echtes Designer-Formular (LauncherForm.Designer.cs): ListView + MenuStrip + Button im Designer platziert/bearbeitbar. Zur Laufzeit werden nur noch ListView-Eintraege/Gruppen (DATEN) aus den registrierten Views befuellt + Events verdrahtet — keine Steuerelemente mehr im Code erzeugt. - TerminalView: Combo-Items, Button-Text/-Farbe in den Designer verlagert; Konstruktor verdrahtet nur noch Verhalten. - Inhaerente Ausnahme (Modul-System): die konkreten View-Eintraege sind Daten, keine vorplatzierbaren Controls -> daher datengetriebene ListView. - Build 0 Fehler. Co-Authored-By: Claude Opus 4.8 --- Ui/LauncherForm.Designer.cs | 129 ++++++++++++++++++++++++++++++ Ui/LauncherForm.cs | 77 ++++++------------ Ui/LauncherForm.resx | 120 +++++++++++++++++++++++++++ Ui/Views/TerminalView.Designer.cs | 11 ++- Ui/Views/TerminalView.cs | 9 +-- Ui/Views/TerminalView.resx | 120 +++++++++++++++++++++++++++ 6 files changed, 408 insertions(+), 58 deletions(-) create mode 100644 Ui/LauncherForm.Designer.cs create mode 100644 Ui/LauncherForm.resx create mode 100644 Ui/Views/TerminalView.resx diff --git a/Ui/LauncherForm.Designer.cs b/Ui/LauncherForm.Designer.cs new file mode 100644 index 0000000..a1e8c99 --- /dev/null +++ b/Ui/LauncherForm.Designer.cs @@ -0,0 +1,129 @@ +namespace PolyTraderSharp.Ui +{ + partial class LauncherForm + { + private System.ComponentModel.IContainer components = null; + + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Komponenten-Designer generierter Code + + private void InitializeComponent() + { + this.menuStrip = new System.Windows.Forms.MenuStrip(); + this.miDatei = new System.Windows.Forms.ToolStripMenuItem(); + this.miLegacy = new System.Windows.Forms.ToolStripMenuItem(); + this.miBeenden = new System.Windows.Forms.ToolStripMenuItem(); + this.lstViews = new System.Windows.Forms.ListView(); + this.colName = new System.Windows.Forms.ColumnHeader(); + this.pnlBottom = new System.Windows.Forms.Panel(); + this.btnOpen = new System.Windows.Forms.Button(); + this.menuStrip.SuspendLayout(); + this.pnlBottom.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip + // + this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miDatei}); + this.menuStrip.Location = new System.Drawing.Point(0, 0); + this.menuStrip.Name = "menuStrip"; + this.menuStrip.Size = new System.Drawing.Size(360, 24); + this.menuStrip.TabIndex = 0; + // + // miDatei + // + this.miDatei.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miLegacy, + this.miBeenden}); + this.miDatei.Name = "miDatei"; + this.miDatei.Text = "Datei"; + // + // miLegacy + // + this.miLegacy.Name = "miLegacy"; + this.miLegacy.Text = "Legacy-UI (alte Tabs)"; + // + // miBeenden + // + this.miBeenden.Name = "miBeenden"; + this.miBeenden.Text = "Beenden"; + // + // lstViews + // + this.lstViews.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.colName}); + this.lstViews.Dock = System.Windows.Forms.DockStyle.Fill; + this.lstViews.FullRowSelect = true; + this.lstViews.HideSelection = false; + this.lstViews.Location = new System.Drawing.Point(0, 24); + this.lstViews.MultiSelect = false; + this.lstViews.Name = "lstViews"; + this.lstViews.Size = new System.Drawing.Size(360, 420); + this.lstViews.TabIndex = 1; + this.lstViews.UseCompatibleStateImageBehavior = false; + this.lstViews.View = System.Windows.Forms.View.Details; + // + // colName + // + this.colName.Text = "Ansicht"; + this.colName.Width = 330; + // + // pnlBottom + // + this.pnlBottom.Controls.Add(this.btnOpen); + this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; + this.pnlBottom.Location = new System.Drawing.Point(0, 444); + this.pnlBottom.Name = "pnlBottom"; + this.pnlBottom.Size = new System.Drawing.Size(360, 44); + this.pnlBottom.TabIndex = 2; + // + // btnOpen + // + this.btnOpen.Location = new System.Drawing.Point(12, 8); + this.btnOpen.Name = "btnOpen"; + this.btnOpen.Size = new System.Drawing.Size(336, 30); + this.btnOpen.TabIndex = 0; + this.btnOpen.Text = "Öffnen"; + this.btnOpen.UseVisualStyleBackColor = true; + // + // LauncherForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(360, 488); + this.Controls.Add(this.lstViews); + this.Controls.Add(this.pnlBottom); + this.Controls.Add(this.menuStrip); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MainMenuStrip = this.menuStrip; + this.MaximizeBox = false; + this.Name = "LauncherForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "PolyTrader"; + this.menuStrip.ResumeLayout(false); + this.menuStrip.PerformLayout(); + this.pnlBottom.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip; + private System.Windows.Forms.ToolStripMenuItem miDatei; + private System.Windows.Forms.ToolStripMenuItem miLegacy; + private System.Windows.Forms.ToolStripMenuItem miBeenden; + private System.Windows.Forms.ListView lstViews; + private System.Windows.Forms.ColumnHeader colName; + private System.Windows.Forms.Panel pnlBottom; + private System.Windows.Forms.Button btnOpen; + } +} diff --git a/Ui/LauncherForm.cs b/Ui/LauncherForm.cs index 9567c8b..32320d4 100644 --- a/Ui/LauncherForm.cs +++ b/Ui/LauncherForm.cs @@ -1,17 +1,18 @@ using System; -using System.Drawing; using System.Linq; using System.Windows.Forms; using Microsoft.Extensions.DependencyInjection; +using PolyTrader.Core.Modularity; namespace PolyTraderSharp.Ui { /// - /// Schlanke „Startleiste" der PolyTrader.App. Rendert Buttons aus den registrierten - /// Views (gruppiert) und öffnet je View ein eigenständiges Fenster. Kennt selbst - /// kein Modul. Enthält übergangsweise einen Legacy-Button für das alte Tab-frm_main. + /// Schlanke „Startleiste" der PolyTrader.App. Das Layout (ListView, Menü, Button) liegt + /// im Designer (LauncherForm.Designer.cs). Zur Laufzeit werden ausschließlich die + /// Listeneinträge (Daten) aus den registrierten Views befüllt — keine Steuerelemente. + /// Kennt selbst kein Modul. /// - public class LauncherForm : Form + public partial class LauncherForm : Form { private readonly ShellUiHost _uiHost; private readonly IServiceProvider _services; @@ -22,68 +23,42 @@ namespace PolyTraderSharp.Ui _uiHost = uiHost; _services = services; - Text = "PolyTrader"; - Width = 360; - Height = 520; - StartPosition = FormStartPosition.CenterScreen; - MinimizeBox = true; - MaximizeBox = false; - FormBorderStyle = FormBorderStyle.FixedSingle; + InitializeComponent(); - BuildUi(); + PopulateViews(); + lstViews.DoubleClick += (_, _) => OpenSelected(); + btnOpen.Click += (_, _) => OpenSelected(); + miLegacy.Click += (_, _) => OpenLegacy(); + miBeenden.Click += (_, _) => Close(); } - private void BuildUi() + private void PopulateViews() { - var flow = new FlowLayoutPanel - { - Dock = DockStyle.Fill, - FlowDirection = FlowDirection.TopDown, - WrapContents = false, - AutoScroll = true, - Padding = new Padding(12) - }; + lstViews.BeginUpdate(); + lstViews.Groups.Clear(); + lstViews.Items.Clear(); foreach (var group in _uiHost.Views - .GroupBy(v => string.IsNullOrEmpty(v.Group) ? "Allgemein" : v.Group) + .GroupBy(v => string.IsNullOrEmpty(v.Group) ? "Allgemein" : v.Group!) .OrderBy(g => g.Key)) { - flow.Controls.Add(MakeHeader(group.Key)); + var lvGroup = new ListViewGroup(group.Key) { Header = group.Key }; + lstViews.Groups.Add(lvGroup); + foreach (var view in group.OrderBy(v => v.Order).ThenBy(v => v.Title)) { - var captured = view; - flow.Controls.Add(MakeButton(view.Title, (_, _) => _uiHost.OpenView(captured))); + lstViews.Items.Add(new ListViewItem(view.Title, lvGroup) { Tag = view }); } } - // Übergangs-Zugang zur alten Tab-UI, bis alle Views extrahiert sind. - flow.Controls.Add(MakeHeader("Übergang")); - flow.Controls.Add(MakeButton("Legacy-UI (alte Tabs)", (_, _) => OpenLegacy())); - - Controls.Add(flow); + lstViews.EndUpdate(); } - private Label MakeHeader(string text) => new() + private void OpenSelected() { - Text = text, - AutoSize = true, - Font = new Font(Font, FontStyle.Bold), - Margin = new Padding(0, 10, 0, 4) - }; - - private Button MakeButton(string text, EventHandler onClick) - { - var btn = new Button - { - Text = text, - Width = 310, - Height = 34, - Margin = new Padding(0, 2, 0, 2), - TextAlign = ContentAlignment.MiddleLeft, - UseVisualStyleBackColor = true - }; - btn.Click += onClick; - return btn; + if (lstViews.SelectedItems.Count == 0) return; + if (lstViews.SelectedItems[0].Tag is ModuleView view) + _uiHost.OpenView(view); } private void OpenLegacy() diff --git a/Ui/LauncherForm.resx b/Ui/LauncherForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Ui/LauncherForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Ui/Views/TerminalView.Designer.cs b/Ui/Views/TerminalView.Designer.cs index dd67abd..e61c513 100644 --- a/Ui/Views/TerminalView.Designer.cs +++ b/Ui/Views/TerminalView.Designer.cs @@ -39,16 +39,25 @@ namespace PolyTraderSharp.Ui.Views // // btnAutoscroll // + this.btnAutoscroll.BackColor = System.Drawing.Color.LightGreen; this.btnAutoscroll.Location = new System.Drawing.Point(224, 5); this.btnAutoscroll.Name = "btnAutoscroll"; this.btnAutoscroll.Size = new System.Drawing.Size(150, 26); this.btnAutoscroll.TabIndex = 2; this.btnAutoscroll.Text = "Stop Autoscroll"; - this.btnAutoscroll.UseVisualStyleBackColor = true; + this.btnAutoscroll.UseVisualStyleBackColor = false; // // cbLogLevel // this.cbLogLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbLogLevel.Items.AddRange(new object[] { + "Alle", + "Debug", + "Info", + "Warning", + "Error", + "Trade", + "TradeReasoning"}); this.cbLogLevel.Location = new System.Drawing.Point(52, 6); this.cbLogLevel.Name = "cbLogLevel"; this.cbLogLevel.Size = new System.Drawing.Size(160, 23); diff --git a/Ui/Views/TerminalView.cs b/Ui/Views/TerminalView.cs index 52d7b61..3598ec0 100644 --- a/Ui/Views/TerminalView.cs +++ b/Ui/Views/TerminalView.cs @@ -22,13 +22,10 @@ namespace PolyTraderSharp.Ui.Views { InitializeComponent(); - cbLogLevel.Items.AddRange(new object[] { "Alle", "Debug", "Info", "Warning", "Error", "Trade", "TradeReasoning" }); - cbLogLevel.SelectedIndex = 0; - - btnAutoscroll.BackColor = System.Drawing.Color.LightGreen; - btnAutoscroll.Text = "Stop Autoscroll"; + // Steuerelemente + statische Eigenschaften stammen aus dem Designer. + // Hier nur noch Verhalten verdrahten und einen sinnvollen Default wählen. + if (cbLogLevel.Items.Count > 0) cbLogLevel.SelectedIndex = 0; btnAutoscroll.Click += (_, _) => ToggleAutoscroll(); - _uiLogTimer.Tick += ProcessLogQueue; } diff --git a/Ui/Views/TerminalView.resx b/Ui/Views/TerminalView.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Ui/Views/TerminalView.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file