Phase 5-UI: Views sind echte Forms + Launcher-Offen-Status
- ModuleView liefert jetzt ein Form (CreateForm statt CreateControl); die 4 Views (Terminal, Settings, Jobs, Dashboard) von UserControl auf Form umgestellt (im Designer als Fenster bearbeitbar). ViewHostForm entfernt. - ShellUiHost verwaltet offene Forms: Einzelinstanz, bereits offenes Fenster wird in den Vordergrund geholt, OpenStateChanged-Event. - LauncherForm: Fenster-Buttons an View-IDs gebunden; offene Fenster werden am Button markiert (Checked), erneuter Klick holt das Fenster nach vorn. - Build 0 Fehler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ff1db2aea0
commit
ad5ba34b56
+4
-12
@@ -138,9 +138,7 @@ internal static class Program
|
||||
Title = "Terminal",
|
||||
Group = "Core",
|
||||
Order = 10,
|
||||
PreferredWidth = 1000,
|
||||
PreferredHeight = 650,
|
||||
CreateControl = () =>
|
||||
CreateForm = () =>
|
||||
{
|
||||
var view = new PolyTraderSharp.Ui.Views.TerminalView();
|
||||
view.Initialize(viewServices.GetRequiredService<TerminalLogger>());
|
||||
@@ -153,9 +151,7 @@ internal static class Program
|
||||
Title = "Server Settings",
|
||||
Group = "Core",
|
||||
Order = 20,
|
||||
PreferredWidth = 720,
|
||||
PreferredHeight = 720,
|
||||
CreateControl = () =>
|
||||
CreateForm = () =>
|
||||
{
|
||||
var view = new PolyTraderSharp.Ui.Views.SettingsView();
|
||||
view.Initialize(
|
||||
@@ -171,9 +167,7 @@ internal static class Program
|
||||
Title = "Server Jobs",
|
||||
Group = "Core",
|
||||
Order = 30,
|
||||
PreferredWidth = 1000,
|
||||
PreferredHeight = 500,
|
||||
CreateControl = () =>
|
||||
CreateForm = () =>
|
||||
{
|
||||
var view = new PolyTraderSharp.Ui.Views.JobsView();
|
||||
view.Initialize(viewServices.GetRequiredService<JobManager>());
|
||||
@@ -186,9 +180,7 @@ internal static class Program
|
||||
Title = "Dashboard",
|
||||
Group = "Core",
|
||||
Order = 5,
|
||||
PreferredWidth = 1200,
|
||||
PreferredHeight = 650,
|
||||
CreateControl = () =>
|
||||
CreateForm = () =>
|
||||
{
|
||||
var view = new PolyTraderSharp.Ui.Views.DashboardView();
|
||||
view.Initialize(
|
||||
|
||||
Generated
+10
@@ -100,6 +100,16 @@ namespace PolyTraderSharp.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap dashboard {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("dashboard", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
||||
@@ -118,20 +118,26 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="system_time" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\system_time.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="diskette" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\diskette.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="money" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\money.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="traffic_lights_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\traffic_lights_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="money_add" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\money_add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="token_quantifier" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\token_quantifier.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="traffic_lights_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\traffic_lights_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="error_log" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\error_log.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="cancel" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\cancel.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
@@ -145,9 +151,6 @@
|
||||
<data name="coins_in_hand" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\coins_in_hand.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="error_log" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\error_log.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="add" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
@@ -172,7 +175,7 @@
|
||||
<data name="money_dollar" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\money_dollar.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="system_time" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\system_time.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="dashboard" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\dashboard.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Generated
+15
-11
@@ -22,10 +22,10 @@ namespace PolyTraderSharp.Ui
|
||||
miLegacy = new ToolStripMenuItem();
|
||||
miBeenden = new ToolStripMenuItem();
|
||||
toolstrip_windows = new ToolStrip();
|
||||
btn_dashboard = new ToolStripButton();
|
||||
btn_settings = new ToolStripButton();
|
||||
btn_terminal = new ToolStripButton();
|
||||
btn_jobs = new ToolStripButton();
|
||||
btn_dashboard = new ToolStripButton();
|
||||
toolstrip_quickbar = new ToolStrip();
|
||||
btn_liveTrading = new ToolStripButton();
|
||||
btn_demoTrading = new ToolStripButton();
|
||||
@@ -72,13 +72,23 @@ namespace PolyTraderSharp.Ui
|
||||
//
|
||||
toolstrip_windows.AutoSize = false;
|
||||
toolstrip_windows.ImageScalingSize = new Size(64, 64);
|
||||
toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_settings, btn_terminal, btn_jobs, btn_dashboard });
|
||||
toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_dashboard, btn_settings, btn_terminal, btn_jobs });
|
||||
toolstrip_windows.Location = new Point(0, 35);
|
||||
toolstrip_windows.Name = "toolstrip_windows";
|
||||
toolstrip_windows.Size = new Size(2599, 70);
|
||||
toolstrip_windows.TabIndex = 3;
|
||||
toolstrip_windows.Text = "toolStrip1";
|
||||
//
|
||||
// btn_dashboard
|
||||
//
|
||||
btn_dashboard.Image = Properties.Resources.dashboard;
|
||||
btn_dashboard.ImageScaling = ToolStripItemImageScaling.None;
|
||||
btn_dashboard.Name = "btn_dashboard";
|
||||
btn_dashboard.Overflow = ToolStripItemOverflow.Never;
|
||||
btn_dashboard.Size = new Size(104, 65);
|
||||
btn_dashboard.Text = "Dashboard";
|
||||
btn_dashboard.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||
//
|
||||
// btn_settings
|
||||
//
|
||||
btn_settings.BackColor = SystemColors.Control;
|
||||
@@ -108,13 +118,6 @@ namespace PolyTraderSharp.Ui
|
||||
btn_jobs.Text = "Server Jobs";
|
||||
btn_jobs.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||
//
|
||||
// btn_dashboard
|
||||
//
|
||||
btn_dashboard.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||
btn_dashboard.Name = "btn_dashboard";
|
||||
btn_dashboard.Size = new Size(110, 65);
|
||||
btn_dashboard.Text = "Dashboard";
|
||||
//
|
||||
// toolstrip_quickbar
|
||||
//
|
||||
toolstrip_quickbar.ImageScalingSize = new Size(24, 24);
|
||||
@@ -144,7 +147,7 @@ namespace PolyTraderSharp.Ui
|
||||
statusStrip_info.BackColor = Color.Gainsboro;
|
||||
statusStrip_info.ImageScalingSize = new Size(24, 24);
|
||||
statusStrip_info.Items.AddRange(new ToolStripItem[] { lbl_trading, lbl_modules, lbl_ratelimit });
|
||||
statusStrip_info.Location = new Point(0, 133);
|
||||
statusStrip_info.Location = new Point(0, 140);
|
||||
statusStrip_info.Name = "statusStrip_info";
|
||||
statusStrip_info.Size = new Size(2599, 32);
|
||||
statusStrip_info.TabIndex = 5;
|
||||
@@ -172,11 +175,12 @@ namespace PolyTraderSharp.Ui
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(10F, 25F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(2599, 165);
|
||||
ClientSize = new Size(2599, 172);
|
||||
Controls.Add(statusStrip_info);
|
||||
Controls.Add(toolstrip_quickbar);
|
||||
Controls.Add(toolstrip_windows);
|
||||
Controls.Add(menuStrip);
|
||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||
MainMenuStrip = menuStrip;
|
||||
Margin = new Padding(4, 5, 4, 5);
|
||||
Name = "LauncherForm";
|
||||
|
||||
+28
-15
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -19,6 +20,7 @@ namespace PolyTraderSharp.Ui
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly TradingState _state;
|
||||
private readonly System.Windows.Forms.Timer _statusTimer = new() { Interval = 1000 };
|
||||
private readonly Dictionary<string, ToolStripButton> _viewButtons;
|
||||
private frm_main? _legacyForm;
|
||||
|
||||
public LauncherForm(ShellUiHost uiHost, IServiceProvider services)
|
||||
@@ -29,19 +31,40 @@ namespace PolyTraderSharp.Ui
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
btn_settings.Click += (_, _) => OpenView("core.settings");
|
||||
btn_terminal.Click += (_, _) => OpenView("core.terminal");
|
||||
btn_jobs.Click += (_, _) => OpenView("core.jobs");
|
||||
btn_dashboard.Click += (_, _) => OpenView("core.dashboard");
|
||||
// Fenster-Buttons an stabile View-IDs binden (Views werden per DI registriert).
|
||||
_viewButtons = new Dictionary<string, ToolStripButton>
|
||||
{
|
||||
["core.dashboard"] = btn_dashboard,
|
||||
["core.settings"] = btn_settings,
|
||||
["core.terminal"] = btn_terminal,
|
||||
["core.jobs"] = btn_jobs,
|
||||
};
|
||||
foreach (var (id, btn) in _viewButtons)
|
||||
{
|
||||
var viewId = id;
|
||||
btn.Click += (_, _) => _uiHost.OpenView(viewId);
|
||||
}
|
||||
|
||||
btn_liveTrading.Click += (_, _) => CycleLiveTrading();
|
||||
btn_demoTrading.Click += (_, _) => CycleDemoTrading();
|
||||
miLegacy.Click += (_, _) => OpenLegacy();
|
||||
miBeenden.Click += (_, _) => Close();
|
||||
|
||||
// Offen-Status der Fenster spiegeln (Button „checked", wenn Fenster offen).
|
||||
_uiHost.OpenStateChanged += UpdateWindowButtonStates;
|
||||
|
||||
_statusTimer.Tick += (_, _) => UpdateStatus();
|
||||
_statusTimer.Start();
|
||||
UpdateStatus();
|
||||
UpdateTradingToggles();
|
||||
UpdateWindowButtonStates();
|
||||
}
|
||||
|
||||
private void UpdateWindowButtonStates()
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
foreach (var (id, btn) in _viewButtons)
|
||||
btn.Checked = _uiHost.IsOpen(id);
|
||||
}
|
||||
|
||||
private void CycleLiveTrading()
|
||||
@@ -91,17 +114,6 @@ namespace PolyTraderSharp.Ui
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Öffnet die Ansicht mit der angegebenen ID (bzw. fokussiert das offene Fenster).</summary>
|
||||
private void OpenView(string viewId)
|
||||
{
|
||||
var view = _uiHost.Views.FirstOrDefault(v => v.Id == viewId);
|
||||
if (view != null)
|
||||
_uiHost.OpenView(view);
|
||||
else
|
||||
MessageBox.Show($"Ansicht '{viewId}' ist (noch) nicht registriert.", "Hinweis",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
string trading = _state.GlobalTradingPaused
|
||||
@@ -116,6 +128,7 @@ namespace PolyTraderSharp.Ui
|
||||
|
||||
// Toggle-Buttons mit externem State synchron halten (z.B. Änderungen aus der Legacy-UI).
|
||||
UpdateTradingToggles();
|
||||
UpdateWindowButtonStates();
|
||||
}
|
||||
|
||||
private void OpenLegacy()
|
||||
|
||||
+32
-7
@@ -1,22 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using PolyTrader.Core.Modularity;
|
||||
|
||||
namespace PolyTraderSharp.Ui
|
||||
{
|
||||
/// <summary>
|
||||
/// Sammelt die von Core-App und Modulen registrierten Views und öffnet sie als
|
||||
/// eigenständige Host-Fenster (Einzelinstanz je View).
|
||||
/// Verwaltet die registrierten Fenster-Views: öffnet sie als eigenständige Forms,
|
||||
/// hält je View höchstens eine Instanz offen und holt ein bereits offenes Fenster
|
||||
/// wieder in den Vordergrund. Meldet Änderungen am Offen-Status (für die
|
||||
/// Button-Markierung im Launcher).
|
||||
/// </summary>
|
||||
public class ShellUiHost : IModuleUiHost
|
||||
{
|
||||
private readonly List<ModuleView> _views = new();
|
||||
private readonly Dictionary<string, ViewHostForm> _open = new();
|
||||
private readonly Dictionary<string, Form> _open = new();
|
||||
|
||||
/// <summary>Wird ausgelöst, wenn sich der Offen-Status irgendeiner View ändert.</summary>
|
||||
public event Action? OpenStateChanged;
|
||||
|
||||
public IReadOnlyList<ModuleView> Views => _views;
|
||||
|
||||
public void RegisterView(ModuleView view) => _views.Add(view);
|
||||
|
||||
public bool IsOpen(string viewId) =>
|
||||
_open.TryGetValue(viewId, out var form) && !form.IsDisposed;
|
||||
|
||||
public void OpenView(string viewId)
|
||||
{
|
||||
var view = _views.FirstOrDefault(v => v.Id == viewId);
|
||||
if (view != null) OpenView(view);
|
||||
}
|
||||
|
||||
public void OpenView(ModuleView view)
|
||||
{
|
||||
if (_open.TryGetValue(view.Id, out var existing) && !existing.IsDisposed)
|
||||
@@ -28,10 +44,19 @@ namespace PolyTraderSharp.Ui
|
||||
return;
|
||||
}
|
||||
|
||||
var host = new ViewHostForm(view);
|
||||
host.FormClosed += (_, _) => _open.Remove(view.Id);
|
||||
_open[view.Id] = host;
|
||||
host.Show();
|
||||
var form = view.CreateForm();
|
||||
if (string.IsNullOrEmpty(form.Text) || form.Text == form.Name)
|
||||
form.Text = view.Title;
|
||||
|
||||
_open[view.Id] = form;
|
||||
form.FormClosed += (_, _) =>
|
||||
{
|
||||
_open.Remove(view.Id);
|
||||
OpenStateChanged?.Invoke();
|
||||
};
|
||||
|
||||
form.Show();
|
||||
OpenStateChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Windows.Forms;
|
||||
using PolyTrader.Core.Modularity;
|
||||
|
||||
namespace PolyTraderSharp.Ui
|
||||
{
|
||||
/// <summary>
|
||||
/// Generisches Host-Fenster für genau eine <see cref="ModuleView"/>. Erzeugt das
|
||||
/// (designbare) Control der View und dockt es formfüllend. Die Shell öffnet je View
|
||||
/// höchstens eine Instanz (siehe <see cref="ShellUiHost"/>).
|
||||
/// </summary>
|
||||
public class ViewHostForm : Form
|
||||
{
|
||||
public string ViewId { get; }
|
||||
|
||||
public ViewHostForm(ModuleView view)
|
||||
{
|
||||
ViewId = view.Id;
|
||||
Text = view.Title;
|
||||
Width = view.PreferredWidth;
|
||||
Height = view.PreferredHeight;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
|
||||
var control = view.CreateControl();
|
||||
control.Dock = DockStyle.Fill;
|
||||
Controls.Add(control);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+2
-1
@@ -173,8 +173,9 @@ namespace PolyTraderSharp.Ui.Views
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.dgvTrades);
|
||||
this.Controls.Add(this.pnlTop);
|
||||
this.ClientSize = new System.Drawing.Size(1200, 650);
|
||||
this.Name = "DashboardView";
|
||||
this.Size = new System.Drawing.Size(1100, 600);
|
||||
this.Text = "Dashboard";
|
||||
this.pnlTop.ResumeLayout(false);
|
||||
this.pnlTop.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dgvTrades)).EndInit();
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace PolyTraderSharp.Ui.Views
|
||||
/// generischen Core-Trade-Log (ITradeLogRepository) und eine Kurzauswertung.
|
||||
/// Designbar (DashboardView.Designer.cs).
|
||||
/// </summary>
|
||||
public partial class DashboardView : UserControl
|
||||
public partial class DashboardView : Form
|
||||
{
|
||||
private ITradeLogRepository? _tradeLog;
|
||||
private TradingState? _state;
|
||||
|
||||
Generated
+2
-1
@@ -109,8 +109,9 @@ namespace PolyTraderSharp.Ui.Views
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.dgvJobs);
|
||||
this.ClientSize = new System.Drawing.Size(1000, 500);
|
||||
this.Name = "JobsView";
|
||||
this.Size = new System.Drawing.Size(900, 500);
|
||||
this.Text = "Server Jobs";
|
||||
((System.ComponentModel.ISupportInitialize)(this.dgvJobs)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PolyTraderSharp.Ui.Views
|
||||
/// Verhalten wie der bisherige Jobs-Tab: „Run Now" löst den ManualTrigger aus,
|
||||
/// „Aktiv" schaltet den Job über die Bindung.
|
||||
/// </summary>
|
||||
public partial class JobsView : UserControl
|
||||
public partial class JobsView : Form
|
||||
{
|
||||
public JobsView()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Generated
+2
-1
@@ -66,8 +66,9 @@ namespace PolyTraderSharp.Ui.Views
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.propertyGrid);
|
||||
this.Controls.Add(this.pnlTop);
|
||||
this.ClientSize = new System.Drawing.Size(720, 720);
|
||||
this.Name = "SettingsView";
|
||||
this.Size = new System.Drawing.Size(700, 600);
|
||||
this.Text = "Server Settings";
|
||||
this.pnlTop.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PolyTraderSharp.Ui.Views
|
||||
/// Designbar (siehe SettingsView.Designer.cs); Laufzeit-Abhängigkeiten via Initialize.
|
||||
/// Verhalten entspricht dem bisherigen Settings-Tab (Speichern -> XML + Services neu laden).
|
||||
/// </summary>
|
||||
public partial class SettingsView : UserControl
|
||||
public partial class SettingsView : Form
|
||||
{
|
||||
private const string SettingsPath = "server_settings.xml";
|
||||
|
||||
|
||||
Generated
+2
-1
@@ -90,8 +90,9 @@ namespace PolyTraderSharp.Ui.Views
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.rtbTerminal);
|
||||
this.Controls.Add(this.pnlTop);
|
||||
this.ClientSize = new System.Drawing.Size(1000, 650);
|
||||
this.Name = "TerminalView";
|
||||
this.Size = new System.Drawing.Size(900, 500);
|
||||
this.Text = "Terminal / Logs";
|
||||
this.pnlTop.ResumeLayout(false);
|
||||
this.pnlTop.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PolyTraderSharp.Ui.Views
|
||||
/// Abhängigkeit (TerminalLogger) wird per <see cref="Initialize"/> injiziert, damit der
|
||||
/// parameterlose Konstruktor für den VS-Designer nutzbar bleibt.
|
||||
/// </summary>
|
||||
public partial class TerminalView : UserControl
|
||||
public partial class TerminalView : Form
|
||||
{
|
||||
private TerminalLogger? _logger;
|
||||
private readonly ConcurrentQueue<LogMessageEventArgs> _logQueue = new();
|
||||
|
||||
@@ -4,35 +4,32 @@ using System.Windows.Forms;
|
||||
namespace PolyTrader.Core.Modularity
|
||||
{
|
||||
/// <summary>
|
||||
/// Eine vom Core oder einem Modul beigesteuerte UI-Ansicht. Die Shell entscheidet,
|
||||
/// wie sie präsentiert wird (aktuell: eigenständiges Host-Fenster über den Launcher).
|
||||
/// Die eigentliche UI ist ein designbares <see cref="Control"/> (i.d.R. ein UserControl),
|
||||
/// das über <see cref="CreateControl"/> erzeugt wird (mit DI-Abhängigkeiten).
|
||||
/// Eine vom Core oder einem Modul beigesteuerte Fenster-Ansicht. Die eigentliche UI ist
|
||||
/// ein designbares <see cref="Form"/>, das über <see cref="CreateForm"/> erzeugt wird
|
||||
/// (mit DI-Abhängigkeiten). Die Shell zeigt je View höchstens eine Instanz und holt ein
|
||||
/// bereits offenes Fenster wieder in den Vordergrund.
|
||||
/// </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 für Launcher-Eintrag und Fenstertitel.</summary>
|
||||
public string Title { get; init; } = "View";
|
||||
/// <summary>Titel (Fallback-Fenstertitel, falls das Form keinen eigenen setzt).</summary>
|
||||
public string Title { get; init; } = "Fenster";
|
||||
|
||||
/// <summary>Optionale Gruppierung im Launcher (z.B. "Core", "CopyTrading").</summary>
|
||||
/// <summary>Optionale Gruppierung (z.B. "Core", "CopyTrading").</summary>
|
||||
public string? Group { get; init; }
|
||||
|
||||
/// <summary>Optionale Sortierreihenfolge im Launcher.</summary>
|
||||
/// <summary>Optionale Sortierreihenfolge.</summary>
|
||||
public int Order { get; init; } = 0;
|
||||
|
||||
/// <summary>Erzeugt das anzuzeigende Control (frische Instanz je Fensteröffnung).</summary>
|
||||
public Func<Control> CreateControl { get; init; } = () => new Control();
|
||||
|
||||
public int PreferredWidth { get; init; } = 900;
|
||||
public int PreferredHeight { get; init; } = 600;
|
||||
/// <summary>Erzeugt das anzuzeigende Fenster (frische Instanz je Öffnung).</summary>
|
||||
public Func<Form> CreateForm { get; init; } = () => new Form();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wird der Shell beim Start übergeben; Core und Module registrieren hier ihre Ansichten.
|
||||
/// Der Launcher rendert daraus seine Einträge und öffnet je View ein Host-Fenster.
|
||||
/// Die Shell (Launcher) öffnet die Fenster auf Anforderung und verwaltet den Offen-Status.
|
||||
/// </summary>
|
||||
public interface IModuleUiHost
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user