初始化

This commit is contained in:
GukSang.Jin
2026-03-10 17:35:25 +08:00
parent bfa418967f
commit 50917b2e38
3 changed files with 196 additions and 149 deletions

View File

@@ -41,85 +41,12 @@
</Border>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="12" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto">
<StackPanel>
<Border Style="{StaticResource CardBorderStyle}" Margin="0,0,0,12">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x68C0;&#x6D4B;&#x603B;&#x89C8;" />
<UniformGrid Columns="1">
<Border Margin="0,0,0,8" Padding="14" Background="#FFE7F5F3" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5408;&#x683C;&#x7387;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding ComplianceDisplay}" />
</StackPanel>
</Border>
<Border Margin="0,0,0,8" Padding="14" Background="#FFF6EFE2" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x538B;&#x5DEE;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding DeltaPressureDisplay}" />
</StackPanel>
</Border>
<Border Margin="0,0,0,8" Padding="14" Background="#FFE9EFF9" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5408;&#x683C;&#x9879;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding QualifiedCount}" />
</StackPanel>
</Border>
<Border Padding="14" Background="#FFFDEBE7" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x9884;&#x8B66;/&#x4E0D;&#x5408;&#x683C;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding WarningCount}" />
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
</Border>
<Border Style="{StaticResource CardBorderStyle}">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x6D41;&#x91CF;&#x5FEB;&#x7167;" />
<Border Margin="0,0,0,8" Padding="12" Background="#FFEAF6F3" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x4E3B;&#x6CF5;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding PumpFlowDisplay}" />
</StackPanel>
</Border>
<Border Margin="0,0,0,8" Padding="12" Background="#FFEFF1FA" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5F15;&#x6D41;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding DrainageFlowDisplay}" />
</StackPanel>
</Border>
<Border Padding="12" Background="#FFFDF0E5" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x56DE;&#x8F93;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding ReturnFlowDisplay}" />
</StackPanel>
</Border>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
<Border Grid.Column="2" Style="{StaticResource CardBorderStyle}" Margin="0">
<Border Style="{StaticResource CardBorderStyle}" Margin="0">
<TabControl>
<TabItem Header="&#x9879;&#x76EE;&#x68C0;&#x6D4B;">
<Grid Margin="0,6,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="280" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Style="{StaticResource CardBorderStyle}">
<ScrollViewer Margin="0,6,0,0" VerticalScrollBarVisibility="Auto" CanContentScroll="False">
<StackPanel>
<Border Style="{StaticResource CardBorderStyle}">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x9879;&#x76EE;&#x68C0;&#x7D22;&#x4E0E;&#x91C7;&#x96C6;&#x7B56;&#x7565;" />
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x6839;&#x636E; YY 0948-2025 &#x5C06;&#x9879;&#x76EE;&#x533A;&#x5206;&#x4E3A;&#x201C;&#x5B9E;&#x65F6;&#x76D1;&#x63A7;&#x201D;&#x201C;&#x5B9E;&#x65F6;&#x663E;&#x793A;+&#x624B;&#x52A8;&#x5F55;&#x5165;&#x201D;&#x548C;&#x201C;&#x624B;&#x52A8;&#x5F55;&#x5165;&#x201D;&#x4E09;&#x7C7B;&#x3002;" TextWrapping="Wrap" />
@@ -158,7 +85,7 @@
</StackPanel>
</Border>
<UniformGrid Grid.Row="1" Columns="3" Margin="0,0,0,12">
<UniformGrid Columns="3" Margin="0,0,0,12">
<Border Margin="0,0,8,8" Padding="14" Background="#FFE7F5F3" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5B9E;&#x65F6;&#x76D1;&#x63A7;" />
@@ -182,7 +109,7 @@
</Border>
</UniformGrid>
<Border Grid.Row="2" Style="{StaticResource CardBorderStyle}">
<Border Style="{StaticResource CardBorderStyle}">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x9879;&#x76EE;&#x6E05;&#x5355;" />
<DataGrid Margin="0,4,0,0"
@@ -194,6 +121,7 @@
CanUserDeleteRows="False"
SelectionMode="Single"
SelectionUnit="FullRow"
Height="280"
ScrollViewer.VerticalScrollBarVisibility="Auto"
VirtualizingPanel.ScrollUnit="Pixel">
<DataGrid.Columns>
@@ -224,7 +152,7 @@
</StackPanel>
</Border>
<UniformGrid Grid.Row="3" Columns="4" Margin="0,0,0,12">
<UniformGrid Columns="4" Margin="0,0,0,12">
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5F53;&#x524D;&#x9879;&#x76EE;" />
@@ -252,17 +180,10 @@
</Border>
</UniformGrid>
<Border Grid.Row="4" Style="{StaticResource CardBorderStyle}" Margin="0">
<DockPanel LastChildFill="True">
<WrapPanel DockPanel.Dock="Bottom" Margin="0,8,0,0">
<Button Command="{Binding SelectPreviousItemCommand}" Content="&#x4E0A;&#x4E00;&#x9879;" Background="#FF6B8791" />
<Button Command="{Binding SelectNextItemCommand}" Content="&#x4E0B;&#x4E00;&#x9879;" Background="#FF6B8791" />
<Button Command="{Binding ApplyResultCommand}" Content="&#x4FDD;&#x5B58;" />
</WrapPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x9879;&#x76EE;&#x8BE6;&#x60C5;&#x4E0E;&#x7ED3;&#x679C;&#x586B;&#x5199;" />
<Grid>
<Border Style="{StaticResource CardBorderStyle}" Margin="0">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x9879;&#x76EE;&#x8BE6;&#x60C5;&#x4E0E;&#x7ED3;&#x679C;&#x586B;&#x5199;" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.12*" />
<ColumnDefinition Width="16" />
@@ -415,41 +336,76 @@
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5907;&#x6CE8;" />
<TextBox Text="{Binding ResultNote, UpdateSourceTrigger=PropertyChanged}" MinHeight="104" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" IsReadOnly="{Binding SelectedItemUsesRealtimeValue}" />
</StackPanel>
</Grid>
</StackPanel>
</ScrollViewer>
</DockPanel>
</Grid>
<WrapPanel Margin="0,8,0,0">
<Button Command="{Binding SelectPreviousItemCommand}" Content="&#x4E0A;&#x4E00;&#x9879;" Background="#FF6B8791" />
<Button Command="{Binding SelectNextItemCommand}" Content="&#x4E0B;&#x4E00;&#x9879;" Background="#FF6B8791" />
<Button Command="{Binding ApplyResultCommand}" Content="&#x4FDD;&#x5B58;" />
</WrapPanel>
</StackPanel>
</Border>
</Grid>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem Header="&#x5B9E;&#x65F6;&#x6570;&#x636E;">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="0,6,0,0">
<UniformGrid Columns="4" Margin="0,0,0,12">
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x9636;&#x6BB5;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding CurrentStage}" TextWrapping="Wrap" /></StackPanel></Border>
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x8BBE;&#x5907;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding DeviceStatus}" TextWrapping="Wrap" /></StackPanel></Border>
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5F85;&#x68C0;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding PendingCount}" /></StackPanel></Border>
<Border Margin="0,0,0,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x544A;&#x8B66;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding AlarmMessages.Count}" /></StackPanel></Border>
</UniformGrid>
<UniformGrid Columns="2" Margin="0,0,0,12">
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x518D;&#x5FAA;&#x73AF;&#x7387;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding RealtimeRecirculationDisplay}" /></StackPanel></Border>
<Border Margin="0,0,0,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x4E3B;&#x6CF5;/&#x56DE;&#x8F93;&#x5DEE;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding FlowImbalanceDisplay}" /></StackPanel></Border>
</UniformGrid>
<UniformGrid Columns="4" Margin="0,0,0,12">
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x538B;&#x529B;&#x964D;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding DeltaPressureDisplay}" /></StackPanel></Border>
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x8D1F;&#x538B;&#x8F85;&#x52A9;&#x5F15;&#x6D41;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding NegativeAssistPressureDisplay}" /></StackPanel></Border>
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="fHb &#x8D8B;&#x52BF;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding FreeHemoglobinDisplay}" /></StackPanel></Border>
<Border Margin="0,0,0,8" Style="{StaticResource PanelSectionStyle}"><StackPanel><TextBlock Style="{StaticResource CaptionStyle}" Text="&#x767D;&#x7EC6;&#x80DE;&#x51CF;&#x5C11;&#x7387;" /><TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding WhiteCellLossDisplay}" /></StackPanel></Border>
</UniformGrid>
<Border Style="{StaticResource CardBorderStyle}">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x5B9E;&#x65F6;&#x603B;&#x89C8;" />
<WrapPanel Margin="0,0,0,4">
<Border Width="150" Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x9636;&#x6BB5;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding CurrentStage}" TextWrapping="Wrap" />
</StackPanel>
</Border>
<Border Width="150" Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x8BBE;&#x5907;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding DeviceStatus}" TextWrapping="Wrap" />
</StackPanel>
</Border>
<Border Width="150" Margin="0,0,8,8" Padding="14" Background="#FFE7F5F3" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5408;&#x683C;&#x7387;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding ComplianceDisplay}" />
</StackPanel>
</Border>
<Border Width="150" Margin="0,0,8,8" Padding="14" Background="#FFE9EFF9" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5408;&#x683C;&#x9879;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding QualifiedCount}" />
</StackPanel>
</Border>
<Border Width="150" Margin="0,0,8,8" Padding="14" Background="#FFFDEBE7" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x9884;&#x8B66;/&#x4E0D;&#x5408;&#x683C;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="24" Text="{Binding WarningCount}" />
</StackPanel>
</Border>
<Border Width="150" Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5F85;&#x68C0;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding PendingCount}" />
</StackPanel>
</Border>
<Border Width="150" Margin="0,0,0,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x544A;&#x8B66;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding AlarmMessages.Count}" />
</StackPanel>
</Border>
</WrapPanel>
</StackPanel>
</Border>
<Border Style="{StaticResource CardBorderStyle}">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x6D41;&#x91CF;&#x4F20;&#x611F;&#x5668;" />
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x6D41;&#x91CF;&#x5FEB;&#x7167;" />
<UniformGrid Columns="3" Margin="0,0,0,8">
<Border Margin="0,0,8,0" Style="{StaticResource PanelSectionStyle}">
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x4E3B;&#x6CF5;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding PumpFlowDisplay}" />
@@ -457,7 +413,7 @@
<ProgressBar Minimum="0" Maximum="1" Value="{Binding PumpFlowNormalizedValue, Mode=OneWay}" Height="10" Foreground="{StaticResource AccentBrush}" Background="#FFDDE7EC" />
</StackPanel>
</Border>
<Border Margin="0,0,8,0" Style="{StaticResource PanelSectionStyle}">
<Border Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5F15;&#x6D41;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding DrainageFlowDisplay}" />
@@ -465,7 +421,7 @@
<ProgressBar Minimum="0" Maximum="1" Value="{Binding DrainageFlowNormalizedValue, Mode=OneWay}" Height="10" Foreground="{StaticResource AccentBrush}" Background="#FFDDE7EC" />
</StackPanel>
</Border>
<Border Style="{StaticResource PanelSectionStyle}">
<Border Margin="0,0,0,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x56DE;&#x8F93;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding ReturnFlowDisplay}" />
@@ -474,33 +430,72 @@
</StackPanel>
</Border>
</UniformGrid>
<WrapPanel>
<Border Width="180" Margin="0,0,8,8" Padding="14" Background="#FFEAF6F3" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x518D;&#x5FAA;&#x73AF;&#x7387;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding RealtimeRecirculationDisplay}" />
</StackPanel>
</Border>
<Border Width="180" Margin="0,0,8,8" Padding="14" Background="#FFF6EFE2" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x538B;&#x529B;&#x964D;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding DeltaPressureDisplay}" />
</StackPanel>
</Border>
<Border Width="180" Margin="0,0,0,8" Padding="14" Background="#FFEFF1FA" CornerRadius="14">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x4E3B;&#x6CF5;/&#x56DE;&#x8F93;&#x5DEE;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding FlowImbalanceDisplay}" />
</StackPanel>
</Border>
</WrapPanel>
</StackPanel>
</Border>
<Border Style="{StaticResource CardBorderStyle}">
<StackPanel>
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x8F85;&#x52A9;&#x5B9E;&#x65F6;&#x6307;&#x6807;" />
<UniformGrid Columns="3">
<Border Margin="0,0,8,0" Style="{StaticResource PanelSectionStyle}">
<TextBlock Style="{StaticResource SectionTitleStyle}" Text="&#x538B;&#x529B;&#x4E0E;&#x8F85;&#x52A9;&#x6307;&#x6807;" />
<WrapPanel Margin="0,0,0,4">
<Border Width="180" Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5165;&#x53E3;/&#x51FA;&#x53E3;&#x538B;&#x529B;" />
<TextBlock FontSize="18" FontWeight="Bold" Text="{Binding SelectedItemLiveDisplay}" TextWrapping="Wrap" />
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x8FD1;&#x7AEF;&#x538B;&#x529B;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding Channels[4].DisplayValue}" />
</StackPanel>
</Border>
<Border Margin="0,0,8,0" Style="{StaticResource PanelSectionStyle}">
<Border Width="180" Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x8FDC;&#x7AEF;&#x538B;&#x529B;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding Channels[3].DisplayValue}" />
</StackPanel>
</Border>
<Border Width="180" Margin="0,0,8,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x8D1F;&#x538B;&#x8F85;&#x52A9;&#x5F15;&#x6D41;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding NegativeAssistPressureDisplay}" />
</StackPanel>
</Border>
<Border Width="180" Margin="0,0,0,8" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x6A21;&#x62DF;&#x8840;&#x6DB2;&#x6E29;&#x5EA6;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding TemperatureDisplay}" />
</StackPanel>
</Border>
<Border Style="{StaticResource PanelSectionStyle}">
</WrapPanel>
<WrapPanel>
<Border Width="220" Margin="0,0,8,0" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x5F53;&#x524D;&#x9009;&#x4E2D;&#x6761;&#x6B3E;&#x7B56;&#x7565;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="20" Text="{Binding SelectedItemCaptureModeText}" TextWrapping="Wrap" />
<TextBlock Margin="0,6,0,0" Style="{StaticResource CaptionStyle}" Text="{Binding SelectedItemMeasurementSource}" TextWrapping="Wrap" />
<TextBlock Style="{StaticResource CaptionStyle}" Text="fHb &#x8D8B;&#x52BF;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding FreeHemoglobinDisplay}" />
</StackPanel>
</Border>
</UniformGrid>
<Border Width="220" Margin="0,0,0,0" Style="{StaticResource PanelSectionStyle}">
<StackPanel>
<TextBlock Style="{StaticResource CaptionStyle}" Text="&#x767D;&#x7EC6;&#x80DE;&#x51CF;&#x5C11;&#x7387;" />
<TextBlock Style="{StaticResource MetricValueStyle}" FontSize="22" Text="{Binding WhiteCellLossDisplay}" />
</StackPanel>
</Border>
</WrapPanel>
</StackPanel>
</Border>
</StackPanel>

