Files
XplorePlane/XP.Hardware.RaySource/Documents/README_RaySourceOperateView.md
T

379 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RaySourceOperateView 使用说明
## 概述
`RaySourceOperateView` 是射线源操作和监控面板,提供射线源开关控制、电压电流实时调节和状态监控功能。
## 架构设计
### MVVM 模式
- **View**: `RaySourceOperateView.xaml` - WPF 用户控件界面
- **ViewModel**: `RaySourceOperateViewModel.cs` - 视图模型,处理业务逻辑
- **Model**: `RaySourceStatus.cs` - 射线源状态枚举(Unavailable / Closed / Opened
### 依赖注入
ViewModel 通过构造函数注入以下依赖:
- `IRaySourceService` - 射线源业务服务
- `IEventAggregator` - Prism 事件聚合器
- `RaySourceConfig` - 射线源配置
- `ILoggerService` - 日志服务
- `ILocalizationService` - 多语言服务
## 功能特性
### 1. 状态监控
- **腰圆状态指示器**
- 灰色径向渐变 = 射线源不可用(Unavailable
- 绿色径向渐变 (#8BC34A#4CAF50) = 射线源已关闭(Closed
- 红色径向渐变 (#FF8A80#F44336) = 射线源已开启(Opened
- **呼吸闪烁动画**:射线源开启时,状态指示器播放呼吸闪烁动画(透明度 1.0 → 0.6 循环,周期约 1.5 秒)
- **实时状态文本**:通过 `ILocalizationService` 获取多语言状态文字
### 2. 射线源控制
- **开启射线源按钮**
- 仅在 Closed 状态、已初始化且变量已连接时可用
- 调用 `IRaySourceService.TurnOn()`
- 按钮文字通过多语言绑定:`{loc:Localization RaySource_TurnOnButton}`
- **关闭射线源按钮**
- 仅在 Opened 状态、已初始化且变量已连接时可用
- 调用 `IRaySourceService.TurnOff()`
- 按钮文字通过多语言绑定:`{loc:Localization RaySource_TurnOffButton}`
- **配置按钮**
- 打开 `RaySourceConfigWindow`(射线源配置窗口)
- 窗口已存在时激活而非重复创建
- **高级/设置按钮**
- 启动外部高级设置程序(`FXEControl.exe`
- 如果程序已运行则将窗口置前
- 使用 `ProcessHelper.StartOrActivate()` 实现
### 3. 电压调节
- **滑块范围**:从配置文件读取(默认 20-225 kV)
- **双向绑定**:滑块和数值输入框绑定同一属性 `VoltageValue`,使用 `Mode=TwoWay`
- **延迟拖拽**:滑块使用 `IsDeferredDraggingEnabled="True"`,松手时才提交值
- **手动提交**:通过 `ApplyVoltageCommand` 提交电压值到硬件(滑块松手/输入框失焦时触发)
- **启用条件**:仅在服务已初始化且变量已连接时可调节(`IsSlidersEnabled`
- **范围显示**:滑块下方显示最小值和最大值
- **实际值显示**:右上角显示当前实际电压值
### 4. 电流调节
- **滑块范围**:从配置文件读取(默认 10-1000 μA)
- **双向绑定**:滑块和数值输入框绑定同一属性 `CurrentValue`,使用 `Mode=TwoWay`
- **延迟拖拽**:滑块使用 `IsDeferredDraggingEnabled="True"`,松手时才提交值
- **手动提交**:通过 `ApplyCurrentCommand` 提交电流值到硬件
- **启用条件**:仅在服务已初始化且变量已连接时可调节(`IsSlidersEnabled`
- **范围显示**:滑块下方显示最小值和最大值
- **实际值显示**:右上角显示当前实际电流值
### 5. 自动初始化
- ViewModel 提供 `AutoInitializeAsync()` 方法
- 由 View 的 `Loaded` 事件触发,仅执行一次
- 异步执行 `InitializeAndConnectAsync()`(初始化 + 连接变量)
- 如果已初始化且变量已连接则跳过
## 关联视图:RaySourceConfigView
`RaySourceConfigView` 是射线源配置和设备状态监控面板,通过 `RaySourceConfigWindow` 包裹为独立窗口。
### ConfigView 功能
- **设备信息**:显示射线源类型和连接状态(颜色编码:灰色=未连接,橙色=已初始化,绿色=变量已连接)
- **操作按钮**:初始化 / 连接变量 / 断开(三列等宽布局)
- **设备状态面板**:暖机/真空/启动/自动定心/灯丝校准/射线开启/连锁/看门狗/TXI/功率模式
- **TXI 控制**TXI ON / TXI OFF 按钮
- **功率模式切换**High Power / Micro Focus 按钮
- **功能设置按钮**:暖机设置 / 训机设置 / 灯丝校准 / 自动定心(四列等宽布局,带确认对话框和进度条窗口)
- **灯丝寿命进度条**:显示灯丝使用百分比(60 秒定时刷新),颜色随百分比变化(绿/黄/红)
### ConfigView 依赖注入
- `IRaySourceService` - 射线源业务服务
- `IEventAggregator` - Prism 事件聚合器
- `RaySourceConfig` - 射线源配置
- `ILoggerService` - 日志服务
- `ILocalizationService` - 多语言服务
- `IFilamentLifetimeService` - 灯丝寿命管理服务
## 多语言支持
### XAML 中使用
```xml
xmlns:loc="clr-namespace:XP.Common.Localization.Extensions;assembly=XP.Common"
<TextBlock Text="{loc:Localization RaySource_VoltageLabel}"/>
<telerik:RadButton Content="{loc:Localization RaySource_TurnOnButton}"/>
```
### ViewModel 中使用
```csharp
_localizationService.GetString("RaySource_StatusClosed")
```
### 资源键列表
#### OperateView 资源键
| 资源键 | 中文 | 英文 |
|--------|------|------|
| RaySource_VoltageLabel | 电压(kV | Voltage (kV) |
| RaySource_CurrentLabel | 电流(μA | Current (μA) |
| RaySource_ActualValueLabel | 当前值: {0} | Actual: {0} |
| RaySource_TurnOnButton | 开启射线源 | Turn On X-Ray |
| RaySource_TurnOffButton | 关闭射线源 | Turn Off X-Ray |
| RaySource_AdvanceButton | 高级 | Advance |
| RaySource_ConfigButton | 配置 | Config |
| RaySource_StatusUnavailable | 射线源\n不可用 | X-Ray\nUnavailable |
| RaySource_StatusClosed | 射线源\n已关闭 | X-Ray\nClosed |
| RaySource_StatusOpened | 射线源\n已开启 | X-Ray\nOpened |
#### ConfigView 资源键
| 资源键 | 中文 | 英文 |
|--------|------|------|
| RaySource_SourceTypeLabel | 射线源类型 | Source Type |
| RaySource_InitializeButton | 初始化 | Initialize |
| RaySource_ConnectVariablesButton | 连接变量 | Connect Variables |
| RaySource_DisconnectButton | 断开 | Disconnect |
| RaySource_WarmUpLabel | 暖机 | Warm-up |
| RaySource_VacuumLabel | 真空 | Vacuum |
| RaySource_StartUpLabel | 启动 | Startup |
| RaySource_AutoCenterLabel | 自动定心 | Auto-center |
| RaySource_FilamentLabel | 灯丝校准 | Filament |
| RaySource_XRayOnLabel | 射线 | X-Ray |
| RaySource_InterlockLabel | 连锁 | Interlock |
| RaySource_WatchdogLabel | 看门狗 | Watchdog |
| RaySource_TxiStatusLabel | TXI | TXI |
| RaySource_TxiOnButton | TXI ON | TXI ON |
| RaySource_TxiOffButton | TXI OFF | TXI OFF |
| RaySource_PowerModeLabel | 功率模式 | Power Mode |
| RaySource_HighPowerButton | High Power | High Power |
| RaySource_MicroFocusButton | Micro Focus | Micro Focus |
| RaySource_WarmUpSettingButton | 暖机设置 | Warm-up |
| RaySource_TrainingSettingButton | 训机设置 | Training |
| RaySource_FilamentCalibrationButton | 灯丝校准 | Filament Cal. |
| RaySource_AutoCenterSettingButton | 自动定心 | Auto-center |
| RaySource_FilamentLifetimeLabel | 灯丝寿命 | Filament Life |
| RaySource_ConfigWindowTitle | 射线源配置 | X-Ray Source Config |
> 注意:多语言仅在应用启动时加载,无需运行时热切换。
## 呼吸闪烁动画
射线源开启时,状态指示器播放呼吸闪烁动画,增强视觉警示效果。
### 动画定义
```xml
<Storyboard x:Key="BreathingAnimation" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1.0" To="0.6" Duration="0:0:0.75"
AutoReverse="True"/>
</Storyboard>
```
### 触发机制
通过 `DataTrigger` 监听 `RaySourceStatus` 属性:
- 当状态变为 `Opened` 时,自动开始动画
- 当状态离开 `Opened` 时,自动停止动画
## 事件订阅
### OperateViewModel 订阅事件
1. **RaySourceStatusChangedEvent**:射线源状态变更(三态)
- 更新 `RaySourceStatus` 属性和按钮/滑块启用状态
- 异常断联时重置变量连接状态
2. **StatusUpdatedEvent**:系统状态更新
- 更新实际电压和电流值(仅在值真正变化时更新,避免无意义赋值)
- 同步服务层权威状态
3. **ErrorOccurredEvent**:错误发生
- 显示错误消息对话框
4. **OperationResultEvent**:操作结果
- 操作失败时显示警告消息
5. **VariablesConnectedEvent**:变量连接状态变更
- 更新 `IsVariablesConnected` 属性
- 连接成功时主动读取最新设备状态
### ConfigViewModel 订阅事件
1. **RaySourceStatusChangedEvent**:刷新初始化状态和命令可执行状态
2. **StatusUpdatedEvent**:刷新设备状态面板所有字段
3. **VariablesConnectedEvent**:刷新连接状态和命令可执行状态
## 数据绑定
### OperateView 状态绑定
```xml
<!-- 状态指示器背景色(径向渐变)-->
Background="{Binding RaySourceStatus, Converter={StaticResource StatusToColorConverter}}"
<!-- 状态指示器边框色 -->
BorderBrush="{Binding RaySourceStatus, Converter={StaticResource StatusToBorderColorConverter}}"
<!-- 状态文本(多语言)-->
Text="{Binding StatusText}"
```
### OperateView 命令绑定
```xml
<telerik:RadButton Content="{loc:Localization RaySource_TurnOnButton}" Command="{Binding TurnOnCommand}"/>
<telerik:RadButton Content="{loc:Localization RaySource_TurnOffButton}" Command="{Binding TurnOffCommand}"/>
<telerik:RadButton Content="{loc:Localization RaySource_AdvanceButton}" Command="{Binding SettingsCommand}"/>
<telerik:RadButton Content="{loc:Localization RaySource_ConfigButton}" Command="{Binding ConfigCommand}"/>
```
### OperateView 滑块绑定
```xml
<!-- 电压滑块(延迟拖拽模式)-->
<telerik:RadSlider Minimum="{Binding VoltageMin}" Maximum="{Binding VoltageMax}"
Value="{Binding VoltageValue, Mode=TwoWay}"
IsDeferredDraggingEnabled="True"
IsEnabled="{Binding IsSlidersEnabled}"/>
<!-- 电压数值输入框 -->
<telerik:RadNumericUpDown Minimum="{Binding VoltageMin}" Maximum="{Binding VoltageMax}"
Value="{Binding VoltageValue, Mode=TwoWay}"
IsEnabled="{Binding IsSlidersEnabled}" NumberDecimalDigits="1"/>
```
## 转换器
### 1. RaySourceStatusToColorConverter
`RaySourceStatus` 枚举转换为径向渐变背景色:
- `Unavailable` → 灰色渐变(#E0E0E0#BDBDBD
- `Closed` → 绿色渐变(#8BC34A#4CAF50
- `Opened` → 红色渐变(#FF8A80#F44336
### 2. RaySourceStatusToBorderColorConverter
`RaySourceStatus` 枚举转换为边框色:
- `Unavailable`#9E9E9E
- `Closed`#2E7D32
- `Opened`#C62828
### 3. FilamentLifetimeColorConverter
将灯丝寿命百分比转换为进度条颜色:
- < 80% → 绿色 (#4CAF50)
- 80%-89% → 黄色 (#FFC107)
- ≥ 90% → 红色 (#E53935)
## 业务规则
### 安全规则
1. **未初始化禁止操作**:所有操作前检查 `IsInitialized``IsVariablesConnected`
2. **参数范围校验**:电压和电流值必须在配置的范围内
3. **操作失败回滚**:设置失败时恢复滑块到实际值(仅当实际值在有效范围内时)
4. **连接丢失处理**:连接丢失时状态设为 `Unavailable`,重置变量连接状态,禁用所有操作
5. **设备反馈保护**`IsUpdatingFromDevice` 标志防止设备反馈更新时误触发写入
### 状态管理
- 状态变更通过事件驱动,确保 UI 与硬件状态同步
- 使用 `RaisePropertyChanged` 通知 UI 更新
- 命令的 `CanExecute` 自动监听状态变化
- 三态管理:Unavailable → Closed → Opened
## 使用示例
### 在独立窗口中使用
```csharp
var raySourceView = _containerProvider.Resolve<RaySourceOperateView>();
var window = new Window
{
Title = "射线源操作",
Content = raySourceView,
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Owner = Application.Current.MainWindow
};
window.ShowDialog();
```
### 在主窗口 Region 中加载
```xml
<ContentControl prism:RegionManager.RegionName="RaySourceOperateRegion" />
```
```csharp
_regionManager.RequestNavigate("RaySourceOperateRegion", "RaySourceOperateView");
```
## XAML 命名空间引用
```xml
xmlns:local="clr-namespace:XP.Hardware.RaySource.Views"
xmlns:converters="clr-namespace:XP.Hardware.RaySource.Converters"
xmlns:enums="clr-namespace:XP.Hardware.RaySource.Abstractions.Enums"
xmlns:loc="clr-namespace:XP.Common.Localization.Extensions;assembly=XP.Common"
xmlns:prism="http://prismlibrary.com/"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
```
## 注意事项
1. **线程安全**:所有事件处理使用 `ThreadOption.UIThread` 确保在 UI 线程执行
2. **资源释放**ViewModel 实现 `IDisposable`,在 Dispose 时取消事件订阅、断开射线源连接、关闭配置窗口
3. **同步操作**:硬件操作为同步方法,ViewModel 中直接调用(不阻塞 UI 因为操作通过 IPC 快速返回)
4. **错误处理**:所有操作包含 try-catch,确保异常不会导致程序崩溃
5. **多语言**:所有界面文字通过 `{loc:Localization}``ILocalizationService` 获取,无硬编码文字
6. **动画性能**:呼吸闪烁动画使用 WPF Storyboard,性能开销极低
7. **日志规范**:使用 `_logger.ForModule("RaySource.ViewModel")` 和结构化日志消息
8. **自动初始化**OperateView 加载时自动执行 `AutoInitializeAsync()`,仅执行一次
9. **配置窗口**:通过 ConfigCommand 打开,单例模式(已存在时激活而非重复创建)
## 故障排查
### 按钮不可用
- 检查 `IsInitialized``IsVariablesConnected` 状态
- 检查 `RaySourceStatus` 是否正确
- 查看命令的 `CanExecute` 逻辑
### 滑块不可用
- 确认服务已初始化且变量已连接(`IsSlidersEnabled`
### 实际值不更新
- 确认已订阅 `StatusUpdatedEvent`
- 检查 Host 进程是否正常推送状态
- 验证 `ThreadOption.UIThread` 设置
### 设置值不生效
- 检查 `ApplyVoltageCommand` / `ApplyCurrentCommand` 是否正确触发
- 查看业务规则校验逻辑
- 确认 IPC 管道连接正常
### 多语言文字不显示
- 确认 XP.Common 资源文件中已添加对应的资源键
- 检查 XAML 中 `xmlns:loc` 命名空间引用是否正确
### 动画不播放
- 确认 `RaySourceStatus` 已变为 `Opened`
- 检查 `enums` 命名空间引用是否正确
### 状态显示为"不可用"
- 检查射线源服务连接状态
- 确认 Host 进程是否正常运行
- 查看日志中是否有连接丢失的警告信息
---
**最后更新 | Last Updated**: 2026-03-26