From 4caba5bfd119af11b7e5f61df941ac85d17130ec Mon Sep 17 00:00:00 2001 From: Richard Date: Mon, 6 Jul 2026 10:11:30 +0200 Subject: [PATCH] Copytrading-Views auf Designer-Muster umgestellt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die drei Modul-Views wurden von komplett code-first (alle Controls im Konstruktor) auf das Standard-WinForms-Designer-Muster umgestellt (je X.cs + X.Designer.cs mit InitializeComponent), damit sie im Designer geöffnet und bearbeitet werden können: - ClosedTradesView, AccountSettingsView, MasterTradersView: alle wichtigen Steuerelemente (Panels, DataGridView mit expliziten Spalten via AutoGenerateColumns=false, PropertyGrid, ToolStrip, GroupBox, CheckedListBox, ComboBox, Buttons, Labels, Splitter) sind jetzt Designer-Felder. - Konsistent mit den Core-Views (DashboardView-Muster): Layout im Designer, Zellformate/Event-Wiring/Datenbindung im Code. Verifiziert: --smoke-ui grün (3 Accounts / 32 Trader; alle Views + Launcher OK). Co-Authored-By: Claude Opus 4.8 --- .../Ui/AccountSettingsView.Designer.cs | 128 ++++++++ .../Ui/AccountSettingsView.cs | 53 +-- .../Ui/ClosedTradesView.Designer.cs | 238 ++++++++++++++ .../Ui/ClosedTradesView.cs | 75 +---- .../Ui/MasterTradersView.Designer.cs | 305 ++++++++++++++++++ .../Ui/MasterTradersView.cs | 129 ++------ 6 files changed, 721 insertions(+), 207 deletions(-) create mode 100644 src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.Designer.cs create mode 100644 src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.Designer.cs create mode 100644 src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.Designer.cs diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.Designer.cs b/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.Designer.cs new file mode 100644 index 0000000..e33b928 --- /dev/null +++ b/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.Designer.cs @@ -0,0 +1,128 @@ +namespace PolyTrader.Modules.CopyTrading.Ui +{ + partial class AccountSettingsView + { + 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.pnlTop = new System.Windows.Forms.Panel(); + this.cmbAccounts = new System.Windows.Forms.ComboBox(); + this.lblAccount = new System.Windows.Forms.Label(); + this.pgSettings = new System.Windows.Forms.PropertyGrid(); + this.pnlBottom = new System.Windows.Forms.Panel(); + this.lblHint = new System.Windows.Forms.Label(); + this.btnSave = new System.Windows.Forms.Button(); + this.pnlTop.SuspendLayout(); + this.pnlBottom.SuspendLayout(); + this.SuspendLayout(); + // + // pnlTop + // + this.pnlTop.Controls.Add(this.cmbAccounts); + this.pnlTop.Controls.Add(this.lblAccount); + this.pnlTop.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTop.Location = new System.Drawing.Point(0, 0); + this.pnlTop.Name = "pnlTop"; + this.pnlTop.Padding = new System.Windows.Forms.Padding(8, 8, 8, 6); + this.pnlTop.Size = new System.Drawing.Size(560, 44); + this.pnlTop.TabIndex = 0; + // + // cmbAccounts + // + this.cmbAccounts.Dock = System.Windows.Forms.DockStyle.Fill; + this.cmbAccounts.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cmbAccounts.Location = new System.Drawing.Point(68, 8); + this.cmbAccounts.Name = "cmbAccounts"; + this.cmbAccounts.Size = new System.Drawing.Size(484, 23); + this.cmbAccounts.TabIndex = 1; + // + // lblAccount + // + this.lblAccount.Dock = System.Windows.Forms.DockStyle.Left; + this.lblAccount.Location = new System.Drawing.Point(8, 8); + this.lblAccount.Name = "lblAccount"; + this.lblAccount.Size = new System.Drawing.Size(60, 30); + this.lblAccount.TabIndex = 0; + this.lblAccount.Text = "Account:"; + this.lblAccount.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // pgSettings + // + this.pgSettings.Dock = System.Windows.Forms.DockStyle.Fill; + this.pgSettings.Location = new System.Drawing.Point(0, 44); + this.pgSettings.Name = "pgSettings"; + this.pgSettings.PropertySort = System.Windows.Forms.PropertySort.Categorized; + this.pgSettings.Size = new System.Drawing.Size(560, 508); + this.pgSettings.TabIndex = 1; + this.pgSettings.ToolbarVisible = false; + // + // pnlBottom + // + this.pnlBottom.Controls.Add(this.lblHint); + this.pnlBottom.Controls.Add(this.btnSave); + this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; + this.pnlBottom.Location = new System.Drawing.Point(0, 552); + this.pnlBottom.Name = "pnlBottom"; + this.pnlBottom.Padding = new System.Windows.Forms.Padding(8); + this.pnlBottom.Size = new System.Drawing.Size(560, 48); + this.pnlBottom.TabIndex = 2; + // + // lblHint + // + this.lblHint.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblHint.ForeColor = System.Drawing.Color.DimGray; + this.lblHint.Location = new System.Drawing.Point(8, 8); + this.lblHint.Name = "lblHint"; + this.lblHint.Size = new System.Drawing.Size(424, 32); + this.lblHint.TabIndex = 1; + this.lblHint.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // btnSave + // + this.btnSave.Dock = System.Windows.Forms.DockStyle.Right; + this.btnSave.Location = new System.Drawing.Point(432, 8); + this.btnSave.Name = "btnSave"; + this.btnSave.Size = new System.Drawing.Size(120, 32); + this.btnSave.TabIndex = 0; + this.btnSave.Text = "Speichern"; + this.btnSave.UseVisualStyleBackColor = true; + // + // AccountSettingsView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(560, 600); + this.Controls.Add(this.pgSettings); + this.Controls.Add(this.pnlBottom); + this.Controls.Add(this.pnlTop); + this.MinimumSize = new System.Drawing.Size(420, 400); + this.Name = "AccountSettingsView"; + this.Text = "Copytrading-Account-Einstellungen"; + this.pnlTop.ResumeLayout(false); + this.pnlBottom.ResumeLayout(false); + this.ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Panel pnlTop; + private System.Windows.Forms.ComboBox cmbAccounts; + private System.Windows.Forms.Label lblAccount; + private System.Windows.Forms.PropertyGrid pgSettings; + private System.Windows.Forms.Panel pnlBottom; + private System.Windows.Forms.Label lblHint; + private System.Windows.Forms.Button btnSave; + } +} diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.cs b/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.cs index 61b0885..250259c 100644 --- a/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.cs +++ b/src/PolyTrader.Modules.CopyTrading/Ui/AccountSettingsView.cs @@ -1,5 +1,4 @@ using System; -using System.Drawing; using System.Linq; using System.Windows.Forms; using PolyTrader.Modules.CopyTrading.Persistence; @@ -12,17 +11,14 @@ namespace PolyTrader.Modules.CopyTrading.Ui /// Bearbeitet die copytrading-spezifischen Detail-Einstellungen je Account /// (Investment-/Zeit-Limits, ). Persistiert über /// das Repo und aktualisiert den Hot-Path-State (). + /// Layout im Designer (AccountSettingsView.Designer.cs), Daten/Logik hier. /// - public class AccountSettingsView : Form + public partial class AccountSettingsView : Form { private readonly ICopyTradingAccountSettingsRepository _repo; private readonly TradingState _state; private readonly CopyTradingState _copyState; - private readonly ComboBox _accounts = new(); - private readonly PropertyGrid _grid = new(); - private readonly Label _hint = new(); - private CopyTradingAccountSettings? _current; public AccountSettingsView(ICopyTradingAccountSettingsRepository repo, TradingState state, CopyTradingState copyState) @@ -31,35 +27,10 @@ namespace PolyTrader.Modules.CopyTrading.Ui _state = state; _copyState = copyState; - Text = "Copytrading-Account-Einstellungen"; - StartPosition = FormStartPosition.CenterScreen; - Size = new Size(560, 620); - MinimumSize = new Size(420, 400); + InitializeComponent(); - var top = new Panel { Dock = DockStyle.Top, Height = 44, Padding = new Padding(8, 8, 8, 6) }; - var lbl = new Label { Text = "Account:", Dock = DockStyle.Left, Width = 60, TextAlign = ContentAlignment.MiddleLeft }; - _accounts.Dock = DockStyle.Fill; - _accounts.DropDownStyle = ComboBoxStyle.DropDownList; - _accounts.SelectedIndexChanged += (_, _) => LoadSelected(); - top.Controls.Add(_accounts); - top.Controls.Add(lbl); - - _grid.Dock = DockStyle.Fill; - _grid.ToolbarVisible = false; - _grid.PropertySort = PropertySort.Categorized; - - var bottom = new Panel { Dock = DockStyle.Bottom, Height = 48, Padding = new Padding(8) }; - var btnSave = new Button { Text = "Speichern", Dock = DockStyle.Right, Width = 120 }; + cmbAccounts.SelectedIndexChanged += (_, _) => LoadSelected(); btnSave.Click += (_, _) => Save(); - _hint.Dock = DockStyle.Fill; - _hint.TextAlign = ContentAlignment.MiddleLeft; - _hint.ForeColor = Color.DimGray; - bottom.Controls.Add(_hint); - bottom.Controls.Add(btnSave); - - Controls.Add(_grid); - Controls.Add(bottom); - Controls.Add(top); PopulateAccounts(); } @@ -71,20 +42,20 @@ namespace PolyTrader.Modules.CopyTrading.Ui .Select(a => new AccountItem(a.AccountId, string.IsNullOrEmpty(a.Name) ? $"#{a.AccountId}" : $"{a.Name} (#{a.AccountId}){(a.IsDemo ? " · Demo" : "")}")) .ToList(); - _accounts.DisplayMember = nameof(AccountItem.Label); - _accounts.ValueMember = nameof(AccountItem.Id); - _accounts.DataSource = items; + cmbAccounts.DisplayMember = nameof(AccountItem.Label); + cmbAccounts.ValueMember = nameof(AccountItem.Id); + cmbAccounts.DataSource = items; if (items.Count > 0) LoadSelected(); - else _hint.Text = "Keine Accounts vorhanden."; + else lblHint.Text = "Keine Accounts vorhanden."; } private void LoadSelected() { - if (_accounts.SelectedItem is not AccountItem item) return; + if (cmbAccounts.SelectedItem is not AccountItem item) return; _current = _repo.Get(item.Id) ?? new CopyTradingAccountSettings { AccountId = item.Id }; - _grid.SelectedObject = _current; - _hint.Text = $"Einstellungen für Account #{item.Id}."; + pgSettings.SelectedObject = _current; + lblHint.Text = $"Einstellungen für Account #{item.Id}."; } private void Save() @@ -92,7 +63,7 @@ namespace PolyTrader.Modules.CopyTrading.Ui if (_current == null) return; _repo.Upsert(_current); _copyState.AccountSettings[_current.AccountId] = _current; - _hint.Text = $"Gespeichert für Account #{_current.AccountId} um {DateTime.Now:HH:mm:ss}."; + lblHint.Text = $"Gespeichert für Account #{_current.AccountId} um {DateTime.Now:HH:mm:ss}."; } private sealed record AccountItem(int Id, string Label); diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.Designer.cs b/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.Designer.cs new file mode 100644 index 0000000..6d4cd88 --- /dev/null +++ b/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.Designer.cs @@ -0,0 +1,238 @@ +namespace PolyTrader.Modules.CopyTrading.Ui +{ + partial class ClosedTradesView + { + 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.pnlTop = new System.Windows.Forms.Panel(); + this.lblSummary = new System.Windows.Forms.Label(); + this.btnRefresh = new System.Windows.Forms.Button(); + this.dgvTrades = new System.Windows.Forms.DataGridView(); + this.colTradeId = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colAccount = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colTrader = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colMarket = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colOutcome = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSide = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colEntry = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colExit = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSize = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPnl = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPnlPct = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colOpenedAt = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colClosedAt = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.pnlTop.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvTrades)).BeginInit(); + this.SuspendLayout(); + // + // pnlTop + // + this.pnlTop.Controls.Add(this.lblSummary); + this.pnlTop.Controls.Add(this.btnRefresh); + this.pnlTop.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTop.Location = new System.Drawing.Point(0, 0); + this.pnlTop.Name = "pnlTop"; + this.pnlTop.Size = new System.Drawing.Size(1100, 40); + this.pnlTop.TabIndex = 0; + // + // lblSummary + // + this.lblSummary.AutoSize = true; + this.lblSummary.Location = new System.Drawing.Point(148, 12); + this.lblSummary.Name = "lblSummary"; + this.lblSummary.Size = new System.Drawing.Size(16, 15); + this.lblSummary.TabIndex = 1; + this.lblSummary.Text = "—"; + // + // btnRefresh + // + this.btnRefresh.Location = new System.Drawing.Point(8, 6); + this.btnRefresh.Name = "btnRefresh"; + this.btnRefresh.Size = new System.Drawing.Size(130, 28); + this.btnRefresh.TabIndex = 0; + this.btnRefresh.Text = "Aktualisieren"; + this.btnRefresh.UseVisualStyleBackColor = true; + // + // dgvTrades + // + this.dgvTrades.AllowUserToAddRows = false; + this.dgvTrades.AllowUserToDeleteRows = false; + this.dgvTrades.AutoGenerateColumns = false; + this.dgvTrades.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvTrades.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colTradeId, + this.colAccount, + this.colTrader, + this.colMarket, + this.colOutcome, + this.colSide, + this.colEntry, + this.colExit, + this.colSize, + this.colPnl, + this.colPnlPct, + this.colOpenedAt, + this.colClosedAt}); + this.dgvTrades.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvTrades.Location = new System.Drawing.Point(0, 40); + this.dgvTrades.Name = "dgvTrades"; + this.dgvTrades.ReadOnly = true; + this.dgvTrades.RowHeadersVisible = false; + this.dgvTrades.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dgvTrades.Size = new System.Drawing.Size(1100, 560); + this.dgvTrades.TabIndex = 1; + // + // colTradeId + // + this.colTradeId.DataPropertyName = "TradeId"; + this.colTradeId.HeaderText = "#"; + this.colTradeId.Name = "colTradeId"; + this.colTradeId.ReadOnly = true; + this.colTradeId.Width = 60; + // + // colAccount + // + this.colAccount.DataPropertyName = "AccountName"; + this.colAccount.HeaderText = "Account"; + this.colAccount.Name = "colAccount"; + this.colAccount.ReadOnly = true; + this.colAccount.Width = 130; + // + // colTrader + // + this.colTrader.DataPropertyName = "SourceTraderName"; + this.colTrader.HeaderText = "Master-Trader"; + this.colTrader.Name = "colTrader"; + this.colTrader.ReadOnly = true; + this.colTrader.Width = 130; + // + // colMarket + // + this.colMarket.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colMarket.DataPropertyName = "MarketQuestion"; + this.colMarket.HeaderText = "Markt"; + this.colMarket.Name = "colMarket"; + this.colMarket.ReadOnly = true; + // + // colOutcome + // + this.colOutcome.DataPropertyName = "Outcome"; + this.colOutcome.HeaderText = "Outcome"; + this.colOutcome.Name = "colOutcome"; + this.colOutcome.ReadOnly = true; + this.colOutcome.Width = 80; + // + // colSide + // + this.colSide.DataPropertyName = "Side"; + this.colSide.HeaderText = "Side"; + this.colSide.Name = "colSide"; + this.colSide.ReadOnly = true; + this.colSide.Width = 60; + // + // colEntry + // + this.colEntry.DataPropertyName = "EntryPrice"; + this.colEntry.HeaderText = "Entry"; + this.colEntry.Name = "colEntry"; + this.colEntry.ReadOnly = true; + this.colEntry.Width = 70; + // + // colExit + // + this.colExit.DataPropertyName = "ExitPrice"; + this.colExit.HeaderText = "Exit"; + this.colExit.Name = "colExit"; + this.colExit.ReadOnly = true; + this.colExit.Width = 70; + // + // colSize + // + this.colSize.DataPropertyName = "Size"; + this.colSize.HeaderText = "Size"; + this.colSize.Name = "colSize"; + this.colSize.ReadOnly = true; + this.colSize.Width = 70; + // + // colPnl + // + this.colPnl.DataPropertyName = "RealizedPnl"; + this.colPnl.HeaderText = "PnL"; + this.colPnl.Name = "colPnl"; + this.colPnl.ReadOnly = true; + this.colPnl.Width = 80; + // + // colPnlPct + // + this.colPnlPct.DataPropertyName = "PnlPercent"; + this.colPnlPct.HeaderText = "PnL %"; + this.colPnlPct.Name = "colPnlPct"; + this.colPnlPct.ReadOnly = true; + this.colPnlPct.Width = 70; + // + // colOpenedAt + // + this.colOpenedAt.DataPropertyName = "OpenedAt"; + this.colOpenedAt.HeaderText = "Eröffnet"; + this.colOpenedAt.Name = "colOpenedAt"; + this.colOpenedAt.ReadOnly = true; + this.colOpenedAt.Width = 130; + // + // colClosedAt + // + this.colClosedAt.DataPropertyName = "ClosedAt"; + this.colClosedAt.HeaderText = "Geschlossen"; + this.colClosedAt.Name = "colClosedAt"; + this.colClosedAt.ReadOnly = true; + this.colClosedAt.Width = 130; + // + // ClosedTradesView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1100, 600); + this.Controls.Add(this.dgvTrades); + this.Controls.Add(this.pnlTop); + this.MinimumSize = new System.Drawing.Size(700, 400); + this.Name = "ClosedTradesView"; + this.Text = "Geschlossene Copytrades"; + this.pnlTop.ResumeLayout(false); + this.pnlTop.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvTrades)).EndInit(); + this.ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Panel pnlTop; + private System.Windows.Forms.Button btnRefresh; + private System.Windows.Forms.Label lblSummary; + private System.Windows.Forms.DataGridView dgvTrades; + private System.Windows.Forms.DataGridViewTextBoxColumn colTradeId; + private System.Windows.Forms.DataGridViewTextBoxColumn colAccount; + private System.Windows.Forms.DataGridViewTextBoxColumn colTrader; + private System.Windows.Forms.DataGridViewTextBoxColumn colMarket; + private System.Windows.Forms.DataGridViewTextBoxColumn colOutcome; + private System.Windows.Forms.DataGridViewTextBoxColumn colSide; + private System.Windows.Forms.DataGridViewTextBoxColumn colEntry; + private System.Windows.Forms.DataGridViewTextBoxColumn colExit; + private System.Windows.Forms.DataGridViewTextBoxColumn colSize; + private System.Windows.Forms.DataGridViewTextBoxColumn colPnl; + private System.Windows.Forms.DataGridViewTextBoxColumn colPnlPct; + private System.Windows.Forms.DataGridViewTextBoxColumn colOpenedAt; + private System.Windows.Forms.DataGridViewTextBoxColumn colClosedAt; + } +} diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs b/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs index 7a9d413..1146c45 100644 --- a/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs +++ b/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel; -using System.Drawing; using System.Linq; using System.Windows.Forms; using PolyTrader.Modules.CopyTrading.Persistence; @@ -12,47 +11,31 @@ namespace PolyTrader.Modules.CopyTrading.Ui /// /// Zeigt die geschlossenen Copytrades des Moduls (mod_copytrading_closed_trades) mit /// aufgelösten Account-/Master-Trader-Namen und einer Kurzauswertung. + /// Layout im Designer (ClosedTradesView.Designer.cs), Daten/Logik hier. /// - public class ClosedTradesView : Form + public partial class ClosedTradesView : Form { private readonly ICopyTradeLogRepository _tradeLog; private readonly TradingState _state; private readonly CopyTradingState _copyState; - private readonly DataGridView _grid = new(); - private readonly Label _summary = new(); - public ClosedTradesView(ICopyTradeLogRepository tradeLog, TradingState state, CopyTradingState copyState) { _tradeLog = tradeLog; _state = state; _copyState = copyState; - Text = "Geschlossene Copytrades"; - StartPosition = FormStartPosition.CenterScreen; - Size = new Size(1100, 620); - MinimumSize = new Size(700, 400); + InitializeComponent(); + + colEntry.DefaultCellStyle.Format = "F3"; + colExit.DefaultCellStyle.Format = "F3"; + colSize.DefaultCellStyle.Format = "F2"; + colPnl.DefaultCellStyle.Format = "F2"; + colPnlPct.DefaultCellStyle.Format = "F1"; + colOpenedAt.DefaultCellStyle.Format = "dd.MM.yyyy HH:mm"; + colClosedAt.DefaultCellStyle.Format = "dd.MM.yyyy HH:mm"; - var top = new Panel { Dock = DockStyle.Top, Height = 40, Padding = new Padding(8, 6, 8, 6) }; - var btnRefresh = new Button { Text = "Aktualisieren", Dock = DockStyle.Left, Width = 120 }; btnRefresh.Click += (_, _) => LoadData(); - _summary.Dock = DockStyle.Fill; - _summary.TextAlign = ContentAlignment.MiddleLeft; - _summary.Padding = new Padding(12, 0, 0, 0); - top.Controls.Add(_summary); - top.Controls.Add(btnRefresh); - - _grid.Dock = DockStyle.Fill; - _grid.ReadOnly = true; - _grid.AllowUserToAddRows = false; - _grid.AllowUserToDeleteRows = false; - _grid.RowHeadersVisible = false; - _grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect; - _grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; - _grid.AutoGenerateColumns = true; - - Controls.Add(_grid); - Controls.Add(top); LoadData(); } @@ -86,44 +69,12 @@ namespace PolyTrader.Modules.CopyTrading.Ui }) .ToList(); - _grid.DataSource = new BindingList(rows); - FormatColumns(); + dgvTrades.DataSource = new BindingList(rows); decimal totalPnl = rows.Sum(x => x.RealizedPnl); int wins = rows.Count(x => x.RealizedPnl > 0); double winrate = rows.Count > 0 ? (double)wins / rows.Count * 100 : 0; - _summary.Text = $"{rows.Count} Trades | PnL gesamt: {totalPnl:F2} USDC | Winrate: {winrate:F1}%"; - } - - private void FormatColumns() - { - void Hide(string name) { if (_grid.Columns[name] is { } c) c.Visible = false; } - void Fmt(string name, string f) { if (_grid.Columns[name] is { } c) c.DefaultCellStyle.Format = f; } - void Head(string name, string h) { if (_grid.Columns[name] is { } c) c.HeaderText = h; } - - Hide(nameof(ClosedTradeRow.TokenId)); - Hide(nameof(ClosedTradeRow.MarketSlug)); - Hide(nameof(ClosedTradeRow.AccountId)); - Hide(nameof(ClosedTradeRow.SourceTraderId)); - Hide(nameof(ClosedTradeRow.IsDemo)); - - Fmt(nameof(ClosedTradeRow.EntryPrice), "F3"); - Fmt(nameof(ClosedTradeRow.ExitPrice), "F3"); - Fmt(nameof(ClosedTradeRow.Size), "F2"); - Fmt(nameof(ClosedTradeRow.RealizedPnl), "F2"); - Fmt(nameof(ClosedTradeRow.PnlPercent), "F1"); - Fmt(nameof(ClosedTradeRow.TotalFees), "F2"); - Fmt(nameof(ClosedTradeRow.OpenedAt), "dd.MM.yyyy HH:mm"); - Fmt(nameof(ClosedTradeRow.ClosedAt), "dd.MM.yyyy HH:mm"); - - Head(nameof(ClosedTradeRow.TradeId), "#"); - Head(nameof(ClosedTradeRow.AccountName), "Account"); - Head(nameof(ClosedTradeRow.SourceTraderName), "Master-Trader"); - Head(nameof(ClosedTradeRow.MarketQuestion), "Markt"); - Head(nameof(ClosedTradeRow.RealizedPnl), "PnL"); - Head(nameof(ClosedTradeRow.PnlPercent), "PnL %"); - Head(nameof(ClosedTradeRow.ClosedAt), "Geschlossen"); - Head(nameof(ClosedTradeRow.OpenedAt), "Eröffnet"); + lblSummary.Text = $"{rows.Count} Trades | PnL gesamt: {totalPnl:F2} USDC | Winrate: {winrate:F1}%"; } private string ResolveAccount(int accountId, bool isDemo) diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.Designer.cs b/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.Designer.cs new file mode 100644 index 0000000..30b4a01 --- /dev/null +++ b/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.Designer.cs @@ -0,0 +1,305 @@ +namespace PolyTrader.Modules.CopyTrading.Ui +{ + partial class MasterTradersView + { + 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.toolbar = new System.Windows.Forms.ToolStrip(); + this.tsNew = new System.Windows.Forms.ToolStripButton(); + this.tsSave = new System.Windows.Forms.ToolStripButton(); + this.tsDelete = new System.Windows.Forms.ToolStripButton(); + this.tsSep = new System.Windows.Forms.ToolStripSeparator(); + this.tsRefresh = new System.Windows.Forms.ToolStripButton(); + this.grid = new System.Windows.Forms.DataGridView(); + this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colWallet = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colCategory = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colActive = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colTrades = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colWinrate = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPnl = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.splitter = new System.Windows.Forms.Splitter(); + this.rightPanel = new System.Windows.Forms.Panel(); + this.pgDetail = new System.Windows.Forms.PropertyGrid(); + this.grpAccounts = new System.Windows.Forms.GroupBox(); + this.clbAccounts = new System.Windows.Forms.CheckedListBox(); + this.statusPanel = new System.Windows.Forms.Panel(); + this.lblHint = new System.Windows.Forms.Label(); + this.toolbar.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.grid)).BeginInit(); + this.rightPanel.SuspendLayout(); + this.grpAccounts.SuspendLayout(); + this.statusPanel.SuspendLayout(); + this.SuspendLayout(); + // + // toolbar + // + this.toolbar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.toolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsNew, + this.tsSave, + this.tsDelete, + this.tsSep, + this.tsRefresh}); + this.toolbar.Location = new System.Drawing.Point(0, 0); + this.toolbar.Name = "toolbar"; + this.toolbar.Size = new System.Drawing.Size(1180, 25); + this.toolbar.TabIndex = 0; + // + // tsNew + // + this.tsNew.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.tsNew.Name = "tsNew"; + this.tsNew.Size = new System.Drawing.Size(35, 22); + this.tsNew.Text = "Neu"; + // + // tsSave + // + this.tsSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.tsSave.Name = "tsSave"; + this.tsSave.Size = new System.Drawing.Size(69, 22); + this.tsSave.Text = "Speichern"; + // + // tsDelete + // + this.tsDelete.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.tsDelete.Name = "tsDelete"; + this.tsDelete.Size = new System.Drawing.Size(57, 22); + this.tsDelete.Text = "Löschen"; + // + // tsSep + // + this.tsSep.Name = "tsSep"; + this.tsSep.Size = new System.Drawing.Size(6, 25); + // + // tsRefresh + // + this.tsRefresh.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.tsRefresh.Name = "tsRefresh"; + this.tsRefresh.Size = new System.Drawing.Size(90, 22); + this.tsRefresh.Text = "Aktualisieren"; + // + // grid + // + this.grid.AllowUserToAddRows = false; + this.grid.AllowUserToDeleteRows = false; + this.grid.AutoGenerateColumns = false; + this.grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.grid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colId, + this.colWallet, + this.colName, + this.colCategory, + this.colActive, + this.colTrades, + this.colWinrate, + this.colPnl}); + this.grid.Dock = System.Windows.Forms.DockStyle.Fill; + this.grid.Location = new System.Drawing.Point(0, 25); + this.grid.MultiSelect = false; + this.grid.Name = "grid"; + this.grid.ReadOnly = true; + this.grid.RowHeadersVisible = false; + this.grid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.grid.Size = new System.Drawing.Size(715, 589); + this.grid.TabIndex = 4; + // + // colId + // + this.colId.DataPropertyName = "Id"; + this.colId.HeaderText = "#"; + this.colId.Name = "colId"; + this.colId.ReadOnly = true; + this.colId.Width = 50; + // + // colWallet + // + this.colWallet.DataPropertyName = "WalletAddress"; + this.colWallet.HeaderText = "Wallet"; + this.colWallet.Name = "colWallet"; + this.colWallet.ReadOnly = true; + this.colWallet.Width = 170; + // + // colName + // + this.colName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colName.DataPropertyName = "DisplayName"; + this.colName.HeaderText = "Name"; + this.colName.Name = "colName"; + this.colName.ReadOnly = true; + // + // colCategory + // + this.colCategory.DataPropertyName = "Category"; + this.colCategory.HeaderText = "Kategorie"; + this.colCategory.Name = "colCategory"; + this.colCategory.ReadOnly = true; + this.colCategory.Width = 110; + // + // colActive + // + this.colActive.DataPropertyName = "IsActive"; + this.colActive.HeaderText = "Aktiv"; + this.colActive.Name = "colActive"; + this.colActive.ReadOnly = true; + this.colActive.Width = 50; + // + // colTrades + // + this.colTrades.DataPropertyName = "TotalTrades"; + this.colTrades.HeaderText = "Trades (7T)"; + this.colTrades.Name = "colTrades"; + this.colTrades.ReadOnly = true; + this.colTrades.Width = 90; + // + // colWinrate + // + this.colWinrate.DataPropertyName = "Winrate30t"; + this.colWinrate.HeaderText = "Winrate %"; + this.colWinrate.Name = "colWinrate"; + this.colWinrate.ReadOnly = true; + this.colWinrate.Width = 90; + // + // colPnl + // + this.colPnl.DataPropertyName = "TotalPnl"; + this.colPnl.HeaderText = "PnL (7T)"; + this.colPnl.Name = "colPnl"; + this.colPnl.ReadOnly = true; + this.colPnl.Width = 100; + // + // splitter + // + this.splitter.Dock = System.Windows.Forms.DockStyle.Right; + this.splitter.Location = new System.Drawing.Point(715, 25); + this.splitter.Name = "splitter"; + this.splitter.Size = new System.Drawing.Size(5, 589); + this.splitter.TabIndex = 3; + this.splitter.TabStop = false; + // + // rightPanel + // + this.rightPanel.Controls.Add(this.pgDetail); + this.rightPanel.Controls.Add(this.grpAccounts); + this.rightPanel.Dock = System.Windows.Forms.DockStyle.Right; + this.rightPanel.Location = new System.Drawing.Point(720, 25); + this.rightPanel.Name = "rightPanel"; + this.rightPanel.Padding = new System.Windows.Forms.Padding(6, 0, 0, 0); + this.rightPanel.Size = new System.Drawing.Size(460, 589); + this.rightPanel.TabIndex = 2; + // + // pgDetail + // + this.pgDetail.Dock = System.Windows.Forms.DockStyle.Fill; + this.pgDetail.Location = new System.Drawing.Point(6, 0); + this.pgDetail.Name = "pgDetail"; + this.pgDetail.PropertySort = System.Windows.Forms.PropertySort.Categorized; + this.pgDetail.Size = new System.Drawing.Size(454, 399); + this.pgDetail.TabIndex = 0; + this.pgDetail.ToolbarVisible = false; + // + // grpAccounts + // + this.grpAccounts.Controls.Add(this.clbAccounts); + this.grpAccounts.Dock = System.Windows.Forms.DockStyle.Bottom; + this.grpAccounts.Location = new System.Drawing.Point(6, 399); + this.grpAccounts.Name = "grpAccounts"; + this.grpAccounts.Padding = new System.Windows.Forms.Padding(8); + this.grpAccounts.Size = new System.Drawing.Size(454, 190); + this.grpAccounts.TabIndex = 1; + this.grpAccounts.TabStop = false; + this.grpAccounts.Text = "Zugewiesene Accounts (kopieren diesen Trader)"; + // + // clbAccounts + // + this.clbAccounts.CheckOnClick = true; + this.clbAccounts.Dock = System.Windows.Forms.DockStyle.Fill; + this.clbAccounts.IntegralHeight = false; + this.clbAccounts.Location = new System.Drawing.Point(8, 24); + this.clbAccounts.Name = "clbAccounts"; + this.clbAccounts.Size = new System.Drawing.Size(438, 158); + this.clbAccounts.TabIndex = 0; + // + // statusPanel + // + this.statusPanel.Controls.Add(this.lblHint); + this.statusPanel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.statusPanel.Location = new System.Drawing.Point(0, 614); + this.statusPanel.Name = "statusPanel"; + this.statusPanel.Size = new System.Drawing.Size(1180, 26); + this.statusPanel.TabIndex = 1; + // + // lblHint + // + this.lblHint.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblHint.ForeColor = System.Drawing.Color.DimGray; + this.lblHint.Location = new System.Drawing.Point(0, 0); + this.lblHint.Name = "lblHint"; + this.lblHint.Padding = new System.Windows.Forms.Padding(8, 0, 0, 0); + this.lblHint.Size = new System.Drawing.Size(1180, 26); + this.lblHint.TabIndex = 0; + this.lblHint.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // MasterTradersView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1180, 640); + this.Controls.Add(this.grid); + this.Controls.Add(this.splitter); + this.Controls.Add(this.rightPanel); + this.Controls.Add(this.statusPanel); + this.Controls.Add(this.toolbar); + this.MinimumSize = new System.Drawing.Size(820, 460); + this.Name = "MasterTradersView"; + this.Text = "Master-Trader"; + this.toolbar.ResumeLayout(false); + this.toolbar.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.grid)).EndInit(); + this.rightPanel.ResumeLayout(false); + this.grpAccounts.ResumeLayout(false); + this.statusPanel.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + } + + #endregion + + private System.Windows.Forms.ToolStrip toolbar; + private System.Windows.Forms.ToolStripButton tsNew; + private System.Windows.Forms.ToolStripButton tsSave; + private System.Windows.Forms.ToolStripButton tsDelete; + private System.Windows.Forms.ToolStripSeparator tsSep; + private System.Windows.Forms.ToolStripButton tsRefresh; + private System.Windows.Forms.DataGridView grid; + private System.Windows.Forms.DataGridViewTextBoxColumn colId; + private System.Windows.Forms.DataGridViewTextBoxColumn colWallet; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewTextBoxColumn colCategory; + private System.Windows.Forms.DataGridViewCheckBoxColumn colActive; + private System.Windows.Forms.DataGridViewTextBoxColumn colTrades; + private System.Windows.Forms.DataGridViewTextBoxColumn colWinrate; + private System.Windows.Forms.DataGridViewTextBoxColumn colPnl; + private System.Windows.Forms.Splitter splitter; + private System.Windows.Forms.Panel rightPanel; + private System.Windows.Forms.PropertyGrid pgDetail; + private System.Windows.Forms.GroupBox grpAccounts; + private System.Windows.Forms.CheckedListBox clbAccounts; + private System.Windows.Forms.Panel statusPanel; + private System.Windows.Forms.Label lblHint; + } +} diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.cs b/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.cs index 8cd7877..c995956 100644 --- a/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.cs +++ b/src/PolyTrader.Modules.CopyTrading/Ui/MasterTradersView.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel; -using System.Drawing; using System.Linq; using System.Windows.Forms; using PolyTrader.Modules.CopyTrading.Persistence; @@ -14,18 +13,14 @@ namespace PolyTrader.Modules.CopyTrading.Ui /// (PropertyGrid) und Account-Zuweisung (welche Accounts diesen Trader kopieren). /// Persistiert über das Repo und hält den Hot-Path-State /// () synchron. + /// Layout im Designer (MasterTradersView.Designer.cs), Daten/Logik hier. /// - public class MasterTradersView : Form + public partial class MasterTradersView : Form { private readonly ITrackedTraderRepository _repo; private readonly TradingState _state; private readonly CopyTradingState _copyState; - private readonly DataGridView _grid = new(); - private readonly PropertyGrid _detail = new(); - private readonly CheckedListBox _accounts = new(); - private readonly Label _hint = new(); - private BindingList _binding = new(); private TrackedTrader? _current; @@ -35,66 +30,16 @@ namespace PolyTrader.Modules.CopyTrading.Ui _state = state; _copyState = copyState; - Text = "Master-Trader"; - StartPosition = FormStartPosition.CenterScreen; - Size = new Size(1180, 640); - MinimumSize = new Size(820, 460); + InitializeComponent(); + + colWinrate.DefaultCellStyle.Format = "F1"; + colPnl.DefaultCellStyle.Format = "F2"; - // Toolbar - var toolbar = new ToolStrip { GripStyle = ToolStripGripStyle.Hidden }; - var tsNew = new ToolStripButton("Neu"); - var tsSave = new ToolStripButton("Speichern"); - var tsDelete = new ToolStripButton("Löschen"); - var tsRefresh = new ToolStripButton("Aktualisieren"); tsNew.Click += (_, _) => AddNew(); tsSave.Click += (_, _) => SaveCurrent(); tsDelete.Click += (_, _) => DeleteCurrent(); tsRefresh.Click += (_, _) => LoadData(); - toolbar.Items.AddRange(new ToolStripItem[] - { - tsNew, tsSave, tsDelete, new ToolStripSeparator(), tsRefresh - }); - - // Liste links - _grid.Dock = DockStyle.Fill; - _grid.ReadOnly = true; - _grid.AllowUserToAddRows = false; - _grid.AllowUserToDeleteRows = false; - _grid.RowHeadersVisible = false; - _grid.MultiSelect = false; - _grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect; - _grid.AutoGenerateColumns = true; - _grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; - _grid.SelectionChanged += (_, _) => OnSelectionChanged(); - - // Detail rechts: PropertyGrid + Account-Zuweisung - _detail.Dock = DockStyle.Fill; - _detail.ToolbarVisible = false; - _detail.PropertySort = PropertySort.Categorized; - - var accBox = new GroupBox { Text = "Zugewiesene Accounts (kopieren diesen Trader)", Dock = DockStyle.Bottom, Height = 190, Padding = new Padding(8) }; - _accounts.Dock = DockStyle.Fill; - _accounts.CheckOnClick = true; - accBox.Controls.Add(_accounts); - - var right = new Panel { Dock = DockStyle.Right, Width = 460, Padding = new Padding(6, 0, 0, 0) }; - right.Controls.Add(_detail); - right.Controls.Add(accBox); - - var split = new Splitter { Dock = DockStyle.Right, Width = 5 }; - - var status = new Panel { Dock = DockStyle.Bottom, Height = 26 }; - _hint.Dock = DockStyle.Fill; - _hint.TextAlign = ContentAlignment.MiddleLeft; - _hint.ForeColor = Color.DimGray; - _hint.Padding = new Padding(8, 0, 0, 0); - status.Controls.Add(_hint); - - Controls.Add(_grid); - Controls.Add(split); - Controls.Add(right); - Controls.Add(status); - Controls.Add(toolbar); + grid.SelectionChanged += (_, _) => OnSelectionChanged(); LoadData(); } @@ -103,63 +48,39 @@ namespace PolyTrader.Modules.CopyTrading.Ui { var traders = _repo.GetAll().OrderBy(t => t.Id).ToList(); _binding = new BindingList(traders); - _grid.DataSource = _binding; - FormatColumns(); + grid.DataSource = _binding; if (traders.Count > 0) - _grid.CurrentCell = _grid.Rows[0].Cells[0]; + grid.CurrentCell = grid.Rows[0].Cells[0]; else ClearDetail(); - _hint.Text = $"{traders.Count} Master-Trader geladen."; - } - - private void FormatColumns() - { - void Hide(string n) { if (_grid.Columns[n] is { } c) c.Visible = false; } - void Head(string n, string h) { if (_grid.Columns[n] is { } c) c.HeaderText = h; } - void Fmt(string n, string f) { if (_grid.Columns[n] is { } c) c.DefaultCellStyle.Format = f; } - - Hide(nameof(TrackedTrader.Description)); - Hide(nameof(TrackedTrader.Reasoning)); - Hide(nameof(TrackedTrader.IsHidden)); - Hide(nameof(TrackedTrader.WinningTrades)); - - Head(nameof(TrackedTrader.Id), "#"); - Head(nameof(TrackedTrader.WalletAddress), "Wallet"); - Head(nameof(TrackedTrader.DisplayName), "Name"); - Head(nameof(TrackedTrader.Category), "Kategorie"); - Head(nameof(TrackedTrader.IsActive), "Aktiv"); - Head(nameof(TrackedTrader.TotalTrades), "Trades (7T)"); - Head(nameof(TrackedTrader.Winrate30t), "Winrate %"); - Head(nameof(TrackedTrader.TotalPnl), "PnL (7T)"); - Fmt(nameof(TrackedTrader.Winrate30t), "F1"); - Fmt(nameof(TrackedTrader.TotalPnl), "F2"); + lblHint.Text = $"{traders.Count} Master-Trader geladen."; } private void OnSelectionChanged() { - if (_grid.CurrentRow?.DataBoundItem is TrackedTrader t) + if (grid.CurrentRow?.DataBoundItem is TrackedTrader t) BindDetail(t); } private void BindDetail(TrackedTrader trader) { _current = trader; - _detail.SelectedObject = trader; + pgDetail.SelectedObject = trader; - _accounts.Items.Clear(); + clbAccounts.Items.Clear(); foreach (var acc in _state.Accounts.Values.OrderBy(a => a.AccountId)) { string label = string.IsNullOrEmpty(acc.Name) ? $"#{acc.AccountId}" : $"{acc.Name} (#{acc.AccountId}){(acc.IsDemo ? " · Demo" : "")}"; - int idx = _accounts.Items.Add(new AccountItem(acc.AccountId, label)); - _accounts.SetItemChecked(idx, trader.AssignedAccountIds.Contains(acc.AccountId)); + int idx = clbAccounts.Items.Add(new AccountItem(acc.AccountId, label)); + clbAccounts.SetItemChecked(idx, trader.AssignedAccountIds.Contains(acc.AccountId)); } } private void ClearDetail() { _current = null; - _detail.SelectedObject = null; - _accounts.Items.Clear(); + pgDetail.SelectedObject = null; + clbAccounts.Items.Clear(); } private void AddNew() @@ -167,25 +88,25 @@ namespace PolyTrader.Modules.CopyTrading.Ui int nextId = _binding.Count > 0 ? _binding.Max(t => t.Id) + 1 : 1; var trader = new TrackedTrader { Id = nextId, DisplayName = $"Neuer Trader {nextId}" }; _binding.Add(trader); - _grid.CurrentCell = _grid.Rows[_binding.Count - 1].Cells[0]; - _hint.Text = $"Neuer Master-Trader #{nextId} – Felder ausfüllen und Speichern."; + grid.CurrentCell = grid.Rows[_binding.Count - 1].Cells[0]; + lblHint.Text = $"Neuer Master-Trader #{nextId} – Felder ausfüllen und Speichern."; } private void SaveCurrent() { - if (_current == null) { _hint.Text = "Kein Trader ausgewählt."; return; } + if (_current == null) { lblHint.Text = "Kein Trader ausgewählt."; return; } - _current.AssignedAccountIds = _accounts.CheckedItems.Cast().Select(a => a.Id).ToHashSet(); + _current.AssignedAccountIds = clbAccounts.CheckedItems.Cast().Select(a => a.Id).ToHashSet(); _repo.Upsert(_current); _copyState.Traders[_current.Id] = _current; - _grid.Refresh(); - _hint.Text = $"Gespeichert: #{_current.Id} {_current.DisplayName} ({_current.AssignedAccountIds.Count} Account(s)) um {DateTime.Now:HH:mm:ss}."; + grid.Refresh(); + lblHint.Text = $"Gespeichert: #{_current.Id} {_current.DisplayName} ({_current.AssignedAccountIds.Count} Account(s)) um {DateTime.Now:HH:mm:ss}."; } private void DeleteCurrent() { - if (_current == null) { _hint.Text = "Kein Trader ausgewählt."; return; } + if (_current == null) { lblHint.Text = "Kein Trader ausgewählt."; return; } var id = _current.Id; if (MessageBox.Show($"Master-Trader #{id} ({_current.DisplayName}) wirklich löschen?", "Löschen bestätigen", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) @@ -195,7 +116,7 @@ namespace PolyTrader.Modules.CopyTrading.Ui _copyState.Traders.TryRemove(id, out _); _binding.Remove(_current); ClearDetail(); - _hint.Text = $"Master-Trader #{id} gelöscht."; + lblHint.Text = $"Master-Trader #{id} gelöscht."; } private sealed record AccountItem(int Id, string Label)