增加射线源探测器Z轴锁定联动功能,增加对应plc信号和配置。

This commit is contained in:
QI Mingxuan
2026-05-07 20:24:55 +08:00
parent 5e14fe3d9b
commit bb1b76ee7a
17 changed files with 404 additions and 114 deletions
+19 -11
View File
@@ -4,6 +4,7 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using XP.Common.Logging.Interfaces;
namespace XP.Common.Controls
{
@@ -31,13 +32,13 @@ namespace XP.Common.Controls
/// <summary>操控点元素引用 | Thumb element reference</summary>
private Ellipse? _thumbElement;
#endregion
#endregion
#region | Constructor
#region | Constructor
public VirtualJoystick()
public VirtualJoystick()
{
InitializeComponent();
InitializeComponent();
// 控件加载完成后绑定操控点的 TranslateTransform | Bind thumb TranslateTransform after control loaded
Loaded += (s, e) =>
@@ -46,8 +47,8 @@ namespace XP.Common.Controls
if (_thumbElement != null)
_thumbElement.RenderTransform = _thumbTransform;
// 初始化时更新背景和图标可见性 | Update background and icon visibility on init
UpdateIconVisibility();
// 初始化时更新背景和图标可见性 | Update background and icon visibility on init
UpdateIconVisibility();
};
}
@@ -152,7 +153,10 @@ namespace XP.Common.Controls
private static void OnSwapMouseButtonsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is VirtualJoystick joystick)
{
joystick.ActiveMouseButton = MouseButtonType.None;
joystick.UpdateIconVisibility();
}
}
#endregion
@@ -363,19 +367,23 @@ namespace XP.Common.Controls
case MouseButtonType.Left:
SetVisibility(Visibility.Collapsed, defaultTop, defaultBottom, defaultLeft, defaultRight);
// 如果交换了左右键,这里显示的是右键图标组
var leftIcons = SwapMouseButtons ? new[] { rightTop, rightBottom, rightLeft, rightRight } : new[] { leftTop, leftBottom, leftLeft, leftRight };
var leftIcons = new[] { leftTop, leftBottom, leftLeft, leftRight };
SetVisibility(Visibility.Visible, leftIcons);
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x3A, 0x7B, 0xC8));
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x2D, 0x63, 0x9E)); // 深一点的浅蓝色 | Darker light blue
break;
case MouseButtonType.Right:
SetVisibility(Visibility.Collapsed, defaultTop, defaultBottom, defaultLeft, defaultRight);
// 如果交换了左右键,这里显示的是左键图标组
var rightIcons = SwapMouseButtons ? new[] { leftTop, leftBottom, leftLeft, leftRight } : new[] { rightTop, rightBottom, rightLeft, rightRight };
var rightIcons = new[] { rightTop, rightBottom, rightLeft, rightRight };
SetVisibility(Visibility.Visible, rightIcons);
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x5B, 0xA8, 0x5B));
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x45, 0x88, 0x45)); // 深一点的浅绿色 | Darker light green
break;
default:
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x4A, 0x90, 0xD9));
// 根据 SwapMouseButtons 决定中心按钮颜色 | Determine center button color based on SwapMouseButtons
if (_thumbElement != null)
_thumbElement.Fill = SwapMouseButtons
? new SolidColorBrush(Color.FromRgb(0x5B, 0xA8, 0x5B)) // 浅绿色 | Light green
: new SolidColorBrush(Color.FromRgb(0x4A, 0x90, 0xD9)); // 浅蓝色 | Light blue
break;
}
@@ -66,6 +66,11 @@ namespace XP.Hardware.MotionControl.Config
// 运行参数 | Runtime parameters
config.PollingInterval = Int(get($"{P}:PollingInterval", "100"));
config.DefaultVelocity = Int(get($"{P}:DefaultVelocity", "100"));
// 射线源与探测器Z轴联动配置 | Source-Detector Z-axis linkage configuration
config.SourceDetectorZLinkage.Enabled = bool.TryParse(get($"{P}:SourceDetectorZLinkage:Enabled", "false"), out var enabled) && enabled;
config.SourceDetectorZLinkage.TriggerThreshold = Dbl(get($"{P}:SourceDetectorZLinkage:TriggerThreshold", "1.0"));
config.SourceDetectorZLinkage.SpeedPercent = Int(get($"{P}:SourceDetectorZLinkage:SpeedPercent", "100"));
}
private static LinearAxisConfig LoadLinear(string name, Func<string, string, string> get)
@@ -23,6 +23,24 @@ namespace XP.Hardware.MotionControl.Config
/// <summary>默认速度| Default velocity</summary>
public int DefaultVelocity { get; set; } = 100;
/// <summary>射线源与探测器Z轴联动配置 | Source-Detector Z-axis linkage configuration</summary>
public SourceDetectorZLinkageConfig SourceDetectorZLinkage { get; set; } = new();
}
/// <summary>
/// 射线源与探测器Z轴联动配置 | Source-Detector Z-axis linkage configuration
/// </summary>
public class SourceDetectorZLinkageConfig
{
/// <summary>联动启用 | Linkage enabled</summary>
public bool Enabled { get; set; } = false;
/// <summary>联动触发的位置变化阈值(mm| Position change threshold for linkage trigger (mm)</summary>
public double TriggerThreshold { get; set; } = 1.0;
/// <summary>联动移动速度百分比(0-100| Linkage movement speed percentage (0-100)</summary>
public int SpeedPercent { get; set; } = 100;
}
/// <summary>
@@ -6,6 +6,14 @@ namespace XP.Hardware.MotionControl.Config
/// </summary>
public static class MotionSignalNames
{
// ==================== 射线源与探测器Z轴联动 | Source-Detector Z-axis Linkage ====================
/// <summary>射线源与探测器Z轴联动使能(写入)| Source-Detector Z-axis linkage enable (write)</summary>
public const string SourceDetZ_Linkage_Enable = "MC_SourceDetZ_Linkage_Enable";
/// <summary>虚拟摇杆使能(写入)| Virtual joystick enable (write)</summary>
public const string VirtualJoystick_Enable = "MC_VirtualJoystick_Enable";
/// <summary>实体摇杆输入激活(读取)| Physical joystick input active (read)</summary>
public const string Joystick_Active = "MC_Joystick_Active";
// ==================== 直线轴 SourceZ | Linear Axis SourceZ ====================
public const string SourceZ_Pos = "MC_SourceZ_Pos";
public const string SourceZ_Target = "MC_SourceZ_Target";
@@ -262,25 +262,25 @@ Confirm to filll move matrix?</value>
<value>Axis Positions</value>
</data>
<data name="AC_StageX" xml:space="preserve">
<value>X mm</value>
<value>X</value>
</data>
<data name="AC_StageY" xml:space="preserve">
<value>Y mm</value>
<value>Y</value>
</data>
<data name="AC_SourceZ" xml:space="preserve">
<value>SZ mm</value>
<value>SZ</value>
</data>
<data name="AC_DetectorZ" xml:space="preserve">
<value>DZ mm</value>
<value>DZ</value>
</data>
<data name="AC_DetectorSwing" xml:space="preserve">
<value>DT' °</value>
<value>DT</value>
</data>
<data name="AC_StageRotation" xml:space="preserve">
<value>R' °</value>
<value>R</value>
</data>
<data name="AC_FixtureRotation" xml:space="preserve">
<value>FR' °</value>
<value>FR</value>
</data>
<data name="AC_SafetyParams" xml:space="preserve">
<value>Safety Parameters</value>
@@ -303,4 +303,16 @@ Confirm to filll move matrix?</value>
<data name="MC_MotionCtrl" xml:space="preserve">
<value>Motion Control</value>
</data>
<data name="AC_LengthUnit" xml:space="preserve">
<value>mm</value>
</data>
<data name="AC_AngleUnit" xml:space="preserve">
<value>°</value>
</data>
<data name="AC_SwapMouseButtons" xml:space="preserve">
<value>Switch the way the virtual joystick is controlled when using the mouse left and right buttons</value>
</data>
<data name="MC_Error" xml:space="preserve">
<value>Error</value>
</data>
</root>
@@ -361,4 +361,20 @@ DetectorZ → {4:F2}mm
<value>运动控制</value>
<comment>header</comment>
</data>
<data name="AC_LengthUnit" xml:space="preserve">
<value>mm</value>
<comment>长度单位</comment>
</data>
<data name="AC_AngleUnit" xml:space="preserve">
<value>°</value>
<comment>角度单位</comment>
</data>
<data name="AC_SwapMouseButtons" xml:space="preserve">
<value>切换虚拟摇杆鼠标左右键控制方式</value>
<comment>切换虚拟摇杆鼠标左右键控制方式</comment>
</data>
<data name="MC_Error" xml:space="preserve">
<value>错误</value>
<comment>错误</comment>
</data>
</root>
@@ -262,25 +262,25 @@ DetectorZ → {4:F2}mm
<value>轴位置</value>
</data>
<data name="AC_StageX" xml:space="preserve">
<value>X mm</value>
<value>X</value>
</data>
<data name="AC_StageY" xml:space="preserve">
<value>Y mm</value>
<value>Y</value>
</data>
<data name="AC_SourceZ" xml:space="preserve">
<value>SZ mm</value>
<value>SZ</value>
</data>
<data name="AC_DetectorZ" xml:space="preserve">
<value>DZ mm</value>
<value>DZ</value>
</data>
<data name="AC_DetectorSwing" xml:space="preserve">
<value>DT' °</value>
<value>DT</value>
</data>
<data name="AC_StageRotation" xml:space="preserve">
<value>R' °</value>
<value>R</value>
</data>
<data name="AC_FixtureRotation" xml:space="preserve">
<value>FR' °</value>
<value>FR</value>
</data>
<data name="AC_SafetyParams" xml:space="preserve">
<value>安全参数</value>
@@ -303,4 +303,16 @@ DetectorZ → {4:F2}mm
<data name="MC_MotionCtrl" xml:space="preserve">
<value>运动控制</value>
</data>
<data name="AC_LengthUnit" xml:space="preserve">
<value>mm</value>
</data>
<data name="AC_AngleUnit" xml:space="preserve">
<value>°</value>
</data>
<data name="AC_SwapMouseButtons" xml:space="preserve">
<value>切换虚拟摇杆鼠标左右键控制方式</value>
</data>
<data name="MC_Error" xml:space="preserve">
<value>错误</value>
</data>
</root>
@@ -262,25 +262,25 @@ DetectorZ → {4:F2}mm
<value>軸位置</value>
</data>
<data name="AC_StageX" xml:space="preserve">
<value>X mm</value>
<value>X</value>
</data>
<data name="AC_StageY" xml:space="preserve">
<value>Y mm</value>
<value>Y</value>
</data>
<data name="AC_SourceZ" xml:space="preserve">
<value>SZ mm</value>
<value>SZ</value>
</data>
<data name="AC_DetectorZ" xml:space="preserve">
<value>DZ mm</value>
<value>DZ</value>
</data>
<data name="AC_DetectorSwing" xml:space="preserve">
<value>DT' °</value>
<value>DT</value>
</data>
<data name="AC_StageRotation" xml:space="preserve">
<value>R' °</value>
<value>R</value>
</data>
<data name="AC_FixtureRotation" xml:space="preserve">
<value>FR' °</value>
<value>FR</value>
</data>
<data name="AC_SafetyParams" xml:space="preserve">
<value>安全參數</value>
@@ -303,4 +303,16 @@ DetectorZ → {4:F2}mm
<data name="MC_MotionCtrl" xml:space="preserve">
<value>運動控制</value>
</data>
<data name="AC_LengthUnit" xml:space="preserve">
<value>mm</value>
</data>
<data name="AC_AngleUnit" xml:space="preserve">
<value>°</value>
</data>
<data name="AC_SwapMouseButtons" xml:space="preserve">
<value>切換虛擬搖杆喺使用滑鼠左右鍵控制時嘅方式</value>
</data>
<data name="MC_Error" xml:space="preserve">
<value>錯誤</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

@@ -186,5 +186,23 @@ namespace XP.Hardware.MotionControl.Services
MotionResult ApplyGeometryByMagnification(double targetFOD, double magnification);
#endregion
#region 线Z轴联动 | Source-Detector Z-axis Linkage
/// <summary>
/// 启用/禁用射线源与探测器Z轴联动 | Enable/disable Source-Detector Z-axis linkage
/// </summary>
/// <param name="enabled">true=启用联动,false=禁用联动 | true=enable linkage, false=disable linkage</param>
/// <returns>操作结果 | Operation result</returns>
MotionResult SetSourceDetectorZLinkage(bool enabled);
/// <summary>
/// 设置虚拟摇杆使能 | Set virtual joystick enable
/// </summary>
/// <param name="enabled">true=启用虚拟摇杆,false=禁用虚拟摇杆 | true=enable virtual joystick, false=disable virtual joystick</param>
/// <returns>操作结果 | Operation result</returns>
MotionResult SetVirtualJoystickEnable(bool enabled);
#endregion
}
}
@@ -1,9 +1,10 @@
using System;
using Emgu.CV.Dnn;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows;
using Prism.Events;
using XP.Common.Localization;
using XP.Common.Logging.Interfaces;
using XP.Hardware.MotionControl.Abstractions;
@@ -27,9 +28,10 @@ namespace XP.Hardware.MotionControl.Services
private readonly IEventAggregator _eventAggregator;
private readonly ILoggerService _logger;
private readonly IPlcService _plcService;
private readonly ISignalDataService _signalService;
// 轮询定时器 | Polling timer
private Timer _pollingTimer;
// 轮询定时器 | Polling timer
private Timer _pollingTimer;
private int _pollErrorCount = 0;
/// <summary>
@@ -58,7 +60,8 @@ namespace XP.Hardware.MotionControl.Services
MotionControlConfig config,
IEventAggregator eventAggregator,
ILoggerService logger,
IPlcService plcService)
IPlcService plcService,
ISignalDataService signalService)
{
_motionSystem = motionSystem ?? throw new ArgumentNullException(nameof(motionSystem));
_geometryCalculator = geometryCalculator ?? throw new ArgumentNullException(nameof(geometryCalculator));
@@ -68,7 +71,8 @@ namespace XP.Hardware.MotionControl.Services
_logger = (logger ?? throw new ArgumentNullException(nameof(logger)))
.ForModule<MotionControlService>();
_plcService = plcService ?? throw new ArgumentNullException(nameof(plcService));
}
_signalService = signalService ?? throw new ArgumentNullException(nameof(signalService));
}
#region | Polling Control
@@ -544,6 +548,76 @@ namespace XP.Hardware.MotionControl.Services
#endregion
#region 线Z轴联动 | Source-Detector Z-axis Linkage
/// <summary>
/// 启用/禁用射线源与探测器Z轴联动 | Enable/disable Source-Detector Z-axis linkage
/// </summary>
/// <param name="enabled">true=启用联动,false=禁用联动 | true=enable linkage, false=disable linkage</param>
/// <returns>操作结果 | Operation result</returns>
public MotionResult SetSourceDetectorZLinkage(bool enabled)
{
try
{
var config = _config.SourceDetectorZLinkage;
if (!config.Enabled)
{
_logger.Warn("射线源与探测器Z轴联动未在配置中启用 | Source-Detector Z-axis linkage not enabled in config");
return MotionResult.Fail("射线源与探测器Z轴联动未启用 | Source-Detector Z-axis linkage not enabled");
}
// 写入联动使能信号 | Write linkage enable signal
var result = _signalService.EnqueueWrite(MotionSignalNames.SourceDetZ_Linkage_Enable, (bool)enabled);
if (result)
{
_logger.Info("射线源与探测器Z轴联动已{Enabled} | Source-Detector Z-axis linkage {Enabled}",
enabled ? "启用 | enabled" : "禁用 | disabled");
}
else
{
_logger.Warn("射线源与探测器Z轴联动使能写入失败 | Source-Detector Z-axis linkage enable write failed");
}
return result ? MotionResult.Ok() : MotionResult.Fail("联动使能写入失败 | Linkage enable write failed");
}
catch (Exception ex)
{
_logger.Error(ex, "射线源与探测器Z轴联动设置异常: {Message} | Source-Detector Z-axis linkage setting error: {Message}", ex.Message);
return MotionResult.Fail($"联动设置异常: {ex.Message}");
}
}
/// <summary>
/// 设置虚拟摇杆使能 | Set virtual joystick enable
/// </summary>
/// <param name="enabled">true=启用虚拟摇杆,false=禁用虚拟摇杆 | true=enable virtual joystick, false=disable virtual joystick</param>
/// <returns>操作结果 | Operation result</returns>
public MotionResult SetVirtualJoystickEnable(bool enabled)
{
try
{
var result = _signalService.EnqueueWrite(MotionSignalNames.VirtualJoystick_Enable, (bool)enabled);
if (result)
{
_logger.Info("虚拟摇杆已{Enabled} | Virtual joystick {Enabled}",
enabled ? "启用 | enabled" : "禁用 | disabled");
}
else
{
_logger.Warn("虚拟摇杆使能写入失败 | Virtual joystick enable write failed");
}
return result ? MotionResult.Ok() : MotionResult.Fail("虚拟摇杆使能写入失败 | Virtual joystick enable write failed");
}
catch (Exception ex)
{
_logger.Error(ex, "虚拟摇杆使能设置异常: {Message} | Virtual joystick enable setting error: {Message}", ex.Message);
return MotionResult.Fail($"虚拟摇杆使能设置异常: {ex.Message}");
}
}
#endregion
#region | Safety Door Control
/// <summary>
@@ -85,9 +85,11 @@ namespace XP.Hardware.MotionControl.ViewModels
ToggleSwapMouseButtonsCommand = new DelegateCommand(ExecuteToggleSwapMouseButtons);
SavePositionsCommand = new DelegateCommand(ExecuteSavePositions);
RestorePositionsCommand = new DelegateCommand(ExecuteRestorePositions, () => _savedPositions != null && IsPlcConnected);
// 射线源与探测器Z轴联动命令 | Source-Detector Z-axis linkage command
SZDZLockCommand = new DelegateCommand(() => SafeRun(ExecuteSZDZLock), () => IsPlcConnected);
// 初始化 Jog 状态跟踪字典 | Initialize jog state tracking dictionaries
foreach (AxisId axisId in Enum.GetValues(typeof(AxisId)))
// 初始化 Jog 状态跟踪字典 | Initialize jog state tracking dictionaries
foreach (AxisId axisId in Enum.GetValues(typeof(AxisId)))
_linearJogActive[axisId] = false;
foreach (RotaryAxisId axisId in Enum.GetValues(typeof(RotaryAxisId)))
_rotaryJogActive[axisId] = false;
@@ -267,12 +269,16 @@ namespace XP.Hardware.MotionControl.ViewModels
/// <summary>错误提示信息 | Error message</summary>
public string ErrorMessage { get => _errorMessage; set => SetProperty(ref _errorMessage, value); }
#endregion
// 射线源与探测器Z轴联动状态 | Source-Detector Z-axis linkage state
private bool _szdzLock;
public bool SZDZLock { get => _szdzLock; set => SetProperty(ref _szdzLock, value); }
#region | Saved Positions State
#endregion
/// <summary>是否有保存的位置数据 | Whether saved position data exists</summary>
public bool HasSavedPositions => _savedPositions != null;
#region | Saved Positions State
/// <summary>是否有保存的位置数据 | Whether saved position data exists</summary>
public bool HasSavedPositions => _savedPositions != null;
#endregion
@@ -290,14 +296,16 @@ namespace XP.Hardware.MotionControl.ViewModels
/// <summary>恢复保存的轴位置命令 | Restore saved axis positions command</summary>
public DelegateCommand RestorePositionsCommand { get; }
#endregion
/// <summary>射线源与探测器Z轴锁定移动命令 | Source-Detector Z-axis lock move command</summary>
public DelegateCommand SZDZLockCommand { get; }
#endregion
#region | Event Callbacks
#region | Event Callbacks
/// <summary>
/// 几何参数更新回调,刷新轴实际位置 | Geometry updated callback, refresh axis actual positions
/// </summary>
private void OnGeometryUpdated(GeometryData data)
/// <summary>
/// 几何参数更新回调,刷新轴实际位置 | Geometry updated callback, refresh axis actual positions
/// </summary>
private void OnGeometryUpdated(GeometryData data)
{
try
{
@@ -453,8 +461,24 @@ namespace XP.Hardware.MotionControl.ViewModels
{
IsJoystickEnabled = !IsJoystickEnabled;
_logger.Info("摇杆使能状态切换:{Enabled} | Joystick enable toggled: {Enabled}", IsJoystickEnabled);
// TODO: 发送使能状态到 PLC(根据实际 PLC 信号定义)| Send enable state to PLC (based on actual PLC signal definition)
}
// 发送使能状态到 PLC(根据实际 PLC 信号定义)| Send enable state to PLC (based on actual PLC signal definition)
try
{
// 设置虚拟摇杆使能 | Set virtual joystick enable
var result = _motionControlService.SetVirtualJoystickEnable(IsJoystickEnabled);
if (!result.Success)
{
MessageBox.Show(result.ErrorMessage, XP.Common.Localization.LocalizationHelper.Get("MC_Error"),
MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, XP.Common.Localization.LocalizationHelper.Get("MC_Error"),
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 切换左右键交换状态 | Toggle swap mouse buttons state
@@ -515,15 +539,42 @@ namespace XP.Hardware.MotionControl.ViewModels
_logger.Info("轴位置已恢复并发送移动命令 | Axis positions restored and move commands sent");
}
#endregion
/// <summary>射线源与探测器Z轴锁定移动 | Source-Detector Z-axis lock move</summary>
private void ExecuteSZDZLock()
{
try
{
// 切换联动状态 | Toggle linkage state
SZDZLock = !SZDZLock;
#region Jog | Joystick Jog Mapping Logic
// 调用服务设置联动 | Call service to set linkage
var result = _motionControlService.SetSourceDetectorZLinkage(SZDZLock);
/// <summary>
/// 处理双轴摇杆输出变化,根据当前激活按键映射到对应轴的 Jog 操作
/// Handle dual joystick output changes, map to corresponding axis jog based on active button
/// </summary>
private void HandleDualJoystickOutput()
if (!result.Success)
{
// 如果设置失败,恢复状态 | If set failed, restore state
SZDZLock = !SZDZLock;
MessageBox.Show(result.ErrorMessage, XP.Common.Localization.LocalizationHelper.Get("MC_Error"),
MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
catch (Exception ex)
{
// 异常时恢复状态 | Restore state on exception
SZDZLock = !SZDZLock;
MessageBox.Show(ex.Message, XP.Common.Localization.LocalizationHelper.Get("MC_Error"),
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
#endregion
#region Jog | Joystick Jog Mapping Logic
/// <summary>
/// 处理双轴摇杆输出变化,根据当前激活按键映射到对应轴的 Jog 操作
/// Handle dual joystick output changes, map to corresponding axis jog based on active button
/// </summary>
private void HandleDualJoystickOutput()
{
switch (DualJoystickActiveButton)
{
@@ -555,12 +606,20 @@ namespace XP.Hardware.MotionControl.ViewModels
case MouseButtonType.Left:
// 左键:Y→SourceZ Jog | Left button: Y→SourceZ Jog
UpdateLinearJog(AxisId.SourceZ, SingleJoystickOutputY);
if (_szdzLock)
{
UpdateLinearJog(AxisId.DetectorZ, SingleJoystickOutputY);
}
break;
case MouseButtonType.Right:
// 右键:Y→DetectorZ Jog | Right button: Y→DetectorZ Jog
UpdateLinearJog(AxisId.DetectorZ, SingleJoystickOutputY);
break;
UpdateLinearJog(AxisId.DetectorZ, SingleJoystickOutputY);
if (_szdzLock)
{
UpdateLinearJog(AxisId.SourceZ, SingleJoystickOutputY);
}
break;
}
}
@@ -47,6 +47,7 @@
<!-- ===== 左侧:轴位置输入框 ===== -->
<Grid Grid.Column="0" Margin="0,0,4,0" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
@@ -60,26 +61,31 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{loc:Localization AC_StageX}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="0" Grid.Column="0" x:Name="NumStageX" Value="{Binding StageXPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageX_GotFocus" LostFocus="NumStageX_LostFocus" KeyDown="NumStageX_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{loc:Localization AC_StageX}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{loc:Localization AC_LengthUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="0" Grid.Column="1" x:Name="NumStageX" Value="{Binding StageXPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageX_GotFocus" LostFocus="NumStageX_LostFocus" KeyDown="NumStageX_KeyDown" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{loc:Localization AC_StageY}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="1" Grid.Column="0" x:Name="NumStageY" Value="{Binding StageYPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageY_GotFocus" LostFocus="NumStageY_LostFocus" KeyDown="NumStageY_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="{loc:Localization AC_StageY}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="{loc:Localization AC_LengthUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="1" Grid.Column="1" x:Name="NumStageY" Value="{Binding StageYPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageY_GotFocus" LostFocus="NumStageY_LostFocus" KeyDown="NumStageY_KeyDown" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="{loc:Localization AC_SourceZ}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="{loc:Localization AC_LengthUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="2" Grid.Column="1" x:Name="NumSourceZ" Value="{Binding SourceZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumSourceZ_GotFocus" LostFocus="NumSourceZ_LostFocus" KeyDown="NumSourceZ_KeyDown" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{loc:Localization AC_SourceZ}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="2" Grid.Column="0" x:Name="NumSourceZ" Value="{Binding SourceZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumSourceZ_GotFocus" LostFocus="NumSourceZ_LostFocus" KeyDown="NumSourceZ_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="{loc:Localization AC_DetectorZ}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1"/>
<TextBlock Grid.Row="3" Grid.Column="2" Text="{loc:Localization AC_LengthUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="3" Grid.Column="1" x:Name="NumDetectorZ" Value="{Binding DetectorZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumDetectorZ_GotFocus" LostFocus="NumDetectorZ_LostFocus" KeyDown="NumDetectorZ_KeyDown" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="{loc:Localization AC_DetectorSwing}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1" Visibility="{Binding DetectorSwingVisibility}"/>
<TextBlock Grid.Row="4" Grid.Column="2" Text="{loc:Localization AC_AngleUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1" Visibility="{Binding DetectorSwingVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="4" Grid.Column="1" x:Name="NumDetSwing" Value="{Binding DetectorSwingAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumDetSwing_GotFocus" LostFocus="NumDetSwing_LostFocus" KeyDown="NumDetSwing_KeyDown" Visibility="{Binding DetectorSwingVisibility}" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{loc:Localization AC_DetectorZ}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="3" Grid.Column="0" x:Name="NumDetectorZ" Value="{Binding DetectorZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumDetectorZ_GotFocus" LostFocus="NumDetectorZ_LostFocus" KeyDown="NumDetectorZ_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="{loc:Localization AC_StageRotation}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1" Visibility="{Binding StageRotationVisibility}"/>
<TextBlock Grid.Row="5" Grid.Column="2" Text="{loc:Localization AC_AngleUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1" Visibility="{Binding StageRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="5" Grid.Column="1" x:Name="NumStageRot" Value="{Binding StageRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageRot_GotFocus" LostFocus="NumStageRot_LostFocus" KeyDown="NumStageRot_KeyDown" Visibility="{Binding StageRotationVisibility}" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="4" Grid.Column="1" Text="{loc:Localization AC_DetectorSwing}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1" Visibility="{Binding DetectorSwingVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="4" Grid.Column="0" x:Name="NumDetSwing" Value="{Binding DetectorSwingAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumDetSwing_GotFocus" LostFocus="NumDetSwing_LostFocus" KeyDown="NumDetSwing_KeyDown" Visibility="{Binding DetectorSwingVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="5" Grid.Column="1" Text="{loc:Localization AC_StageRotation}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1" Visibility="{Binding StageRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="5" Grid.Column="0" x:Name="NumStageRot" Value="{Binding StageRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageRot_GotFocus" LostFocus="NumStageRot_LostFocus" KeyDown="NumStageRot_KeyDown" Visibility="{Binding StageRotationVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="6" Grid.Column="1" Text="{loc:Localization AC_FixtureRotation}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1" Visibility="{Binding FixtureRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="6" Grid.Column="0" x:Name="NumFixtureRot" Value="{Binding FixtureRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumFixtureRot_GotFocus" LostFocus="NumFixtureRot_LostFocus" KeyDown="NumFixtureRot_KeyDown" Visibility="{Binding FixtureRotationVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="6" Grid.Column="0" Text="{loc:Localization AC_FixtureRotation}" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Right" Margin="3,1,1,1" Visibility="{Binding FixtureRotationVisibility}"/>
<TextBlock Grid.Row="6" Grid.Column="2" Text="{loc:Localization AC_AngleUnit}" FontSize="11" VerticalAlignment="Center" Margin="1,1,1,1" Visibility="{Binding FixtureRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="6" Grid.Column="1" x:Name="NumFixtureRot" Value="{Binding FixtureRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumFixtureRot_GotFocus" LostFocus="NumFixtureRot_LostFocus" KeyDown="NumFixtureRot_KeyDown" Visibility="{Binding FixtureRotationVisibility}" Margin="4,1,2,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
</Grid>
<!-- ===== 右侧:摇杆区域 ===== -->
@@ -120,10 +126,12 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 虚拟摇杆使能开关 -->
<telerik:RadButton Grid.Column="1" Width="35" Height="24" Margin="0,0,8,0"
<telerik:RadButton Grid.Column="1" Width="38" Height="26" Margin="0,0,8,0"
Command="{Binding ToggleEnableCommand}"
ToolTip="{loc:Localization AC_Enable}"
telerik:StyleManager.Theme="Crystal">
@@ -148,7 +156,7 @@
</telerik:RadButton>
<!-- 摇杆左右键功能切换开关 -->
<telerik:RadButton Grid.Column="2" Width="35" Height="24" Margin="0,0,8,0"
<telerik:RadButton Grid.Column="2" Width="38" Height="26" Margin="0,0,8,0"
Command="{Binding ToggleSwapMouseButtonsCommand}"
ToolTip="{loc:Localization AC_SwapMouseButtons}"
telerik:StyleManager.Theme="Crystal">
@@ -156,14 +164,39 @@
<Style TargetType="telerik:RadButton">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SwingDisable.png" Width="19" Height="17"/>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SwingDisable.png" Width="20" Height="19"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding SwapMouseButtons}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SwingEnable.png" Width="17" Height="17"/>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SwingEnable.png" Width="20" Height="19"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>
<!-- 射线源探测器Z轴锁定移动 -->
<telerik:RadButton Grid.Column="3" Width="38" Height="26" Margin="0,0,8,0"
Command="{Binding SZDZLockCommand}"
ToolTip="{loc:Localization AC_SZDZLock}"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SZDZLockDisable.png" Width="19" Height="19"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding SZDZLock}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SZDZLockEnable.png" Width="19" Height="19"/>
</Setter.Value>
</Setter>
</DataTrigger>
@@ -173,7 +206,7 @@
</telerik:RadButton>
<!-- 保存当前位置 -->
<telerik:RadButton Grid.Column="3" Width="35" Height="24" Margin="0,0,8,0"
<telerik:RadButton Grid.Column="4" Width="38" Height="26" Margin="0,0,8,0"
Command="{Binding SavePositionsCommand}"
ToolTip="{loc:Localization AC_Save}"
telerik:StyleManager.Theme="Crystal">
@@ -189,7 +222,7 @@
</telerik:RadButton>
<!-- 恢复前一位置 -->
<telerik:RadButton Grid.Column="4" Width="35" Height="24" Margin="0,0,8,0"
<telerik:RadButton Grid.Column="5" Width="38" Height="26" Margin="0,0,8,0"
Command="{Binding RestorePositionsCommand}"
ToolTip="{loc:Localization AC_Restore}"
IsEnabled="{Binding HasSavedPositions}"
+2 -2
View File
@@ -179,8 +179,8 @@ namespace XP.Hardware.Plc.Services
{
StatusText = $"连接异常: {ex.Message} | Connection exception: {ex.Message}";
_logger.Error(ex, $"PLC 初始化失败: {ex.Message} | PLC initialization failed: {ex.Message}");
MessageBox.Show($"PLC初始化失败 | PLC initialization failed: {ex.Message}",
"错误 | Error", MessageBoxButton.OK, MessageBoxImage.Error);
//MessageBox.Show($"PLC初始化失败 | PLC initialization failed: {ex.Message}",
// "错误 | Error", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
catch (Exception ex)
@@ -9,7 +9,7 @@
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="245" Background="White" >
prism:ViewModelLocator.AutoWireViewModel="True" Height="230" Background="White" >
<UserControl.Resources>
<!-- 转换器 | Converters -->
<converters:RaySourceStatusToColorConverter x:Key="StatusToColorConverter"/>
@@ -63,8 +63,8 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" MinHeight="70" />
<RowDefinition Height="Auto" MinHeight="70" />
<RowDefinition Height="Auto" MinHeight="65" />
<RowDefinition Height="Auto" MinHeight="65" />
</Grid.RowDefinitions>
<!-- 标题栏 -->
@@ -187,16 +187,24 @@
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_VoltageLabel}"
FontSize="13" FontWeight="Bold" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="{Binding VoltageActualText}"
FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right"/>
FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="18"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="35"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<telerik:RadSlider x:Name="VoltageSlider" Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,5,10,0" VerticalAlignment="Center"
<!-- 最小值 | Minimum Value -->
<TextBlock Grid.Column="0" Text="{Binding VoltageMin, StringFormat={}{0:F0}}"
FontSize="10" Foreground="#616161"
HorizontalAlignment="Right" VerticalAlignment="Center" TextAlignment="Right"
Margin="0,5,5,5"/>
<telerik:RadSlider x:Name="VoltageSlider" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,5,5,5" VerticalAlignment="Center"
telerik:StyleManager.Theme="Crystal"
Minimum="{Binding VoltageMin}"
Maximum="{Binding VoltageMax}"
@@ -204,23 +212,21 @@
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"
<!-- 最大值 | Maximum Value -->
<TextBlock Grid.Column="2" Text="{Binding VoltageMax, StringFormat={}{0:F0}}"
FontSize="10" Foreground="#616161"
HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Left"
Margin="0,5,10,5"/>
<telerik:RadNumericUpDown x:Name="VoltageNumeric" Grid.Column="3" HorizontalAlignment="Center" Margin="0,5,0,5" 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">
@@ -248,17 +254,25 @@
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_CurrentLabel}"
FontSize="13" FontWeight="Bold" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="{Binding CurrentActualText}"
FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right"/>
FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right"/>
</Grid>
<!-- 滑块 | Slider -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="18"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="35"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<telerik:RadSlider x:Name="CurrentSlider" Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,6,10,0" VerticalAlignment="Top"
<!-- 最小值 | Minimum Value -->
<TextBlock Grid.Column="0" Text="{Binding CurrentMin, StringFormat={}{0:F0}}"
FontSize="10" Foreground="#616161"
HorizontalAlignment="Right" VerticalAlignment="Center" TextAlignment="Right"
Margin="0,5,5,5"/>
<telerik:RadSlider x:Name="CurrentSlider" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,5,5,5" VerticalAlignment="Center"
telerik:StyleManager.Theme="Crystal"
Minimum="{Binding CurrentMin}"
Maximum="{Binding CurrentMax}"
@@ -266,23 +280,20 @@
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"
<!-- 最大值 | Maximum Value -->
<TextBlock Grid.Column="2" Text="{Binding CurrentMax, StringFormat={}{0:F0}}"
FontSize="10" Foreground="#616161"
HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Left"
Margin="0,5,10,5"/>
<telerik:RadNumericUpDown x:Name="CurrentNumeric" Grid.Column="3" HorizontalAlignment="Center" Margin="0,5,0,5" 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 -->
+4
View File
@@ -162,6 +162,10 @@
<!-- 运行参数 | Runtime parameters -->
<add key="MotionControl:PollingInterval" value="500" />
<add key="MotionControl:DefaultVelocity" value="500" />
<!-- 射线源与探测器Z轴联动配置 | Source-Detector Z-axis linkage configuration -->
<add key="MotionControl:SourceDetectorZLinkage:Enabled" value="true" />
<add key="MotionControl:SourceDetectorZLinkage:TriggerThreshold" value="1.0" />
<add key="MotionControl:SourceDetectorZLinkage:SpeedPercent" value="100" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />