diff --git a/Converters/BooleanToVisibilityConverter.cs b/Converters/BooleanToVisibilityConverter.cs new file mode 100644 index 0000000..e32970a --- /dev/null +++ b/Converters/BooleanToVisibilityConverter.cs @@ -0,0 +1,20 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace MembranePoreTester.Converters +{ + public class BooleanToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return (value is bool b && b) ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return (value is Visibility v && v == Visibility.Visible); + } + } +} \ No newline at end of file diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs index 9495973..bbc2b4b 100644 --- a/ViewModels/MainViewModel.cs +++ b/ViewModels/MainViewModel.cs @@ -5,6 +5,7 @@ using System.Net; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using System.Windows.Threading; using static OfficeOpenXml.ExcelErrorValue; namespace MembranePoreTester.ViewModels @@ -12,6 +13,41 @@ namespace MembranePoreTester.ViewModels public class MainViewModel : ViewModelBase { public ObservableCollection Stations { get; } = new(); + + + + // 报警信息集合(用于显示多条) + private ObservableCollection _alarmMessages; + public ObservableCollection AlarmMessages + { + get => _alarmMessages; + set => SetProperty(ref _alarmMessages, value); + } + + private bool _hasAlarm; + public bool HasAlarm + { + get => _hasAlarm; + set => SetProperty(ref _hasAlarm, value); + } + + private string _alarmText; + public string AlarmText + { + get => _alarmText; + set => SetProperty(ref _alarmText, value); + } + + private DispatcherTimer _alarmTimer; + + + + + + + + + public class PressureModeItem { public string Text { get; set; } @@ -396,6 +432,52 @@ namespace MembranePoreTester.ViewModels }; Stations.Add(station); } + + + AlarmMessages = new ObservableCollection(); + + _alarmTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; + _alarmTimer.Tick += async (s, e) => await RefreshAlarms(); + _alarmTimer.Start(); + } + + + + private async Task RefreshAlarms() + { + try + { + var plc = App.PlcService; + var config = App.PlcConfig; + + // 读取4个报警线圈状态 + bool smallFlowAlarm = await plc.ReadCoilAsync(config.SmallFlowAlarm); + bool bigFlowAlarm = await plc.ReadCoilAsync(config.BigFlowAlarm); + bool highPressAlarm = await plc.ReadCoilAsync(config.HighPressAlarm); + bool lowPressAlarm = await plc.ReadCoilAsync(config.LowPressAlarm); + + // 收集当前报警信息 + var newAlarms = new List(); + if (smallFlowAlarm) newAlarms.Add("小流量计报警"); + if (bigFlowAlarm) newAlarms.Add("大流量报警"); + if (highPressAlarm) newAlarms.Add("高压超限"); + if (lowPressAlarm) newAlarms.Add("低压超限"); + + // 更新UI(避免频繁刷新集合导致界面闪烁,直接替换内容) + Application.Current.Dispatcher.Invoke(() => + { + AlarmMessages.Clear(); + foreach (var msg in newAlarms) + AlarmMessages.Add(msg); + + HasAlarm = newAlarms.Any(); + AlarmText = HasAlarm ? string.Join(";", newAlarms) : ""; + }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"读取报警状态失败: {ex.Message}"); + } } } } \ No newline at end of file diff --git a/Views/MainWindow.xaml b/Views/MainWindow.xaml index f8bfe68..6b8b924 100644 --- a/Views/MainWindow.xaml +++ b/Views/MainWindow.xaml @@ -92,7 +92,26 @@ - + + + + + + + + + + + + + + + + + + diff --git a/Views/ValveControlWindow.xaml b/Views/ValveControlWindow.xaml index bce15b2..41b13bb 100644 --- a/Views/ValveControlWindow.xaml +++ b/Views/ValveControlWindow.xaml @@ -121,7 +121,7 @@ - + diff --git a/分离膜孔径测试仪1.gxw b/分离膜孔径测试仪333单比例阀(1).gxw similarity index 81% rename from 分离膜孔径测试仪1.gxw rename to 分离膜孔径测试仪333单比例阀(1).gxw index 94e662b..20ef4bf 100644 Binary files a/分离膜孔径测试仪1.gxw and b/分离膜孔径测试仪333单比例阀(1).gxw differ