379 lines
14 KiB
Markdown
379 lines
14 KiB
Markdown
# 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
|