Files
VacuumPressureMembranePoreS…/Views/ValveControlWindow.xaml.cs
2026-03-31 20:17:17 +08:00

181 lines
6.3 KiB
C#

using MembranePoreTester.Communication;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
namespace MembranePoreTester.Views
{
public partial class ValveControlWindow : Window
{
private readonly IPlcService _plcService;
private readonly PlcConfiguration _config;
private readonly DispatcherTimer _refreshTimer;
private readonly Dictionary<int, List<ValveInfo>> _valvesByStation = new()
{
[1] = new()
{
new ValveInfo { Name = "高压进气阀", CoilAddress = 100 },
new ValveInfo { Name = "低压进气阀", CoilAddress = 101 },
new ValveInfo { Name = "排气阀", CoilAddress = 102 },
new ValveInfo { Name = "低压保护阀", CoilAddress = 103 },
new ValveInfo { Name = "大流量阀", CoilAddress = 104 },
new ValveInfo { Name = "小流量阀", CoilAddress = 105 },
new ValveInfo { Name = "底部出气阀", CoilAddress = 106 },
new ValveInfo { Name = "顶部出气阀", CoilAddress = 107 }
},
[2] = new()
{
new ValveInfo { Name = "高压进气阀", CoilAddress = 108 },
new ValveInfo { Name = "低压进气阀", CoilAddress = 109 },
new ValveInfo { Name = "排气阀", CoilAddress = 110 },
new ValveInfo { Name = "低压保护阀", CoilAddress = 111 },
new ValveInfo { Name = "大流量阀", CoilAddress = 112 },
new ValveInfo { Name = "小流量阀", CoilAddress = 113 },
new ValveInfo { Name = "底部出气阀", CoilAddress = 114 },
new ValveInfo { Name = "顶部出气阀", CoilAddress = 115 }
},
[3] = new()
{
new ValveInfo { Name = "高压进气阀", CoilAddress = 116 },
new ValveInfo { Name = "低压进气阀", CoilAddress = 117 },
new ValveInfo { Name = "排气阀", CoilAddress = 118 },
new ValveInfo { Name = "低压保护阀", CoilAddress = 119 },
new ValveInfo { Name = "大流量阀", CoilAddress = 120 },
new ValveInfo { Name = "小流量阀", CoilAddress = 121 },
new ValveInfo { Name = "底部出气阀", CoilAddress = 122 },
new ValveInfo { Name = "顶部出气阀", CoilAddress = 123 }
}
};
public ValveControlWindow()
{
InitializeComponent();
_plcService = App.PlcService;
_config = App.PlcConfig;
_refreshTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1)
};
_refreshTimer.Tick += async (s, e) => await RefreshValveStates();
_refreshTimer.Start();
Loaded += (s, e) => ShowStation(1);
}
private void ShowStation(int station)
{
if (valveList == null) return; // 防御性检查
if (_valvesByStation.TryGetValue(station, out var valves))
{
valveList.ItemsSource = valves;
}
else
{
valveList.ItemsSource = null;
}
}
private async void CmbStation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (valveList == null) return; // 初始化未完成
if (cmbStation.SelectedItem is ComboBoxItem item)
{
int station = int.Parse(item.Content.ToString().Replace("工位", ""));
ShowStation(station);
await RefreshValveStates();
}
}
private async Task RefreshValveStates()
{
if (valveList.ItemsSource is not List<ValveInfo> valves) return;
foreach (var valve in valves)
{
try
{
bool state = await _plcService.ReadCoilAsync((ushort)valve.CoilAddress);
valve.IsOn = state;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"读取线圈{valve.CoilAddress}失败: {ex.Message}");
}
}
}
private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton btn && btn.DataContext is ValveInfo valve)
{
await WriteCoil(valve.CoilAddress, true);
}
}
private async void ToggleButton_Unchecked(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton btn && btn.DataContext is ValveInfo valve)
{
await WriteCoil(valve.CoilAddress, false);
}
}
private async Task WriteCoil(int coilAddress, bool value)
{
try
{
await _plcService.WriteCoilAsync((ushort)coilAddress, value);
await RefreshValveStates();
}
catch (Exception ex)
{
MessageBox.Show($"控制阀门失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private async void Refresh_Click(object sender, RoutedEventArgs e)
{
await RefreshValveStates();
}
protected override void OnClosed(EventArgs e)
{
_refreshTimer?.Stop();
base.OnClosed(e);
}
}
public class ValveInfo : INotifyPropertyChanged
{
public string Name { get; set; }
public int CoilAddress { get; set; }
private bool _isOn;
public bool IsOn
{
get => _isOn;
set
{
if (_isOn != value)
{
_isOn = value;
OnPropertyChanged(nameof(IsOn));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}