refactor: 插件 UI 从 WinForms 迁移到 CycleGUI,并修复代码质量问题

将 StandardScene 各插件的配置/监控窗体从 WinForms 迁移到 CycleGUI(删除 .Designer.cs/.resx,重写为 PanelBuilder 立即模式 UI,新增 CycleUiHelper 统一对话框)。

同时修复代码审核中的问题:
- 后台文件写入加锁 + try/catch(ButtonBoxManager / DoorManager,对齐 LoopViewer.SaveTasks 模式)
- CoderFieldsMetadata.cs 启用 #nullable enable,消除 CS8632 警告
- DummyCar 移除已废弃的 rightClickAction()/SetPosition()
- CarRemoteHelper.OpenVehicleWebPage 的 Process.Start 加 try/catch
- 重命名名不副实的 Mstsc()(现为打开网页)
- 统一弃元命名为 _
- TrafficInterlockViewer 改用稳定 Id(GUID)做选择/编辑,替代行索引
- csproj 改用 $(CGUILibDir) 解析 CycleGUI,绝对路径收敛到 Directory.Build.props

构建:dotnet build StandardScene.sln → 0 错误,30 警告(均为历史遗留)。
注:static 单例状态重构(审核第 8 项)暂未处理,留待单独任务。
This commit is contained in:
zhaowei.huang
2026-06-26 15:00:53 +08:00
parent c8e540d272
commit a0dc1e6cd0
91 changed files with 3946 additions and 15419 deletions
@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using CycleGUI;
using SimpleCore;
using SimpleCore.Library;
using StandardScene.Utils;
namespace StandardScene.Charge
{
@@ -13,36 +14,11 @@ namespace StandardScene.Charge
/// </summary>
public static class ChargeStationHelper
{
private static ChargeStationManagementForm _managementForm;
/// <summary>打开充电桩管理面板(单实例)。</summary>
public static void OpenManagementWindow() => ChargeStationManagementForm.Open();
/// <summary>
/// 打开充电桩管理窗口(单例模式)
/// </summary>
public static void OpenManagementWindow()
{
if (_managementForm == null || _managementForm.IsDisposed)
{
_managementForm = new ChargeStationManagementForm();
_managementForm.FormClosed += (s, e) => _managementForm = null;
_managementForm.Show();
}
else
{
_managementForm.BringToFront();
_managementForm.Activate();
}
}
/// <summary>
/// 打开充电桩管理窗口(对话框模式)
/// </summary>
public static DialogResult OpenManagementDialog()
{
using (var form = new ChargeStationManagementForm())
{
return form.ShowDialog();
}
}
/// <summary>打开充电桩管理面板(兼容旧 API)。</summary>
public static void OpenManagementDialog() => ChargeStationManagementForm.Open();
/// <summary>
/// 获取指定站点的充电桩
@@ -297,65 +273,44 @@ namespace StandardScene.Charge
return success;
}
/// <summary>
/// 显示充电桩选择对话框
/// </summary>
/// <param name="filterByStatus">按状态过滤(null表示显示全部)</param>
/// <returns>选中的充电桩,取消则返回null</returns>
public static ChargeStation ShowStationSelectionDialog(ChargeStationStatus? filterByStatus = null)
/// <summary>显示充电桩选择面板(非阻塞;通过 <paramref name="onSelected"/> 回调返回结果)。</summary>
public static void ShowStationSelectionDialog(ChargeStationStatus? filterByStatus, System.Action<ChargeStation> onSelected)
{
var dataService = ChargeStationDataService.Instance;
var stations = dataService.GetAllStations();
var stations = ChargeStationDataService.Instance.GetAllStations();
if (filterByStatus.HasValue)
{
stations = stations.Where(s => s.Status == filterByStatus.Value).ToList();
}
if (stations.Count == 0)
{
MessageBox.Show("没有符合条件的充电桩", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;
CycleUiHelper.Alert("提示", "没有符合条件的充电桩");
onSelected?.Invoke(null);
return;
}
// 创建简单的选择对话框
using (var dialog = new Form())
var labels = stations.Select(s =>
$"[{s.StationId}] {s.Name} - {s.IpAddress}:{s.Port} - {GetStatusText(s.Status)}").ToArray();
int sel = 0;
var dlg = GUI.DeclarePanel()
.ShowTitle("选择充电桩")
.TopMost(true)
.InitSize(520, 400)
.InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
dlg.Define(pb =>
{
dialog.Text = "选择充电桩";
dialog.Size = new System.Drawing.Size(500, 400);
dialog.StartPosition = FormStartPosition.CenterParent;
var listBox = new ListBox
if (pb.Closing()) { dlg.Exit(); onSelected?.Invoke(null); return; }
sel = pb.ListBox("充电桩", labels, height: 12);
if (pb.Button("确定", distinct: "cs-pick-ok"))
{
Dock = DockStyle.Fill,
Font = new System.Drawing.Font("微软雅黑", 10F)
};
foreach (var station in stations)
{
listBox.Items.Add($"[{station.StationId}] {station.Name} - {station.IpAddress}:{station.Port} - {GetStatusText(station.Status)}");
dlg.Exit();
onSelected?.Invoke(sel >= 0 && sel < stations.Count ? stations[sel] : null);
}
var btnOK = new Button
pb.SameLine(8);
if (pb.Button("取消", distinct: "cs-pick-cancel"))
{
Text = "确定",
DialogResult = DialogResult.OK,
Dock = DockStyle.Bottom,
Height = 40
};
dialog.Controls.Add(listBox);
dialog.Controls.Add(btnOK);
dialog.AcceptButton = btnOK;
if (dialog.ShowDialog() == DialogResult.OK && listBox.SelectedIndex >= 0)
{
return stations[listBox.SelectedIndex];
dlg.Exit();
onSelected?.Invoke(null);
}
return null;
}
});
}
/// <summary>