This commit is contained in:
GukSang.Jin
2026-05-28 13:40:07 +08:00
parent a5cdb1d9d5
commit a700cab0b2
4 changed files with 163 additions and 18 deletions

View File

@@ -1,16 +1,11 @@
using System.Windows.Input;
namespace ConeCalorimeter.ViewModels; namespace ConeCalorimeter.ViewModels;
public sealed class SmokeDensityCalibrationViewModel public sealed class SmokeDensityCalibrationViewModel
{ {
public SmokeDensityCalibrationViewModel(string label, ICommand command) public SmokeDensityCalibrationViewModel(string label)
{ {
Label = label; Label = label;
Command = command;
} }
public string Label { get; } public string Label { get; }
public ICommand Command { get; }
} }

View File

@@ -21,6 +21,7 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
private readonly DispatcherTimer _refreshTimer; private readonly DispatcherTimer _refreshTimer;
private readonly HashSet<ushort> _loggedFloatDiagnostics = []; private readonly HashSet<ushort> _loggedFloatDiagnostics = [];
private readonly HashSet<ushort> _loggedInvalidFloatDiagnostics = []; private readonly HashSet<ushort> _loggedInvalidFloatDiagnostics = [];
private readonly HashSet<string> _pressedCalibrationLabels = [];
private double? _stableAbsorbance; private double? _stableAbsorbance;
private double? _pendingAbsorbance; private double? _pendingAbsorbance;
private int _pendingAbsorbanceReadCount; private int _pendingAbsorbanceReadCount;
@@ -34,15 +35,14 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
_closeAction = closeAction; _closeAction = closeAction;
_tcpDeviceConnectionService = tcpDeviceConnectionService; _tcpDeviceConnectionService = tcpDeviceConnectionService;
CloseCommand = new RelayCommand(_closeAction); CloseCommand = new RelayCommand(_closeAction);
CalibrationCommand = new RelayCommand<string>(Calibrate);
CalibrationActions = CalibrationActions =
[ [
new SmokeDensityCalibrationViewModel("0%校准", CalibrationCommand), new SmokeDensityCalibrationViewModel("0%校准"),
new SmokeDensityCalibrationViewModel("25%校准", CalibrationCommand), new SmokeDensityCalibrationViewModel("25%校准"),
new SmokeDensityCalibrationViewModel("50%校准", CalibrationCommand), new SmokeDensityCalibrationViewModel("50%校准"),
new SmokeDensityCalibrationViewModel("75%校准", CalibrationCommand), new SmokeDensityCalibrationViewModel("75%校准"),
new SmokeDensityCalibrationViewModel("100%校准", CalibrationCommand) new SmokeDensityCalibrationViewModel("100%校准")
]; ];
RefreshDeviceValues(); RefreshDeviceValues();
@@ -58,8 +58,6 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
public IRelayCommand CloseCommand { get; } public IRelayCommand CloseCommand { get; }
public IRelayCommand<string> CalibrationCommand { get; }
public string AbsorbanceText public string AbsorbanceText
{ {
get => _absorbanceText; get => _absorbanceText;
@@ -72,13 +70,18 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
private set => SetProperty(ref _lastCalibration, value); private set => SetProperty(ref _lastCalibration, value);
} }
private void Calibrate(string? label) public void PressCalibration(string? label)
{ {
if (string.IsNullOrWhiteSpace(label)) if (string.IsNullOrWhiteSpace(label))
{ {
return; return;
} }
if (_pressedCalibrationLabels.Contains(label))
{
return;
}
LastCalibration = label; LastCalibration = label;
if (!TryGetCalibrationCoil(label, out var coilAddress)) if (!TryGetCalibrationCoil(label, out var coilAddress))
@@ -89,7 +92,34 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
if (!_tcpDeviceConnectionService.TryWriteCoil(coilAddress, true)) if (!_tcpDeviceConnectionService.TryWriteCoil(coilAddress, true))
{ {
LastCalibration = $"{label}失败"; LastCalibration = $"{label}失败";
Debug.WriteLine($"Smoke density calibration '{label}' write failed."); Debug.WriteLine($"Smoke density calibration '{label}' press write failed.");
return;
}
_pressedCalibrationLabels.Add(label);
}
public void ReleaseCalibration(string? label)
{
if (string.IsNullOrWhiteSpace(label))
{
return;
}
if (!_pressedCalibrationLabels.Remove(label))
{
return;
}
if (!TryGetCalibrationCoil(label, out var coilAddress))
{
return;
}
if (!_tcpDeviceConnectionService.TryWriteCoil(coilAddress, false))
{
LastCalibration = $"{label}复位失败";
Debug.WriteLine($"Smoke density calibration '{label}' release write failed.");
} }
} }