View File

@@ -1,4 +1,6 @@
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Cardiopulmonarybypasssystems.Models;
using NModbus;
@@ -11,6 +13,8 @@ public sealed class MockModbusTelemetryService : IModbusTelemetryService, IDispo
private const byte SlaveId = 1;
private const ushort ProximalPressureRegister = 1330;
private const ushort DistalPressureRegister = 1380;
private static readonly TimeSpan ConnectionAttemptTimeout = TimeSpan.FromMilliseconds(300);
private static readonly TimeSpan ConnectionRetryInterval = TimeSpan.FromSeconds(5);
private readonly object _syncRoot = new();
private readonly Random _random = new();
@@ -32,16 +36,18 @@ public sealed class MockModbusTelemetryService : IModbusTelemetryService, IDispo
private TcpClient? _tcpClient;
private IModbusMaster? _master;
private bool _connectionInitialized;
private Task? _connectionTask;
private DateTime _nextConnectionAttemptUtc = DateTime.MinValue;
public IReadOnlyList<DeviceChannel> GetChannels()
{
EnsureConnected();
EnsureConnectionScheduled();
return _channels;
}
public IReadOnlyList<AlarmMessage> UpdateChannels()
{
EnsureConnected();
EnsureConnectionScheduled();
lock (_syncRoot)
{
@@ -74,14 +80,19 @@ public sealed class MockModbusTelemetryService : IModbusTelemetryService, IDispo
{
lock (_syncRoot)
{
_master?.Dispose();
_tcpClient?.Dispose();
_master = null;
_tcpClient = null;
ReleaseConnection();
}
}
private void EnsureConnected()
private void ReleaseConnection()
{
_master?.Dispose();
_tcpClient?.Dispose();
_master = null;
_tcpClient = null;
}
private void EnsureConnectionScheduled()
{
lock (_syncRoot)
{
@@ -90,20 +101,50 @@ public sealed class MockModbusTelemetryService : IModbusTelemetryService, IDispo
return;
}
Dispose();
try
if (_connectionTask is { IsCompleted: false })
{
_tcpClient = new TcpClient();
_tcpClient.Connect(IpAddress, Port);
_master = _factory.CreateMaster(_tcpClient);
_connectionInitialized = true;
return;
}
catch
if (DateTime.UtcNow < _nextConnectionAttemptUtc)
{
_master = null;
_tcpClient?.Dispose();
_tcpClient = null;
return;
}
_nextConnectionAttemptUtc = DateTime.UtcNow.Add(ConnectionRetryInterval);
_connectionTask = Task.Run(ConnectWithTimeout);
}
}
private void ConnectWithTimeout()
{
TcpClient? tcpClient = null;
try
{
tcpClient = new TcpClient();
using var cancellation = new CancellationTokenSource(ConnectionAttemptTimeout);
tcpClient.ConnectAsync(IpAddress, Port, cancellation.Token).GetAwaiter().GetResult();
tcpClient.ReceiveTimeout = (int)ConnectionAttemptTimeout.TotalMilliseconds;
tcpClient.SendTimeout = (int)ConnectionAttemptTimeout.TotalMilliseconds;
var master = _factory.CreateMaster(tcpClient);
lock (_syncRoot)
{
ReleaseConnection();
_tcpClient = tcpClient;
_master = master;
_connectionInitialized = true;
tcpClient = null;
}
}
catch
{
tcpClient?.Dispose();
lock (_syncRoot)
{
ReleaseConnection();
}
}
}
@@ -126,7 +167,12 @@ public sealed class MockModbusTelemetryService : IModbusTelemetryService, IDispo
}
catch
{
Dispose();
lock (_syncRoot)
{
ReleaseConnection();
_nextConnectionAttemptUtc = DateTime.MinValue;
}
SimulatePressureChannels();
}
}

