将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
<UserControl x:Class="XP.Hardware.RaySource.Views.RaySourceConfigView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
|
||||
xmlns:loc="clr-namespace:XP.Common.Localization.Extensions;assembly=XP.Common"
|
||||
xmlns:converters="clr-namespace:XP.Hardware.RaySource.Converters"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="420" d:DesignWidth="500"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
Background="White">
|
||||
<UserControl.Resources>
|
||||
<converters:FilamentLifetimeColorConverter x:Key="LifetimeColorConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="15">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 第1行:设备信息 | Row 1: Device Info -->
|
||||
<Grid Grid.Row="0" Margin="0 0 0 10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_SourceTypeLabel}"
|
||||
FontSize="13" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding SourceTypeText}"
|
||||
FontSize="13" FontWeight="Bold" VerticalAlignment="Center" Margin="8 0 0 0"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding ConnectionStatusText}"
|
||||
FontSize="12" VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<!-- 默认灰色:未连接 -->
|
||||
<Setter Property="Foreground" Value="#FF9E9E9E"/>
|
||||
<Style.Triggers>
|
||||
<!-- 已初始化但变量未连接:橙色 -->
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsInitialized}" Value="True"/>
|
||||
<Condition Binding="{Binding IsVariablesConnected}" Value="False"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Foreground" Value="#FFFF9800"/>
|
||||
</MultiDataTrigger>
|
||||
<!-- 变量已连接:绿色 -->
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsInitialized}" Value="True"/>
|
||||
<Condition Binding="{Binding IsVariablesConnected}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Foreground" Value="#FF4CAF50"/>
|
||||
</MultiDataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
<!-- 第2行:操作按钮(3列等宽均布)| Row 2: Action Buttons (3 equal-width columns) -->
|
||||
<Grid Grid.Row="1" Margin="0 0 0 12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<telerik:RadButton Grid.Column="0" Content="{loc:Localization RaySource_InitializeButton}"
|
||||
Command="{Binding InitializeCommand}"
|
||||
Height="32" Margin="0 0 4 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal">
|
||||
<telerik:RadButton.Background>
|
||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
||||
<GradientStop Color="White"/>
|
||||
<GradientStop Color="#FF62B8E0" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</telerik:RadButton.Background>
|
||||
</telerik:RadButton>
|
||||
<telerik:RadButton Grid.Column="1" Content="{loc:Localization RaySource_ConnectVariablesButton}"
|
||||
Command="{Binding ConnectVariablesCommand}"
|
||||
Height="32" Margin="4 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal">
|
||||
<telerik:RadButton.Background>
|
||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
||||
<GradientStop Color="White"/>
|
||||
<GradientStop Color="#FF77E062" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</telerik:RadButton.Background>
|
||||
</telerik:RadButton>
|
||||
<telerik:RadButton Grid.Column="2" Content="{loc:Localization RaySource_DisconnectButton}"
|
||||
Command="{Binding DisconnectCommand}"
|
||||
Height="32" Margin="4 0 0 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal">
|
||||
<telerik:RadButton.Background>
|
||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
||||
<GradientStop Color="White"/>
|
||||
<GradientStop Color="#FFFFA1A1" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</telerik:RadButton.Background>
|
||||
</telerik:RadButton>
|
||||
</Grid>
|
||||
|
||||
<!-- 第3行:分隔线 | Row 3: Separator -->
|
||||
<Separator Grid.Row="2" Margin="0 0 0 8"/>
|
||||
|
||||
<!-- 第4行:设备状态监控面板 | Row 4: Device Status Monitor Panel -->
|
||||
<Grid Grid.Row="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 暖机状态 | Warm-up Status -->
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" Margin="0 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_WarmUpLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding WarmUpStatus}" FontSize="12" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 真空状态 | Vacuum Status -->
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" Margin="8 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_VacuumLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding VacuumStatus}" FontSize="12" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 启动状态 | Startup Status -->
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Margin="0 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_StartUpLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding StartUpStatus}" FontSize="12" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 自动定心 | Auto-center Status -->
|
||||
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" Margin="8 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_AutoCenterLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding AutoCenterStatus}" FontSize="12" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 灯丝校准 | Filament Adjust Status -->
|
||||
<StackPanel Grid.Row="2" Grid.Column="0" Orientation="Horizontal" Margin="0 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_FilamentLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding FilamentAdjustStatus}" FontSize="12" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 射线开启状态 | X-Ray On Status -->
|
||||
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" Margin="8 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_XRayOnLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding XRayOnStatusText}" FontSize="12" FontWeight="SemiBold">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsXRayOn}" Value="True">
|
||||
<Setter Property="Foreground" Value="#FF4CAF50"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 连锁状态 | Interlock Status -->
|
||||
<StackPanel Grid.Row="3" Grid.Column="0" Orientation="Horizontal" Margin="0 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_InterlockLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding InterlockStatusText}" FontSize="12" FontWeight="SemiBold">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<!-- 默认未激活:红色 | Default inactive: red -->
|
||||
<Setter Property="Foreground" Value="#FFE53935"/>
|
||||
<Style.Triggers>
|
||||
<!-- 激活时:绿色 | Active: green -->
|
||||
<DataTrigger Binding="{Binding IsInterlockActive}" Value="True">
|
||||
<Setter Property="Foreground" Value="#FF4CAF50"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 看门狗 | Watchdog Status -->
|
||||
<StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" Margin="8 2">
|
||||
<TextBlock Text="{loc:Localization RaySource_WatchdogLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding WatchdogStatus}" FontSize="12" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- TXI状态 + TXI ON/OFF 按钮(同一行)| TXI Status + TXI ON/OFF Buttons (same row) -->
|
||||
<StackPanel Grid.Row="4" Grid.Column="0" Orientation="Horizontal" Margin="0 4 0 2" VerticalAlignment="Center">
|
||||
<TextBlock Text="{loc:Localization RaySource_TxiStatusLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding TxiStatus}" FontSize="12" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="4" Grid.Column="1" Margin="8 2 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<telerik:RadButton Grid.Column="0" Content="{loc:Localization RaySource_TxiOnButton}"
|
||||
Command="{Binding TxiOnCommand}"
|
||||
Height="20" Padding="4 0" FontSize="11"
|
||||
Margin="0 0 2 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
<telerik:RadButton Grid.Column="1" Content="{loc:Localization RaySource_TxiOffButton}"
|
||||
Command="{Binding TxiOffCommand}"
|
||||
Height="20" Padding="4 0" FontSize="11"
|
||||
Margin="2 0 0 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 功率模式 + High Power/Micro Focus 按钮(同一行)| Power Mode + HP/MF Buttons (same row) -->
|
||||
<StackPanel Grid.Row="5" Grid.Column="0" Orientation="Horizontal" Margin="0 4 0 2" VerticalAlignment="Center">
|
||||
<TextBlock Text="{loc:Localization RaySource_PowerModeLabel}" FontSize="12" Foreground="#616161" Width="80"/>
|
||||
<TextBlock Text="{Binding PowerMode}" FontSize="12" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="5" Grid.Column="1" Margin="8 2 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<telerik:RadButton Grid.Column="0" Content="{loc:Localization RaySource_HighPowerButton}"
|
||||
Command="{Binding HighPowerCommand}"
|
||||
Height="20" Padding="4 0" FontSize="11"
|
||||
Margin="0 0 2 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
<telerik:RadButton Grid.Column="1" Content="{loc:Localization RaySource_MicroFocusButton}"
|
||||
Command="{Binding MicroFocusCommand}"
|
||||
Height="20" Padding="4 0" FontSize="11"
|
||||
Margin="2 0 0 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- 第5行:分隔线 | Row 5: Separator -->
|
||||
<Separator Grid.Row="4" Margin="0 8 0 8"/>
|
||||
|
||||
<!-- 第6行:功能设置按钮 | Row 6: Function Setting Buttons -->
|
||||
<Grid Grid.Row="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<telerik:RadButton Grid.Column="0" Content="{loc:Localization RaySource_WarmUpSettingButton}"
|
||||
Command="{Binding WarmUpSettingCommand}"
|
||||
Height="30" Margin="0 0 4 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
<telerik:RadButton Grid.Column="1" Content="{loc:Localization RaySource_TrainingSettingButton}"
|
||||
Command="{Binding TrainingSettingCommand}"
|
||||
Height="30" Margin="4 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
<telerik:RadButton Grid.Column="2" Content="{loc:Localization RaySource_FilamentCalibrationButton}"
|
||||
Command="{Binding FilamentCalibrationCommand}"
|
||||
Height="30" Margin="4 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
<telerik:RadButton Grid.Column="3" Content="{loc:Localization RaySource_AutoCenterSettingButton}"
|
||||
Command="{Binding AutoCenterSettingCommand}"
|
||||
Height="30" Margin="4 0 0 0" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 第7行:分隔线 | Row 7: Separator -->
|
||||
<Separator Grid.Row="6" Margin="0 8 0 8"/>
|
||||
|
||||
<!-- 第8行:灯丝寿命进度条 | Row 8: Filament Lifetime Progress Bar -->
|
||||
<Grid Grid.Row="7">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{loc:Localization RaySource_FilamentLifetimeLabel}"
|
||||
FontSize="12" Foreground="#616161" VerticalAlignment="Center" Margin="0 0 8 0"/>
|
||||
<telerik:RadProgressBar Grid.Column="1"
|
||||
Minimum="0" Maximum="100"
|
||||
Value="{Binding FilamentLifetime, Mode=OneWay}"
|
||||
Foreground="{Binding FilamentLifetime, Converter={StaticResource LifetimeColorConverter}}"
|
||||
Height="8" VerticalAlignment="Center"
|
||||
telerik:StyleManager.Theme="Crystal"/>
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="{Binding FilamentLifetimeText}"
|
||||
FontSize="11" Foreground="#616161" VerticalAlignment="Center" Margin="8 0 0 0"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace XP.Hardware.RaySource.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ViewA.xaml
|
||||
/// </summary>
|
||||
public partial class RaySourceConfigView : UserControl
|
||||
{
|
||||
public RaySourceConfigView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<Window x:Class="XP.Hardware.RaySource.Views.RaySourceConfigWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:loc="clr-namespace:XP.Common.Localization.Extensions;assembly=XP.Common"
|
||||
xmlns:raySourceViews="clr-namespace:XP.Hardware.RaySource.Views"
|
||||
Title="{loc:Localization RaySource_ConfigWindowTitle}"
|
||||
Height="350" Width="600"
|
||||
MinHeight="350" MinWidth="400"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ResizeMode="CanResize">
|
||||
<Grid>
|
||||
<raySourceViews:RaySourceConfigView />
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace XP.Hardware.RaySource.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// 射线源配置窗口 | Ray source config window
|
||||
/// </summary>
|
||||
public partial class RaySourceConfigWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数 | Constructor
|
||||
/// </summary>
|
||||
public RaySourceConfigWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 继承主窗口图标
|
||||
if (Application.Current?.MainWindow != null)
|
||||
{
|
||||
Icon = Application.Current.MainWindow.Icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="XP.Hardware.RaySource.Views.RaySourceOperateView"
|
||||
mc:Ignorable="d" d:DesignWidth="350"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True" Height="249" Background="White" >
|
||||
<UserControl.Resources>
|
||||
<!-- 转换器 | Converters -->
|
||||
<converters:RaySourceStatusToColorConverter x:Key="StatusToColorConverter"/>
|
||||
<converters:RaySourceStatusToBorderColorConverter x:Key="StatusToBorderColorConverter"/>
|
||||
|
||||
<!-- 呼吸闪烁动画 | Breathing Flash Animation -->
|
||||
<Storyboard x:Key="BreathingAnimation" RepeatBehavior="Forever">
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity"
|
||||
From="1.0" To="0.6" Duration="0:0:0.75"
|
||||
AutoReverse="True"/>
|
||||
</Storyboard>
|
||||
|
||||
<!-- 按钮样式 | Button Style -->
|
||||
<Style x:Key="RaySourceButtonStyle" TargetType="{x:Type Button}">
|
||||
<Setter Property="Background" Value="#E0E0E0"/>
|
||||
<Setter Property="BorderBrush" Value="#BDBDBD"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Foreground" Value="Black"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="FontWeight" Value="Medium"/>
|
||||
<Setter Property="Padding" Value="8"/>
|
||||
<Setter Property="Width" Value="85"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border CornerRadius="4" Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#BDBDBD"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" Value="#9E9E9E"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Background" Value="#F5F5F5"/>
|
||||
<Setter Property="Foreground" Value="#BDBDBD"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" MinHeight="70" />
|
||||
<RowDefinition Height="Auto" MinHeight="70" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 1. 状态区:腰圆指示器 + 按钮 | Status Area: Capsule Indicator + Buttons -->
|
||||
<Grid Grid.Row="0" Margin="5,5,5,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 腰圆状态指示器 | Capsule Status Indicator -->
|
||||
<Grid Grid.Column="0" Width="200" Height="80" Margin="20 0 0 5">
|
||||
<Border x:Name="StatusIndicator"
|
||||
Width="200" Height="80"
|
||||
Background="{Binding RaySourceStatus, Converter={StaticResource StatusToColorConverter}}"
|
||||
BorderBrush="{Binding RaySourceStatus, Converter={StaticResource StatusToBorderColorConverter}}"
|
||||
BorderThickness="2"
|
||||
CornerRadius="40">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RaySourceStatus}"
|
||||
Value="{x:Static enums:RaySourceStatus.Opened}">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard Name="BreathingStoryboard" Storyboard="{StaticResource BreathingAnimation}"/>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<StopStoryboard BeginStoryboardName="BreathingStoryboard"/>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
</Border>
|
||||
<TextBlock Text="{Binding StatusText}"
|
||||
Foreground="White" FontSize="18" FontWeight="Bold"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
TextAlignment="Center" LineHeight="20"/>
|
||||
<!-- 连锁状态图标(腰圆右侧圆弧区域)| Interlock status icon (right arc area of capsule) -->
|
||||
<Image Width="22" Height="22"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,20,0"
|
||||
RenderOptions.BitmapScalingMode="HighQuality">
|
||||
<Image.Style>
|
||||
<Style TargetType="Image">
|
||||
<!-- 默认未激活:解锁图标 | Default inactive: unlocked icon -->
|
||||
<Setter Property="Source" Value="/XP.Hardware.RaySource;component/Resources/Unlocked.png"/>
|
||||
<Setter Property="ToolTip" Value="{loc:Localization RaySource_InterlockNormal}"/>
|
||||
<Style.Triggers>
|
||||
<!-- 激活时:锁定图标 | Active: locked icon -->
|
||||
<DataTrigger Binding="{Binding IsInterlockActive}" Value="True">
|
||||
<Setter Property="Source" Value="/XP.Hardware.RaySource;component/Resources/Locked.png"/>
|
||||
<Setter Property="ToolTip" Value="{loc:Localization RaySource_InterlockActive}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Image.Style>
|
||||
</Image>
|
||||
</Grid>
|
||||
|
||||
<!-- 按钮区 | Button Area -->
|
||||
<StackPanel Grid.Column="1" Orientation="Vertical"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Center"
|
||||
Margin="20 0 20 0">
|
||||
<telerik:RadButton Content="{loc:Localization RaySource_TurnOnButton}"
|
||||
Command="{Binding TurnOnCommand}"
|
||||
Margin="0 0 0 8" Height="35" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal">
|
||||
<telerik:RadButton.Background>
|
||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
||||
<GradientStop Color="White"/>
|
||||
<GradientStop Color="#FF77E062" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</telerik:RadButton.Background>
|
||||
</telerik:RadButton>
|
||||
<telerik:RadButton Content="{loc:Localization RaySource_TurnOffButton}"
|
||||
Command="{Binding TurnOffCommand}"
|
||||
Margin="0 0 0 0" Height="35" HorizontalAlignment="Stretch"
|
||||
telerik:StyleManager.Theme="Crystal">
|
||||
<telerik:RadButton.Background>
|
||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
||||
<GradientStop Color="White"/>
|
||||
<GradientStop Color="#FFFFA1A1" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</telerik:RadButton.Background>
|
||||
</telerik:RadButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 2. 电压区 | Voltage Area -->
|
||||
<Grid Grid.Row="1" Margin="20,0,20,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 标签+实际值 | Label + Actual Value -->
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="80"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_VoltageLabel}"
|
||||
FontSize="14" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding VoltageActualText}"
|
||||
FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<telerik:RadSlider x:Name="VoltageSlider" Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,5,10,0" VerticalAlignment="Center"
|
||||
telerik:StyleManager.Theme="Crystal"
|
||||
Minimum="{Binding VoltageMin}"
|
||||
Maximum="{Binding VoltageMax}"
|
||||
Value="{Binding VoltageValue, Mode=TwoWay}"
|
||||
SmallChange="1" LargeChange="10"
|
||||
IsDeferredDraggingEnabled="True"
|
||||
IsEnabled="{Binding IsSlidersEnabled}"/>
|
||||
<telerik:RadNumericUpDown x:Name="VoltageNumeric" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Center" Width="70"
|
||||
Minimum="{Binding VoltageMin}"
|
||||
Maximum="{Binding VoltageMax}"
|
||||
Value="{Binding VoltageValue, Mode=TwoWay}"
|
||||
SmallChange="1" LargeChange="10"
|
||||
IsEnabled="{Binding IsSlidersEnabled}"
|
||||
NumberDecimalDigits="0" telerik:StyleManager.Theme="Crystal" FontSize="11"/>
|
||||
<!-- 最小值 | Minimum Value -->
|
||||
<TextBlock Grid.Column="0" Text="{Binding VoltageMin, StringFormat={}{0:F0}}"
|
||||
FontSize="12" Foreground="#616161"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
||||
Margin="0 0 0 -17"/>
|
||||
<!-- 最大值 | Maximum Value -->
|
||||
<TextBlock Grid.Column="0" Text="{Binding VoltageMax, StringFormat={}{0:F0}}"
|
||||
FontSize="12" Foreground="#616161"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom" TextAlignment="Right"
|
||||
Margin="0,0,10,-17"/>
|
||||
</Grid>
|
||||
<!-- 按钮行:配置 | Button Row: Config -->
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0">
|
||||
<telerik:RadButton Content="{loc:Localization RaySource_ConfigButton}"
|
||||
Command="{Binding ConfigCommand}"
|
||||
Width="70"
|
||||
telerik:StyleManager.Theme="Crystal" FontSize="10"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 3. 电流区 | Current Area -->
|
||||
<Grid Grid.Row="1" Margin="20,75,20,0" Grid.RowSpan="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 标签+实际值 | Label + Actual Value -->
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="80"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_CurrentLabel}"
|
||||
FontSize="14" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding CurrentActualText}"
|
||||
FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 滑块 | Slider -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<telerik:RadSlider x:Name="CurrentSlider" Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,6,10,0" VerticalAlignment="Top"
|
||||
telerik:StyleManager.Theme="Crystal"
|
||||
Minimum="{Binding CurrentMin}"
|
||||
Maximum="{Binding CurrentMax}"
|
||||
Value="{Binding CurrentValue, Mode=TwoWay}"
|
||||
SmallChange="10" LargeChange="100"
|
||||
IsDeferredDraggingEnabled="True"
|
||||
IsEnabled="{Binding IsSlidersEnabled}"/>
|
||||
<telerik:RadNumericUpDown x:Name="CurrentNumeric" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Center" Width="70"
|
||||
Minimum="{Binding CurrentMin}"
|
||||
Maximum="{Binding CurrentMax}"
|
||||
Value="{Binding CurrentValue, Mode=TwoWay}"
|
||||
SmallChange="10" LargeChange="100"
|
||||
IsEnabled="{Binding IsSlidersEnabled}"
|
||||
NumberDecimalDigits="0" telerik:StyleManager.Theme="Crystal" FontSize="11"/>
|
||||
<!-- 最小值 | Minimum Value -->
|
||||
<TextBlock Grid.Column="0" Text="{Binding CurrentMin, StringFormat={}{0:F0}}"
|
||||
FontSize="12" Foreground="#616161"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
||||
Margin="0 0 0 -17"/>
|
||||
<!-- 最大值 | Maximum Value -->
|
||||
<TextBlock Grid.Column="0" Text="{Binding CurrentMax, StringFormat={}{0:F0}}"
|
||||
FontSize="12" Foreground="#616161"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom" TextAlignment="Right"
|
||||
Margin="0,0,10,-17"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 按钮行:高级 | Button Row: Advance -->
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0">
|
||||
<telerik:RadButton Content="{loc:Localization RaySource_AdvanceButton}"
|
||||
Command="{Binding SettingsCommand}"
|
||||
Width="70"
|
||||
telerik:StyleManager.Theme="Crystal" FontSize="10"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Telerik.Windows.Controls;
|
||||
using XP.Hardware.RaySource.ViewModels;
|
||||
|
||||
namespace XP.Hardware.RaySource.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// 射线源操作视图 code-behind | X-Ray Source Operate View code-behind
|
||||
/// 负责将滑块 DragCompleted / 输入框确认操作桥接到 ViewModel 命令
|
||||
/// Bridges slider DragCompleted / numeric confirm actions to ViewModel commands
|
||||
/// </summary>
|
||||
public partial class RaySourceOperateView : UserControl
|
||||
{
|
||||
// 防止初始化阶段触发写入 | Prevent writes during initialization
|
||||
private bool _isLoaded = false;
|
||||
|
||||
// 标记输入框是否正在键盘输入中(区分手动输入和箭头点击)
|
||||
// Flag whether numeric input is in keyboard editing (distinguish manual input from arrow click)
|
||||
private bool _isVoltageEditing = false;
|
||||
private bool _isCurrentEditing = false;
|
||||
|
||||
public RaySourceOperateView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 滑块拖动完成时提交值到硬件 | Apply value to hardware when slider drag completes
|
||||
VoltageSlider.DragCompleted += VoltageSlider_DragCompleted;
|
||||
CurrentSlider.DragCompleted += CurrentSlider_DragCompleted;
|
||||
|
||||
// 输入框事件 | Numeric input events
|
||||
VoltageNumeric.GotKeyboardFocus += (s, e) => _isVoltageEditing = true;
|
||||
VoltageNumeric.LostFocus += VoltageNumeric_LostFocus;
|
||||
VoltageNumeric.KeyDown += VoltageNumeric_KeyDown;
|
||||
VoltageNumeric.ValueChanged += VoltageNumeric_ValueChanged;
|
||||
|
||||
CurrentNumeric.GotKeyboardFocus += (s, e) => _isCurrentEditing = true;
|
||||
CurrentNumeric.LostFocus += CurrentNumeric_LostFocus;
|
||||
CurrentNumeric.KeyDown += CurrentNumeric_KeyDown;
|
||||
CurrentNumeric.ValueChanged += CurrentNumeric_ValueChanged;
|
||||
|
||||
Loaded += OnViewLoaded;
|
||||
Unloaded += OnViewUnloaded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 界面加载完成:标记已加载并触发自动初始化流程
|
||||
/// View loaded: mark as loaded and trigger auto-initialization sequence
|
||||
/// 参考旧代码 AreaDetector_Load 模式 | Follows AreaDetector_Load pattern from legacy code
|
||||
/// </summary>
|
||||
private async void OnViewLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_isLoaded = true;
|
||||
|
||||
if (DataContext is RaySourceOperateViewModel vm)
|
||||
{
|
||||
await vm.AutoInitializeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 界面卸载:触发 ViewModel 的 Dispose 执行断开操作
|
||||
/// View unloaded: trigger ViewModel Dispose to execute disconnect
|
||||
/// </summary>
|
||||
private void OnViewUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is RaySourceOperateViewModel vm)
|
||||
{
|
||||
vm.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以提交(已加载、非设备反馈更新中)| Check if can apply (loaded and not updating from device)
|
||||
/// </summary>
|
||||
private bool CanApply(out RaySourceOperateViewModel vm)
|
||||
{
|
||||
vm = null;
|
||||
if (!_isLoaded) return false;
|
||||
if (DataContext is not RaySourceOperateViewModel viewModel) return false;
|
||||
if (viewModel.IsUpdatingFromDevice) return false;
|
||||
vm = viewModel;
|
||||
return true;
|
||||
}
|
||||
|
||||
#region 滑块事件 | Slider Events
|
||||
|
||||
/// <summary>
|
||||
/// 电压滑块拖动完成 | Voltage slider drag completed
|
||||
/// </summary>
|
||||
private void VoltageSlider_DragCompleted(object sender, RadDragCompletedEventArgs e)
|
||||
{
|
||||
if (CanApply(out var vm))
|
||||
vm.ApplyVoltageCommand.Execute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 电流滑块拖动完成 | Current slider drag completed
|
||||
/// </summary>
|
||||
private void CurrentSlider_DragCompleted(object sender, RadDragCompletedEventArgs e)
|
||||
{
|
||||
if (CanApply(out var vm))
|
||||
vm.ApplyCurrentCommand.Execute();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 电压输入框事件 | Voltage Numeric Events
|
||||
|
||||
/// <summary>
|
||||
/// 电压输入框值变更:仅在非键盘编辑时提交(即箭头按钮点击)
|
||||
/// Voltage numeric value changed: only apply when not keyboard editing (i.e. arrow button click)
|
||||
/// </summary>
|
||||
private void VoltageNumeric_ValueChanged(object sender, RadRangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
if (!_isVoltageEditing && CanApply(out var vm))
|
||||
vm.ApplyVoltageCommand.Execute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 电压输入框回车确认 | Voltage numeric Enter key confirm
|
||||
/// </summary>
|
||||
private void VoltageNumeric_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Enter && CanApply(out var vm))
|
||||
{
|
||||
_isVoltageEditing = false;
|
||||
vm.ApplyVoltageCommand.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 电压输入框失焦确认 | Voltage numeric lost focus confirm
|
||||
/// </summary>
|
||||
private void VoltageNumeric_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isVoltageEditing && CanApply(out var vm))
|
||||
{
|
||||
_isVoltageEditing = false;
|
||||
vm.ApplyVoltageCommand.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 电流输入框事件 | Current Numeric Events
|
||||
|
||||
/// <summary>
|
||||
/// 电流输入框值变更:仅在非键盘编辑时提交(即箭头按钮点击)
|
||||
/// Current numeric value changed: only apply when not keyboard editing (i.e. arrow button click)
|
||||
/// </summary>
|
||||
private void CurrentNumeric_ValueChanged(object sender, RadRangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
if (!_isCurrentEditing && CanApply(out var vm))
|
||||
vm.ApplyCurrentCommand.Execute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 电流输入框回车确认 | Current numeric Enter key confirm
|
||||
/// </summary>
|
||||
private void CurrentNumeric_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Enter && CanApply(out var vm))
|
||||
{
|
||||
_isCurrentEditing = false;
|
||||
vm.ApplyCurrentCommand.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 电流输入框失焦确认 | Current numeric lost focus confirm
|
||||
/// </summary>
|
||||
private void CurrentNumeric_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isCurrentEditing && CanApply(out var vm))
|
||||
{
|
||||
_isCurrentEditing = false;
|
||||
vm.ApplyCurrentCommand.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user