View File

@@ -78,8 +78,14 @@
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<Button Content="{Binding Label}" <Button Content="{Binding Label}"
Command="{Binding Command}" PreviewMouseLeftButtonDown="CalibrationButton_PreviewMouseLeftButtonDown"
CommandParameter="{Binding Label}" PreviewMouseLeftButtonUp="CalibrationButton_PreviewMouseLeftButtonUp"
MouseLeave="CalibrationButton_MouseLeave"
LostMouseCapture="CalibrationButton_LostMouseCapture"
TouchDown="CalibrationButton_TouchDown"
TouchUp="CalibrationButton_TouchUp"
TouchLeave="CalibrationButton_TouchLeave"
LostTouchCapture="CalibrationButton_LostTouchCapture"
Width="128" Width="128"
Height="42" Height="42"
Margin="0,8,24,8" Margin="0,8,24,8"

View File

@@ -1,4 +1,7 @@
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using ConeCalorimeter.ViewModels;
namespace ConeCalorimeter.Views; namespace ConeCalorimeter.Views;
@@ -8,4 +11,115 @@ public partial class SmokeDensitySettingsView : UserControl
{ {
InitializeComponent(); InitializeComponent();
} }
private void CalibrationButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
StartCalibration(sender);
if (sender is Button button)
{
button.CaptureMouse();
}
}
private void CalibrationButton_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
StopCalibration(sender);
ReleaseMouseCapture(sender);
}
private void CalibrationButton_MouseLeave(object sender, MouseEventArgs e)
{
if (sender is Button { IsMouseCaptured: true })
{
StopCalibration(sender);
ReleaseMouseCapture(sender);
}
}
private void CalibrationButton_LostMouseCapture(object sender, MouseEventArgs e)
{
StopCalibration(sender);
}
private void CalibrationButton_TouchDown(object sender, TouchEventArgs e)
{
StartCalibration(sender);
if (sender is Button button)
{
button.CaptureTouch(e.TouchDevice);
}
e.Handled = true;
}
private void CalibrationButton_TouchUp(object sender, TouchEventArgs e)
{
StopCalibration(sender);
ReleaseTouchCapture(sender, e.TouchDevice);
e.Handled = true;
}
private void CalibrationButton_TouchLeave(object sender, TouchEventArgs e)
{
StopCalibration(sender);
ReleaseTouchCapture(sender, e.TouchDevice);
}
private void CalibrationButton_LostTouchCapture(object sender, TouchEventArgs e)
{
StopCalibration(sender);
}
private void StartCalibration(object sender)
{
if (TryGetCalibrationContext(sender, out var viewModel, out var action))
{
viewModel.PressCalibration(action.Label);
}
}
private void StopCalibration(object sender)
{
if (TryGetCalibrationContext(sender, out var viewModel, out var action))
{
viewModel.ReleaseCalibration(action.Label);
}
}
private bool TryGetCalibrationContext(
object sender,
out SmokeDensitySettingsViewModel viewModel,
out SmokeDensityCalibrationViewModel action)
{
viewModel = null!;
action = null!;
if (DataContext is not SmokeDensitySettingsViewModel smokeDensitySettingsViewModel
|| sender is not Button { DataContext: SmokeDensityCalibrationViewModel calibrationAction })
{
return false;
}
viewModel = smokeDensitySettingsViewModel;
action = calibrationAction;
return true;
}
private static void ReleaseMouseCapture(object sender)
{
if (sender is Button { IsMouseCaptured: true } button)
{
button.ReleaseMouseCapture();
}
}
private static void ReleaseTouchCapture(object sender, TouchDevice touchDevice)
{
if (sender is Button button)
{
button.ReleaseTouchCapture(touchDevice);
}
}
} }