From 7a4bc2a2fb3768a469d6e8218d479d52d03b98be Mon Sep 17 00:00:00 2001 From: "zhengxuan.zhang" Date: Wed, 1 Apr 2026 15:51:36 +0800 Subject: [PATCH] =?UTF-8?q?#0051=20=E8=B0=83=E6=95=B4CNC=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=9B=86=E6=88=90=E7=A1=AC=E4=BB=B6?= =?UTF-8?q?DLL=E7=9A=84=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/RAYSOURCE_VIEW_INTEGRATION_TECHNICAL.md | 171 ++++++++++++++++++ XplorePlane/Views/Cnc/CncEditorWindow.xaml | 4 +- XplorePlane/Views/Cnc/CncEditorWindow.xaml.cs | 9 + XplorePlane/Views/Cnc/CncPageView.xaml | 58 +++--- .../Views/Cnc/MatrixEditorWindow.xaml.cs | 9 + 5 files changed, 219 insertions(+), 32 deletions(-) create mode 100644 Doc/RAYSOURCE_VIEW_INTEGRATION_TECHNICAL.md diff --git a/Doc/RAYSOURCE_VIEW_INTEGRATION_TECHNICAL.md b/Doc/RAYSOURCE_VIEW_INTEGRATION_TECHNICAL.md new file mode 100644 index 0000000..39b0b43 --- /dev/null +++ b/Doc/RAYSOURCE_VIEW_INTEGRATION_TECHNICAL.md @@ -0,0 +1,171 @@ +# RaySourceOperateView 集成技术路线 + +## 整体架构 + +采用 **DLL 直接引用 + Prism DI 容器手动注册 + AutoWireViewModel 自动装配** 的集成方式。 + +DLL 提供完整的 MVVM 三层(View / ViewModel / Service),主项目负责 DI 注册和 XAML 布局嵌入,数据通过注入的服务接口和 Prism EventAggregator 在两侧流动。 + +--- + +## 分层说明 + +### 1. DLL 引用层 + +`XP.Hardware.RaySource.dll` 放置于 `Libs/Hardware/` 目录,通过 `.csproj` 的 `` 引用。 + +DLL 内部包含: + +| 类型 | 名称 | 说明 | +|------|------|------| +| UserControl | `RaySourceOperateView` | 射线源操作界面 | +| ViewModel | `RaySourceOperateViewModel` | 对应 ViewModel | +| 服务接口/实现 | `IRaySourceService` / `RaySourceService` | 射线源业务逻辑 | +| 工厂 | `IRaySourceFactory` / `RaySourceFactory` | 策略工厂,支持 Comet225/320、Spellman225 | +| 服务 | `IFilamentLifetimeService` | 灯丝寿命管理 | +| 配置模型 | `RaySourceConfig` | 从 App.config 加载的配置 | + +--- + +### 2. DI 注册层(App.xaml.cs → AppBootstrapper) + +主项目在 `RegisterTypes()` 中**手动注册** DLL 内所有服务,未走 Prism 的 `ConfigureModuleCatalog` 自动模块加载,目的是避免模块加载顺序问题,确保 DryIoc 容器在 Shell 创建前已具备所有依赖。 + +```csharp +// 注册 ViewModel(供 ViewModelLocator 自动装配) +containerRegistry.Register(); + +// 注册配置(从 App.config 读取 RaySource:xxx 键值) +var raySourceConfig = XP.Hardware.RaySource.Config.ConfigLoader.LoadConfig(); +containerRegistry.RegisterInstance(raySourceConfig); + +// 注册核心服务(全部单例) +containerRegistry.RegisterSingleton(); +containerRegistry.RegisterSingleton(); +containerRegistry.RegisterSingleton(); +``` + +--- + +### 3. XAML 嵌入层(MainWindow.xaml) + +通过 XML 命名空间直接引用 DLL 中的 View: + +```xml +xmlns:views1="clr-namespace:XP.Hardware.RaySource.Views;assembly=XP.Hardware.RaySource" +``` + +在主窗口右侧面板顶部(Grid.Row="0",固定高度 250px)放置控件: + +```xml + +``` + +控件内部已设置 `prism:ViewModelLocator.AutoWireViewModel="True"`,Prism 按命名约定自动从 DI 容器解析 `RaySourceOperateViewModel` 并绑定为 DataContext。 + +--- + +### 4. 数据传递路线 + +数据流分四条路径: + +**路径 A:配置数据(启动时,单向下行)** + +``` +App.config (RaySource:xxx 键值) + → ConfigLoader.LoadConfig() + → RaySourceConfig 实例 + → 注入到 RaySourceService / RaySourceOperateViewModel +``` + +App.config 中的关键配置项: + +```xml + + + + + +``` + +**路径 B:用户操作(UI → DLL 服务层)** + +``` +RaySourceOperateView(按钮点击) + → RaySourceOperateViewModel(Command 绑定) + → IRaySourceService.SetVoltageAsync() / TurnOnAsync() / ... + → IXRaySource(具体策略实现,如 Comet225) + → 硬件通讯(B&R PVI / BR.AN.PviServices.dll) +``` + +**路径 C:状态回传(DLL 服务层 → UI)** + +``` +硬件状态轮询(StatusPollingInterval = 500ms) + → RaySourceService 内部更新 + → RaySourceOperateViewModel 属性变更(INotifyPropertyChanged) + → RaySourceOperateView 数据绑定自动刷新 + +同时: + → AppStateService 订阅 IRaySourceService 事件 + → 更新 RaySourceState(IsOn, Voltage, Power) + → Dispatcher.BeginInvoke 调度到 UI 线程 + → 其他 ViewModel 通过 IAppStateService 读取全局射线源状态 +``` + +`RaySourceState` 为不可变 record,定义于 `Models/StateModels.cs`: + +```csharp +public record RaySourceState( + bool IsOn, // 开关状态 + double Voltage, // 电压 (kV) + double Power // 功率 (W) +) +{ + public static readonly RaySourceState Default = new(false, 0, 0); +} +``` + +**路径 D:跨模块事件通讯(Prism EventAggregator)** + +``` +DLL 内部发布事件(XP.Hardware.RaySource.Abstractions.Events): + XrayStateChangedEvent — 射线开关状态变化 + StatusUpdatedEvent — 实时电压/电流数据 + ErrorOccurredEvent — 错误通知 + OperationResultEvent — 操作结果回调 + +主项目任意 ViewModel 订阅示例: + _eventAggregator.GetEvent().Subscribe(data => { ... }); +``` + +--- + +### 5. 完整依赖关系 + +``` +RaySourceOperateView(DLL 中的 UserControl) + └─ AutoWire → RaySourceOperateViewModel(DLL,主项目注册到 DI) + ├─ IRaySourceService ← 单例,DLL 实现 + ├─ RaySourceConfig ← App.config 加载 + ├─ IFilamentLifetimeService ← 单例,DLL 实现 + ├─ IEventAggregator ← Prism 内置 + ├─ ILoggerService ← 主项目 LoggerServiceAdapter 适配 Serilog + └─ ILocalizationService ← 主项目注册,DLL 消费 +``` + +--- + +### 6. 资源释放 + +`App.OnExit()` 中显式从容器解析并释放资源: + +```csharp +var appStateService = bootstrapper.Container.Resolve(); +appStateService?.Dispose(); + +var raySourceService = bootstrapper.Container.Resolve(); +raySourceService?.Dispose(); +``` + +确保硬件连接在应用退出时正确断开。 diff --git a/XplorePlane/Views/Cnc/CncEditorWindow.xaml b/XplorePlane/Views/Cnc/CncEditorWindow.xaml index 29a78ba..654cd01 100644 --- a/XplorePlane/Views/Cnc/CncEditorWindow.xaml +++ b/XplorePlane/Views/Cnc/CncEditorWindow.xaml @@ -4,10 +4,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cnc="clr-namespace:XplorePlane.Views.Cnc" Title="CNC 编辑器" - Width="1200" + Width="350" Height="750" - MinWidth="900" - MinHeight="550" ShowInTaskbar="False" WindowStartupLocation="CenterOwner"> diff --git a/XplorePlane/Views/Cnc/CncEditorWindow.xaml.cs b/XplorePlane/Views/Cnc/CncEditorWindow.xaml.cs index e3ce395..1c326f7 100644 --- a/XplorePlane/Views/Cnc/CncEditorWindow.xaml.cs +++ b/XplorePlane/Views/Cnc/CncEditorWindow.xaml.cs @@ -1,4 +1,7 @@ +using System; +using System.Runtime.InteropServices; using System.Windows; +using System.Windows.Interop; namespace XplorePlane.Views.Cnc { @@ -7,6 +10,12 @@ namespace XplorePlane.Views.Cnc public CncEditorWindow() { InitializeComponent(); + SourceInitialized += OnSourceInitialized; + } + + private void OnSourceInitialized(object sender, EventArgs e) + { + WindowIconHelper.RemoveIcon(this); } } } diff --git a/XplorePlane/Views/Cnc/CncPageView.xaml b/XplorePlane/Views/Cnc/CncPageView.xaml index fc212a7..27c11ef 100644 --- a/XplorePlane/Views/Cnc/CncPageView.xaml +++ b/XplorePlane/Views/Cnc/CncPageView.xaml @@ -1,4 +1,4 @@ - + - + Microsoft YaHei UI - + - +