View File

@@ -191,6 +191,8 @@ public partial class MainViewModel : ObservableObject
public string PumpFlowDisplay => $"{PumpFlow:F2} L/min";
public string DrainageFlowDisplay => $"{DrainageFlow:F2} L/min";
public string ReturnFlowDisplay => $"{ReturnFlow:F2} L/min";
public string ProximalPressureDisplay => $"{ChannelValue("è¿ç«¯åŽåŠ"):F1} mmHg";
public string DistalPressureDisplay => $"{ChannelValue("远端åŽåŠ"):F1} mmHg";
public string FlowImbalanceDisplay => $"{Math.Abs(PumpFlow - ReturnFlow):F2} L/min";
public string PumpFlowLoadDisplay => $"{ChannelNormalizedValue(""):P0} 量程";
public string DrainageFlowLoadDisplay => $"{ChannelNormalizedValue(""):P0} 量程";
@@ -569,9 +571,11 @@ public partial class MainViewModel : ObservableObject
private void RefreshTelemetry()
{
var alarms = _telemetryService.UpdateChannels();
AlarmMessages.Clear();
foreach (var alarm in alarms.OrderByDescending(a => a.Timestamp))
{
AlarmMessages.Insert(0, alarm);
AlarmMessages.Add(alarm);
}
RefreshTelemetryPanel();
@@ -591,6 +595,8 @@ public partial class MainViewModel : ObservableObject
OnPropertyChanged(nameof(PumpFlowDisplay));
OnPropertyChanged(nameof(DrainageFlowDisplay));
OnPropertyChanged(nameof(ReturnFlowDisplay));
OnPropertyChanged(nameof(ProximalPressureDisplay));
OnPropertyChanged(nameof(DistalPressureDisplay));
OnPropertyChanged(nameof(RealtimeRecirculationDisplay));
OnPropertyChanged(nameof(FlowImbalanceDisplay));
OnPropertyChanged(nameof(NegativeAssistPressureDisplay));