最新更新20260508
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<Window x:Class="Cardiopulmonarybypasssystems.EngineeringRegistersWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="工程寄存器"
|
||||
Title="泵/流量系数"
|
||||
Width="920"
|
||||
Height="640"
|
||||
MinWidth="860"
|
||||
@@ -29,19 +29,14 @@
|
||||
<TextBlock FontSize="20"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
Text="工程寄存器" />
|
||||
<TextBlock Margin="0,6,0,0"
|
||||
FontSize="12"
|
||||
Foreground="#EFFAFC"
|
||||
Text="长按左上角空白区可关闭窗口。这里只保留 8 泵默认配置和 8 路流量系数配置;流量系数以 PLC 当前寄存器值为准。"
|
||||
TextWrapping="Wrap" />
|
||||
Text="泵/流量系数" />
|
||||
</StackPanel>
|
||||
<StackPanel DockPanel.Dock="Right"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Center">
|
||||
<Button Padding="12,6"
|
||||
Command="{Binding RefreshEngineeringRegistersCommand}"
|
||||
Content="刷新寄存器"
|
||||
Content="刷新"
|
||||
Background="#FFFFFFFF"
|
||||
Foreground="{StaticResource HeaderBrush}" />
|
||||
</StackPanel>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,15 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
using Cardiopulmonarybypasssystems.Models;
|
||||
using Cardiopulmonarybypasssystems.ViewModels;
|
||||
|
||||
namespace Cardiopulmonarybypasssystems;
|
||||
@@ -13,11 +17,23 @@ namespace Cardiopulmonarybypasssystems;
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private EngineeringRegistersWindow? _engineeringRegistersWindow;
|
||||
private readonly List<Button> _navigationButtons = [];
|
||||
private readonly List<Button> _projectInspectionButtons = [];
|
||||
private object? _projectInspectionContent;
|
||||
private object? _realtimeContent;
|
||||
private object? _manualSupplementContent;
|
||||
private object? _configurationContent;
|
||||
private object? _traceContent;
|
||||
private NavigationPage _currentPage = NavigationPage.RealtimeData;
|
||||
private InspectionItem? _currentProjectItem;
|
||||
private bool _isPumpSetpointKeypadOpen;
|
||||
|
||||
public MainWindow(MainViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = viewModel;
|
||||
EmbedProjectDetailContent();
|
||||
ConfigureNavigation(viewModel);
|
||||
ConfigureTrendBindings();
|
||||
}
|
||||
|
||||
@@ -31,17 +47,525 @@ public partial class MainWindow : Window
|
||||
|
||||
Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
if (sender is DataGrid { SelectedItem: not null })
|
||||
if (sender is DataGrid { SelectedItem: InspectionItem inspectionItem })
|
||||
{
|
||||
ProjectDetailTab.IsSelected = true;
|
||||
NavigateToProjectItem(inspectionItem);
|
||||
}
|
||||
}, DispatcherPriority.Background);
|
||||
}
|
||||
|
||||
private void ReturnToProjectListButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ProjectListTab.IsSelected = true;
|
||||
InspectionItemsGrid.Focus();
|
||||
NavigateToFixedPage(NavigationPage.RealtimeData);
|
||||
}
|
||||
|
||||
private void EmbedProjectDetailContent()
|
||||
{
|
||||
if (ProjectDetailContentHost.Content is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ProjectDetailTab.Content is ScrollViewer detailScrollViewer)
|
||||
{
|
||||
var detailContent = detailScrollViewer.Content;
|
||||
detailScrollViewer.Content = null;
|
||||
ProjectDetailContentHost.Content = detailContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
ProjectDetailContentHost.Content = ProjectDetailTab.Content;
|
||||
}
|
||||
|
||||
ProjectDetailTab.Content = null;
|
||||
RootTabControl.Items.Remove(ProjectDetailTab);
|
||||
}
|
||||
|
||||
private void ConfigureNavigation(MainViewModel viewModel)
|
||||
{
|
||||
_realtimeContent = ExtractTabContent(RealtimeDataTab);
|
||||
_projectInspectionContent = ExtractTabContent(ProjectListTab);
|
||||
_manualSupplementContent = ExtractTabContent(ManualSupplementTab);
|
||||
_configurationContent = ExtractTabContent(ConfigurationTab);
|
||||
_traceContent = ExtractTabContent(TraceTab);
|
||||
|
||||
viewModel.PropertyChanged += ViewModel_OnPropertyChanged;
|
||||
|
||||
if (viewModel.FilteredItemsView is INotifyCollectionChanged filteredItems)
|
||||
{
|
||||
filteredItems.CollectionChanged += (_, _) => RebuildNavigationButtons();
|
||||
}
|
||||
|
||||
RebuildNavigationButtons();
|
||||
NavigateToFixedPage(NavigationPage.RealtimeData);
|
||||
}
|
||||
|
||||
private static object? ExtractTabContent(TabItem tab)
|
||||
{
|
||||
var content = tab.Content;
|
||||
tab.Content = null;
|
||||
return content;
|
||||
}
|
||||
|
||||
private void RebuildNavigationButtons()
|
||||
{
|
||||
if (DataContext is not MainViewModel viewModel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NavigationButtonPanel.Children.Clear();
|
||||
_navigationButtons.Clear();
|
||||
_projectInspectionButtons.Clear();
|
||||
|
||||
AddNavigationButton("实时数据", new NavigationTarget(NavigationPage.RealtimeData, null));
|
||||
|
||||
foreach (var item in viewModel.FilteredItemsView.Cast<InspectionItem>())
|
||||
{
|
||||
var button = AddNavigationButton(item.Item, new NavigationTarget(NavigationPage.ProjectItem, item));
|
||||
_projectInspectionButtons.Add(button);
|
||||
}
|
||||
|
||||
AddNavigationButton("项目补充", new NavigationTarget(NavigationPage.ManualSupplement, null));
|
||||
AddNavigationButton("配置", new NavigationTarget(NavigationPage.Configuration, null));
|
||||
AddNavigationButton("追溯", new NavigationTarget(NavigationPage.Trace, null));
|
||||
|
||||
if (_currentPage == NavigationPage.ProjectItem
|
||||
&& (_currentProjectItem is null || !_projectInspectionButtons.Any(button => ReferenceEquals(((NavigationTarget)button.Tag).ProjectItem, _currentProjectItem))))
|
||||
{
|
||||
NavigateToFixedPage(NavigationPage.RealtimeData);
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshNavigationButtonStates();
|
||||
}
|
||||
|
||||
private Button AddNavigationButton(string text, NavigationTarget target)
|
||||
{
|
||||
var button = new Button
|
||||
{
|
||||
Content = new TextBlock
|
||||
{
|
||||
MaxWidth = 132,
|
||||
Text = text,
|
||||
TextAlignment = TextAlignment.Center,
|
||||
TextWrapping = TextWrapping.Wrap
|
||||
},
|
||||
Tag = target,
|
||||
MinWidth = 92,
|
||||
MinHeight = 38,
|
||||
Padding = new Thickness(10, 6, 10, 6),
|
||||
Margin = new Thickness(0, 0, 6, 6),
|
||||
FontSize = 14
|
||||
};
|
||||
|
||||
button.Click += NavigationButton_OnClick;
|
||||
NavigationButtonPanel.Children.Add(button);
|
||||
_navigationButtons.Add(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
private void NavigationButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { Tag: NavigationTarget target })
|
||||
{
|
||||
Navigate(target);
|
||||
}
|
||||
}
|
||||
|
||||
private void Navigate(NavigationTarget target)
|
||||
{
|
||||
if (target.Page == NavigationPage.ProjectItem)
|
||||
{
|
||||
NavigateToProjectItem(target.ProjectItem);
|
||||
return;
|
||||
}
|
||||
|
||||
NavigateToFixedPage(target.Page);
|
||||
}
|
||||
|
||||
private void NavigateToFixedPage(NavigationPage page)
|
||||
{
|
||||
_currentPage = page;
|
||||
_currentProjectItem = null;
|
||||
MainContentHost.Content = page switch
|
||||
{
|
||||
NavigationPage.RealtimeData => _realtimeContent,
|
||||
NavigationPage.ManualSupplement => _manualSupplementContent,
|
||||
NavigationPage.Configuration => _configurationContent,
|
||||
NavigationPage.Trace => _traceContent,
|
||||
_ => _realtimeContent
|
||||
};
|
||||
|
||||
RefreshNavigationButtonStates();
|
||||
}
|
||||
|
||||
private void NavigateToProjectItem(InspectionItem? item)
|
||||
{
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataContext is MainViewModel viewModel && !ReferenceEquals(viewModel.SelectedItem, item))
|
||||
{
|
||||
viewModel.SelectedItem = item;
|
||||
}
|
||||
|
||||
_currentPage = NavigationPage.ProjectItem;
|
||||
_currentProjectItem = item;
|
||||
MainContentHost.Content = _projectInspectionContent;
|
||||
RefreshNavigationButtonStates();
|
||||
}
|
||||
|
||||
private void RefreshNavigationButtonStates()
|
||||
{
|
||||
foreach (var button in _navigationButtons)
|
||||
{
|
||||
if (button.Tag is not NavigationTarget target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var isSelected = target.Page == _currentPage
|
||||
&& (_currentPage != NavigationPage.ProjectItem || ReferenceEquals(target.ProjectItem, _currentProjectItem));
|
||||
|
||||
button.Background = isSelected ? BrushFromRgb(0xE3, 0xF6, 0xEF) : BrushFromRgb(0xE1, 0xE9, 0xEC);
|
||||
button.Foreground = isSelected ? BrushFromRgb(0x0E, 0x6C, 0x58) : BrushFromRgb(0x54, 0x65, 0x70);
|
||||
button.BorderBrush = isSelected ? BrushFromRgb(0x6E, 0xB2, 0xA9) : BrushFromRgb(0xC6, 0xD5, 0xDB);
|
||||
button.FontWeight = isSelected ? FontWeights.Bold : FontWeights.SemiBold;
|
||||
}
|
||||
}
|
||||
|
||||
private static SolidColorBrush BrushFromRgb(byte red, byte green, byte blue) => new(Color.FromRgb(red, green, blue));
|
||||
|
||||
private void ViewModel_OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(MainViewModel.SelectedItem) && sender is MainViewModel viewModel)
|
||||
{
|
||||
if (viewModel.SelectedItem is not null && _currentPage == NavigationPage.ProjectItem)
|
||||
{
|
||||
NavigateToProjectItem(viewModel.SelectedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum NavigationPage
|
||||
{
|
||||
RealtimeData,
|
||||
ProjectItem,
|
||||
ManualSupplement,
|
||||
Configuration,
|
||||
Trace
|
||||
}
|
||||
|
||||
private sealed record NavigationTarget(NavigationPage Page, InspectionItem? ProjectItem);
|
||||
|
||||
private void PumpSetpointTextBox_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if (sender is TextBox { DataContext: PumpControlChannel pump })
|
||||
{
|
||||
ShowPumpSetpointKeypad(pump);
|
||||
}
|
||||
}
|
||||
|
||||
private void PumpSetpointTextBox_OnGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox { DataContext: PumpControlChannel pump })
|
||||
{
|
||||
ShowPumpSetpointKeypad(pump);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowPumpSetpointKeypad(PumpControlChannel pump)
|
||||
{
|
||||
if (_isPumpSetpointKeypadOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isPumpSetpointKeypadOpen = true;
|
||||
|
||||
var valueBox = new TextBox
|
||||
{
|
||||
Text = string.IsNullOrWhiteSpace(pump.PendingSetpointText) ? "0" : pump.PendingSetpointText.Trim(),
|
||||
IsReadOnly = true,
|
||||
Height = 46,
|
||||
FontSize = 22,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
TextAlignment = TextAlignment.Right,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
Margin = new Thickness(0, 0, 0, 10),
|
||||
Padding = new Thickness(10, 0, 10, 0)
|
||||
};
|
||||
|
||||
var errorText = new TextBlock
|
||||
{
|
||||
Foreground = Brushes.Firebrick,
|
||||
FontSize = 12,
|
||||
MinHeight = 18,
|
||||
Margin = new Thickness(0, 0, 0, 8)
|
||||
};
|
||||
|
||||
var keypad = new UniformGrid
|
||||
{
|
||||
Columns = 3,
|
||||
Rows = 4,
|
||||
Margin = new Thickness(0, 0, 0, 12)
|
||||
};
|
||||
|
||||
foreach (var key in new[] { "7", "8", "9", "4", "5", "6", "1", "2", "3", ".", "0", "退格" })
|
||||
{
|
||||
keypad.Children.Add(CreateKeypadButton(key, (_, _) =>
|
||||
{
|
||||
errorText.Text = string.Empty;
|
||||
ApplyKeypadInput(valueBox, key);
|
||||
}));
|
||||
}
|
||||
|
||||
var actions = new Grid();
|
||||
actions.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
actions.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
actions.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
|
||||
var clearButton = CreateKeypadButton("清空", (_, _) =>
|
||||
{
|
||||
errorText.Text = string.Empty;
|
||||
valueBox.Text = string.Empty;
|
||||
});
|
||||
|
||||
var cancelButton = CreateKeypadButton("取消", (_, _) =>
|
||||
{
|
||||
if (Window.GetWindow(valueBox) is Window owner)
|
||||
{
|
||||
owner.DialogResult = false;
|
||||
}
|
||||
});
|
||||
|
||||
var okButton = CreateKeypadButton("确定", (_, _) =>
|
||||
{
|
||||
var normalizedValue = NormalizePumpSetpointText(valueBox.Text);
|
||||
|
||||
if (!double.TryParse(
|
||||
normalizedValue,
|
||||
NumberStyles.Float,
|
||||
CultureInfo.InvariantCulture,
|
||||
out var parsedValue)
|
||||
|| parsedValue < 0)
|
||||
{
|
||||
errorText.Text = "请输入有效流量";
|
||||
return;
|
||||
}
|
||||
|
||||
pump.PendingSetpointText = parsedValue.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
|
||||
if (DataContext is MainViewModel viewModel
|
||||
&& viewModel.WritePumpSetpointCommand.CanExecute(pump))
|
||||
{
|
||||
viewModel.WritePumpSetpointCommand.Execute(pump);
|
||||
}
|
||||
|
||||
if (Window.GetWindow(valueBox) is Window owner)
|
||||
{
|
||||
owner.DialogResult = true;
|
||||
}
|
||||
});
|
||||
|
||||
Grid.SetColumn(clearButton, 0);
|
||||
Grid.SetColumn(cancelButton, 1);
|
||||
Grid.SetColumn(okButton, 2);
|
||||
actions.Children.Add(clearButton);
|
||||
actions.Children.Add(cancelButton);
|
||||
actions.Children.Add(okButton);
|
||||
|
||||
var panel = new StackPanel
|
||||
{
|
||||
Margin = new Thickness(18)
|
||||
};
|
||||
panel.Children.Add(new TextBlock
|
||||
{
|
||||
Text = pump.Name,
|
||||
FontSize = 16,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = BrushFromRgb(0x1F, 0x3B, 0x46),
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Margin = new Thickness(0, 0, 0, 10)
|
||||
});
|
||||
panel.Children.Add(valueBox);
|
||||
panel.Children.Add(errorText);
|
||||
panel.Children.Add(keypad);
|
||||
panel.Children.Add(actions);
|
||||
|
||||
var dialog = new Window
|
||||
{
|
||||
Owner = this,
|
||||
Title = "输入目标流量",
|
||||
Width = 450,
|
||||
Height = 500,
|
||||
MinWidth = 280,
|
||||
MinHeight = 390,
|
||||
ResizeMode = ResizeMode.NoResize,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
||||
Content = panel
|
||||
};
|
||||
|
||||
dialog.Closed += (_, _) => _isPumpSetpointKeypadOpen = false;
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private static Button CreateKeypadButton(string text, RoutedEventHandler handler)
|
||||
{
|
||||
var button = new Button
|
||||
{
|
||||
Content = text,
|
||||
MinHeight = 46,
|
||||
Margin = new Thickness(4),
|
||||
FontSize = 16,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Background = BrushFromRgb(0xE3, 0xF6, 0xEF),
|
||||
Foreground = BrushFromRgb(0x1F, 0x3B, 0x46),
|
||||
BorderBrush = BrushFromRgb(0x9C, 0xCB, 0xBF)
|
||||
};
|
||||
|
||||
button.Click += handler;
|
||||
return button;
|
||||
}
|
||||
|
||||
private static void ApplyKeypadInput(TextBox valueBox, string key)
|
||||
{
|
||||
if (key == "退格")
|
||||
{
|
||||
valueBox.Text = valueBox.Text.Length > 0 ? valueBox.Text[..^1] : string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == "." && valueBox.Text.Contains('.', StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (valueBox.Text == "0" && key != ".")
|
||||
{
|
||||
valueBox.Text = key;
|
||||
return;
|
||||
}
|
||||
|
||||
valueBox.Text += key;
|
||||
}
|
||||
|
||||
private static string NormalizePumpSetpointText(string value)
|
||||
{
|
||||
var normalizedValue = value.Trim();
|
||||
|
||||
if (normalizedValue.StartsWith(".", StringComparison.Ordinal))
|
||||
{
|
||||
normalizedValue = "0" + normalizedValue;
|
||||
}
|
||||
|
||||
return normalizedValue;
|
||||
}
|
||||
|
||||
private void OpenProjectInfoDialogButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not MainViewModel viewModel || viewModel.SelectedItem is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var item = viewModel.SelectedItem;
|
||||
var panel = new StackPanel
|
||||
{
|
||||
Margin = new Thickness(18)
|
||||
};
|
||||
|
||||
AddDialogSection(panel, "类别", item.Category);
|
||||
AddDialogSection(panel, "判定要求", item.AcceptanceCriteria);
|
||||
AddDialogSection(panel, "检验方法", item.TestMethod);
|
||||
AddDialogSection(panel, "记录要点", item.RecordFocus);
|
||||
AddDialogSection(panel, "数据来源", viewModel.SelectedItemMeasurementSource);
|
||||
AddDialogSection(panel, "填写说明", viewModel.RealtimeMeasurementHint);
|
||||
AddDialogSection(panel, "实时数据预览", viewModel.SelectedItemLiveDisplay);
|
||||
AddDialogSection(panel, "实时数据说明", viewModel.SelectedItemLiveHint);
|
||||
|
||||
var scrollViewer = new ScrollViewer
|
||||
{
|
||||
Content = panel,
|
||||
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
|
||||
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled
|
||||
};
|
||||
|
||||
var closeButton = new Button
|
||||
{
|
||||
Content = "关闭",
|
||||
MinWidth = 88,
|
||||
MinHeight = 34,
|
||||
Padding = new Thickness(12, 5, 12, 5),
|
||||
Margin = new Thickness(0, 10, 18, 14),
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
Background = BrushFromRgb(0xE3, 0xF6, 0xEF),
|
||||
Foreground = BrushFromRgb(0x1F, 0x3B, 0x46),
|
||||
BorderBrush = BrushFromRgb(0x9C, 0xCB, 0xBF)
|
||||
};
|
||||
|
||||
var content = new Grid();
|
||||
content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
||||
content.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
|
||||
content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
||||
|
||||
var title = new TextBlock
|
||||
{
|
||||
Text = item.Item,
|
||||
Margin = new Thickness(18, 16, 18, 6),
|
||||
FontSize = 18,
|
||||
FontWeight = FontWeights.Bold,
|
||||
Foreground = BrushFromRgb(0x1F, 0x3B, 0x46),
|
||||
TextWrapping = TextWrapping.Wrap
|
||||
};
|
||||
|
||||
Grid.SetRow(title, 0);
|
||||
Grid.SetRow(scrollViewer, 1);
|
||||
Grid.SetRow(closeButton, 2);
|
||||
content.Children.Add(title);
|
||||
content.Children.Add(scrollViewer);
|
||||
content.Children.Add(closeButton);
|
||||
|
||||
var dialog = new Window
|
||||
{
|
||||
Owner = this,
|
||||
Title = "项目说明",
|
||||
Width = Math.Min(760, Math.Max(420, ActualWidth - 120)),
|
||||
Height = Math.Min(620, Math.Max(420, ActualHeight - 140)),
|
||||
MinWidth = 360,
|
||||
MinHeight = 320,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
||||
Content = content
|
||||
};
|
||||
|
||||
closeButton.Click += (_, _) => dialog.Close();
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private static void AddDialogSection(Panel panel, string title, string? value)
|
||||
{
|
||||
panel.Children.Add(new TextBlock
|
||||
{
|
||||
Text = title,
|
||||
FontSize = 13,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = BrushFromRgb(0x54, 0x65, 0x70),
|
||||
Margin = new Thickness(0, 0, 0, 4)
|
||||
});
|
||||
|
||||
panel.Children.Add(new TextBlock
|
||||
{
|
||||
Text = string.IsNullOrWhiteSpace(value) ? "-" : value.Trim(),
|
||||
FontSize = 14,
|
||||
Foreground = BrushFromRgb(0x1F, 0x3B, 0x46),
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Margin = new Thickness(0, 0, 0, 12)
|
||||
});
|
||||
}
|
||||
|
||||
private void OpenEngineeringRegistersButton_OnClick(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -22,6 +22,7 @@ public partial class ValveControlChannel : ObservableObject
|
||||
? $"停止{Name}"
|
||||
: $"启动{Name}";
|
||||
public string CirculatingWaterToggleText => IsOpen ? "停止循环水温" : "启动循环水温";
|
||||
public string ReservoirToggleText => IsOpen ? "关闭贮液" : "开启贮液";
|
||||
public string IndicatorColor => !StateAvailable ? "#FF94A6AE" : IsOpen ? "#FF32B06A" : "#FFC8D4DA";
|
||||
public string StateHint => !StateAvailable ? "未取得 PLC 状态" : $"{Name}已{StateText}";
|
||||
public bool HideRealtimeCardStateDescription => Key is "TestLoopValve1" or "TestLoopValve2" or "CirculatingWaterTemperature";
|
||||
@@ -32,6 +33,7 @@ public partial class ValveControlChannel : ObservableObject
|
||||
OnPropertyChanged(nameof(ActionText));
|
||||
OnPropertyChanged(nameof(ToggleButtonText));
|
||||
OnPropertyChanged(nameof(CirculatingWaterToggleText));
|
||||
OnPropertyChanged(nameof(ReservoirToggleText));
|
||||
OnPropertyChanged(nameof(IndicatorColor));
|
||||
OnPropertyChanged(nameof(StateHint));
|
||||
}
|
||||
@@ -41,6 +43,7 @@ public partial class ValveControlChannel : ObservableObject
|
||||
OnPropertyChanged(nameof(StateText));
|
||||
OnPropertyChanged(nameof(ToggleButtonText));
|
||||
OnPropertyChanged(nameof(CirculatingWaterToggleText));
|
||||
OnPropertyChanged(nameof(ReservoirToggleText));
|
||||
OnPropertyChanged(nameof(IndicatorColor));
|
||||
OnPropertyChanged(nameof(StateHint));
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public sealed class ModbusTelemetryService : IModbusTelemetryService, IDisposabl
|
||||
private readonly List<PumpControlChannel> _pumpControls =
|
||||
[
|
||||
new() { Key = "NegativeAssistPump", Name = "负压泵", StartAddress = 0 },
|
||||
new() { Key = "PressureDropPump", Name = "压力降/抗塌陷泵", StartAddress = 1, FlowAddress = FlowRegisters["PressureDropPump"] },
|
||||
new() { Key = "PressureDropPump", Name = "压力降泵", StartAddress = 1, FlowAddress = FlowRegisters["PressureDropPump"] },
|
||||
new() { Key = "RecirculationMainPump", Name = "再循环主泵", StartAddress = 2, FlowAddress = FlowRegisters["RecirculationMainPump"] },
|
||||
new() { Key = "RecirculationReturnPump", Name = "回流泵", StartAddress = 3, FlowAddress = FlowRegisters["RecirculationReturnPump"] },
|
||||
new() { Key = "RecirculationDrainagePump", Name = "引流泵", StartAddress = 4, FlowAddress = FlowRegisters["RecirculationDrainagePump"] },
|
||||
|
||||
Reference in New Issue
Block a user