更新121
This commit is contained in:
@@ -7,6 +7,8 @@ public sealed class CValueCalibrationActionViewModel : ObservableObject
|
||||
{
|
||||
private bool _isActive;
|
||||
private bool _isStatusKnown;
|
||||
private bool _isBusy;
|
||||
private string _busyDisplayText = string.Empty;
|
||||
|
||||
public CValueCalibrationActionViewModel(
|
||||
string label,
|
||||
@@ -54,11 +56,31 @@ public sealed class CValueCalibrationActionViewModel : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayText => IsStatusKnown
|
||||
public bool IsBusy
|
||||
{
|
||||
get => _isBusy;
|
||||
private set
|
||||
{
|
||||
if (SetProperty(ref _isBusy, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(DisplayText));
|
||||
OnPropertyChanged(nameof(StatusText));
|
||||
OnPropertyChanged(nameof(IsEnabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnabled => !IsBusy;
|
||||
|
||||
public string DisplayText => IsBusy
|
||||
? _busyDisplayText
|
||||
: IsStatusKnown
|
||||
? IsActive ? ActiveDisplayText : InactiveDisplayText
|
||||
: $"{Label}:未知";
|
||||
|
||||
public string StatusText => IsStatusKnown
|
||||
public string StatusText => IsBusy
|
||||
? "进行中"
|
||||
: IsStatusKnown
|
||||
? IsActive ? "开启" : "关闭"
|
||||
: "未知";
|
||||
|
||||
@@ -67,4 +89,21 @@ public sealed class CValueCalibrationActionViewModel : ObservableObject
|
||||
IsStatusKnown = isStatusKnown;
|
||||
IsActive = isActive;
|
||||
}
|
||||
|
||||
public void BeginWaiting(string busyDisplayText)
|
||||
{
|
||||
_busyDisplayText = busyDisplayText;
|
||||
IsStatusKnown = true;
|
||||
IsActive = true;
|
||||
IsBusy = true;
|
||||
OnPropertyChanged(nameof(DisplayText));
|
||||
OnPropertyChanged(nameof(StatusText));
|
||||
}
|
||||
|
||||
public void FinishWaiting()
|
||||
{
|
||||
IsStatusKnown = true;
|
||||
IsActive = false;
|
||||
IsBusy = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
private readonly Action _calibrationCompletedAction;
|
||||
private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService;
|
||||
private readonly DispatcherTimer _refreshTimer;
|
||||
private readonly DispatcherTimer _pairedActionCompletionTimer;
|
||||
private readonly Dictionary<string, CValueCalibrationActionViewModel> _actionsByLabel = [];
|
||||
private readonly Dictionary<string, PairedActionWaitState> _pairedActionWaitStates = [];
|
||||
private readonly HashSet<ushort> _loggedFloatDiagnostics = [];
|
||||
private readonly HashSet<ushort> _loggedInvalidFloatDiagnostics = [];
|
||||
private string _baselineOxygenText = "";
|
||||
@@ -90,6 +92,22 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
];
|
||||
_actionsByLabel[CalibrationStartAction].UpdateStatus(false);
|
||||
_actionsByLabel[BaselineCollectionAction].UpdateStatus(false);
|
||||
_pairedActionWaitStates[CalibrationStartAction] = new PairedActionWaitState(
|
||||
CalibrationEndCoil,
|
||||
"标定中",
|
||||
"标定完成",
|
||||
_calibrationCompletedAction);
|
||||
_pairedActionWaitStates[BaselineCollectionAction] = new PairedActionWaitState(
|
||||
BaselineEndCoil,
|
||||
"基线采集中",
|
||||
"基线采集完成",
|
||||
_baselineCollectionCompletedAction);
|
||||
|
||||
_pairedActionCompletionTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(250)
|
||||
};
|
||||
_pairedActionCompletionTimer.Tick += (_, _) => RefreshPairedActionCompletions();
|
||||
|
||||
RefreshDeviceValues();
|
||||
_refreshTimer = new DispatcherTimer
|
||||
@@ -155,14 +173,13 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
return;
|
||||
}
|
||||
|
||||
LastAction = action;
|
||||
|
||||
if (IsPairedAction(action))
|
||||
{
|
||||
TogglePairedAction(action);
|
||||
StartPairedAction(action);
|
||||
return;
|
||||
}
|
||||
|
||||
LastAction = action;
|
||||
ToggleHoldAction(action);
|
||||
}
|
||||
|
||||
@@ -324,7 +341,7 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
Debug.WriteLine($"C value calibration action '{action}' write failed.");
|
||||
}
|
||||
|
||||
private void TogglePairedAction(string action)
|
||||
private void StartPairedAction(string action)
|
||||
{
|
||||
if (!TryGetPairedActionCoils(action, out var startCoilAddress, out var endCoilAddress, out var endActionText))
|
||||
{
|
||||
@@ -336,34 +353,98 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
return;
|
||||
}
|
||||
|
||||
var isActive = actionViewModel.IsActive;
|
||||
var coilAddress = isActive ? endCoilAddress : startCoilAddress;
|
||||
var actionText = isActive ? endActionText : action;
|
||||
|
||||
if (TryStartCoilPulse(coilAddress, actionText))
|
||||
if (actionViewModel.IsBusy)
|
||||
{
|
||||
var completedBaselineCollection = action == BaselineCollectionAction && isActive;
|
||||
var completedCalibration = action == CalibrationStartAction && isActive;
|
||||
LastAction = completedBaselineCollection
|
||||
? "基线采集完成"
|
||||
: completedCalibration ? "标定完成" : actionText;
|
||||
actionViewModel.UpdateStatus(!isActive);
|
||||
|
||||
if (completedBaselineCollection)
|
||||
{
|
||||
_baselineCollectionCompletedAction();
|
||||
}
|
||||
|
||||
if (completedCalibration)
|
||||
{
|
||||
_calibrationCompletedAction();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LastAction = $"{actionText}失败";
|
||||
Debug.WriteLine($"C value calibration action '{actionText}' write failed.");
|
||||
if (!_pairedActionWaitStates.TryGetValue(action, out var waitState))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryStartCoilPulse(startCoilAddress, action))
|
||||
{
|
||||
LastAction = $"{action}失败";
|
||||
Debug.WriteLine($"C value calibration action '{action}' write failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
var completionIsAlreadyActive = _tcpDeviceConnectionService.TryReadCoil(endCoilAddress, out var isComplete) && isComplete;
|
||||
waitState.Begin(completionIsAlreadyActive);
|
||||
actionViewModel.BeginWaiting(waitState.WaitingText);
|
||||
_pairedActionCompletionTimer.Start();
|
||||
LastAction = waitState.WaitingText;
|
||||
|
||||
if (completionIsAlreadyActive)
|
||||
{
|
||||
Debug.WriteLine(
|
||||
$"C value calibration completion coil {endCoilAddress} was already active when '{action}' started; "
|
||||
+ "waiting for it to reset before accepting completion.");
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshPairedActionCompletions()
|
||||
{
|
||||
var hasWaitingAction = false;
|
||||
|
||||
foreach (var (action, waitState) in _pairedActionWaitStates)
|
||||
{
|
||||
if (!waitState.IsWaiting)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasWaitingAction = true;
|
||||
|
||||
if (!_actionsByLabel.TryGetValue(action, out var actionViewModel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_tcpDeviceConnectionService.TryReadCoil(waitState.CompletionCoilAddress, out var isComplete))
|
||||
{
|
||||
LastAction = $"{waitState.WaitingText},完成状态读取失败";
|
||||
Debug.WriteLine(
|
||||
$"C value calibration completion coil {waitState.CompletionCoilAddress} read failed for '{action}'.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isComplete)
|
||||
{
|
||||
waitState.MarkCompletionInactive();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (waitState.RequiresInactiveBeforeCompletion && !waitState.HasSeenInactiveCompletionState)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CompletePairedAction(waitState, actionViewModel);
|
||||
}
|
||||
|
||||
if (!hasWaitingAction)
|
||||
{
|
||||
_pairedActionCompletionTimer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void CompletePairedAction(
|
||||
PairedActionWaitState waitState,
|
||||
CValueCalibrationActionViewModel actionViewModel)
|
||||
{
|
||||
LastAction = waitState.CompletedText;
|
||||
waitState.End();
|
||||
|
||||
try
|
||||
{
|
||||
waitState.CompletedAction();
|
||||
}
|
||||
finally
|
||||
{
|
||||
actionViewModel.FinishWaiting();
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryStartCoilPulse(ushort coilAddress, string actionText)
|
||||
@@ -441,4 +522,44 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
{
|
||||
return action is BaselineCollectionAction or CalibrationStartAction;
|
||||
}
|
||||
|
||||
private sealed class PairedActionWaitState(
|
||||
ushort completionCoilAddress,
|
||||
string waitingText,
|
||||
string completedText,
|
||||
Action completedAction)
|
||||
{
|
||||
public ushort CompletionCoilAddress { get; } = completionCoilAddress;
|
||||
|
||||
public string WaitingText { get; } = waitingText;
|
||||
|
||||
public string CompletedText { get; } = completedText;
|
||||
|
||||
public Action CompletedAction { get; } = completedAction;
|
||||
|
||||
public bool IsWaiting { get; private set; }
|
||||
|
||||
public bool RequiresInactiveBeforeCompletion { get; private set; }
|
||||
|
||||
public bool HasSeenInactiveCompletionState { get; private set; }
|
||||
|
||||
public void Begin(bool completionIsAlreadyActive)
|
||||
{
|
||||
IsWaiting = true;
|
||||
RequiresInactiveBeforeCompletion = completionIsAlreadyActive;
|
||||
HasSeenInactiveCompletionState = !completionIsAlreadyActive;
|
||||
}
|
||||
|
||||
public void MarkCompletionInactive()
|
||||
{
|
||||
HasSeenInactiveCompletionState = true;
|
||||
}
|
||||
|
||||
public void End()
|
||||
{
|
||||
IsWaiting = false;
|
||||
RequiresInactiveBeforeCompletion = false;
|
||||
HasSeenInactiveCompletionState = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@
|
||||
<Button Content="{Binding DisplayText}"
|
||||
Command="{Binding Command}"
|
||||
CommandParameter="{Binding Label}"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
Width="150"
|
||||
Height="42"
|
||||
Margin="0,5,14,5"
|
||||
@@ -252,6 +253,7 @@
|
||||
<Button Content="{Binding DisplayText}"
|
||||
Command="{Binding Command}"
|
||||
CommandParameter="{Binding Label}"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
Width="150"
|
||||
Height="42"
|
||||
Margin="0,5,24,5"
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
BorderBrush="#AEB7B2"
|
||||
BorderThickness="1">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="72" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<TextBlock Text="{Binding BodyText}"
|
||||
@@ -26,6 +31,21 @@
|
||||
LineHeight="43"
|
||||
TextWrapping="Wrap" />
|
||||
</ScrollViewer>
|
||||
|
||||
<Border Grid.Row="1"
|
||||
BorderBrush="#D7DEDA"
|
||||
BorderThickness="0,1,0,0"
|
||||
Background="#F7F9F8">
|
||||
<Button Content="确定"
|
||||
Width="120"
|
||||
Height="42"
|
||||
Margin="0,0,24,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsDefault="True"
|
||||
Click="ConfirmButton_Click"
|
||||
Style="{StaticResource InstrumentButtonStyle}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
@@ -10,4 +10,10 @@ public partial class HelpDialogWindow : Window
|
||||
InitializeComponent();
|
||||
DataContext = new HelpDialogViewModel(headerText, titleText, bodyText);
|
||||
}
|
||||
|
||||
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user