Compare commits

6 Commits

Author SHA1 Message Date
xyy
e941113da9 2026-03-16 15:36:54 +08:00
xyy
533ca5a0fd 2026-03-16 11:17:49 +08:00
xyy
98d0111560 2026-03-14 19:21:11 +08:00
xyy
0bc8dce03e 2026-03-13 10:31:33 +08:00
xyy
b2848b4510 2026-03-11 15:31:20 +08:00
xyy
9b2d17d0ea 2026-03-11 15:24:40 +08:00
27 changed files with 937 additions and 982 deletions

View File

@@ -28,12 +28,6 @@ namespace 自救器呼吸器综合检验仪
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
if (AppShutdownCoordinator.ShouldSuppressDuringShutdown(e.Exception))
{
e.Handled = true;
return;
}
LogError(e.Exception, "UI线程异常");
e.Handled = true; // 标记为已处理,避免崩溃(仅用于调试)
}
@@ -55,11 +49,6 @@ namespace 自救器呼吸器综合检验仪
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "error.log");
string logContent = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {type}\n{ex.ToString()}\n\n";
File.AppendAllText(logPath, logContent);
if (AppShutdownCoordinator.IsShutdownInProgress)
{
return;
}
MessageBox.Show($"发生错误,详情已记录到 {logPath}", "错误");
}

View File

@@ -1,65 +0,0 @@
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
namespace
{
internal static class AppShutdownCoordinator
{
private static int _shutdownRequested;
public static bool IsShutdownInProgress
{
get
{
Application application = Application.Current;
if (application == null)
{
return Interlocked.CompareExchange(ref _shutdownRequested, 0, 0) == 1;
}
return Interlocked.CompareExchange(ref _shutdownRequested, 0, 0) == 1
|| application.Dispatcher.HasShutdownStarted
|| application.Dispatcher.HasShutdownFinished;
}
}
public static void RequestShutdown()
{
Application application = Application.Current;
if (application == null)
{
return;
}
if (Interlocked.Exchange(ref _shutdownRequested, 1) == 1)
{
return;
}
application.Dispatcher.BeginInvoke(
DispatcherPriority.ApplicationIdle,
new Action(() =>
{
if (application.Dispatcher.HasShutdownStarted || application.Dispatcher.HasShutdownFinished)
{
return;
}
application.Shutdown();
}));
}
public static bool ShouldSuppressDuringShutdown(Exception exception)
{
if (!IsShutdownInProgress || exception == null)
{
return false;
}
return exception is InvalidOperationException || exception is Win32Exception;
}
}
}

View File

@@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:自救器呼吸器综合检验仪.Data"
mc:Ignorable="d"
Title="BaseWindow" Height="600" Width="1024" WindowState="Maximized">
Title="BaseWindow" Height="450" Width="800">
<Grid>
</Grid>

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:自救器呼吸器综合检验仪"
Title="检验功能选择" Height="600" Width="1024" WindowState="Maximized"
Title="检验功能选择" Height="700" Width="1200"
WindowStartupLocation="CenterScreen"
FontFamily="Segoe UI"
Background="#F5F7FA">

View File

@@ -1,187 +0,0 @@
<Window x:Class="自救器呼吸器综合检验仪.LoadingOverlayWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None"
AllowsTransparency="True"
Background="#5C0F2238"
ShowInTaskbar="False"
ShowActivated="False"
ResizeMode="NoResize"
Topmost="False"
WindowStartupLocation="Manual">
<Window.Resources>
<Storyboard x:Key="CardIntroStoryboard">
<DoubleAnimation Storyboard.TargetName="LoadingCard"
Storyboard.TargetProperty="Opacity"
From="0"
To="1"
Duration="0:0:0.18" />
<DoubleAnimation Storyboard.TargetName="CardTranslate"
Storyboard.TargetProperty="Y"
From="18"
To="0"
Duration="0:0:0.18" />
</Storyboard>
<Storyboard x:Key="SpinnerStoryboard" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="SpinnerRotate"
Storyboard.TargetProperty="Angle"
From="0"
To="360"
Duration="0:0:0.95" />
<DoubleAnimation Storyboard.TargetName="SpinnerGlowScale"
Storyboard.TargetProperty="ScaleX"
From="0.88"
To="1.08"
Duration="0:0:0.65"
AutoReverse="True"
RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetName="SpinnerGlowScale"
Storyboard.TargetProperty="ScaleY"
From="0.88"
To="1.08"
Duration="0:0:0.65"
AutoReverse="True"
RepeatBehavior="Forever" />
</Storyboard>
<Storyboard x:Key="SubtitlePulseStoryboard" RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation Storyboard.TargetName="SubtitleText"
Storyboard.TargetProperty="Opacity"
From="0.62"
To="1"
Duration="0:0:0.8" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource CardIntroStoryboard}" />
<BeginStoryboard Storyboard="{StaticResource SpinnerStoryboard}" />
<BeginStoryboard Storyboard="{StaticResource SubtitlePulseStoryboard}" />
</EventTrigger>
</Window.Triggers>
<Grid IsHitTestVisible="False">
<Border x:Name="LoadingCard"
Width="390"
Padding="32"
HorizontalAlignment="Center"
VerticalAlignment="Center"
CornerRadius="18"
Background="#F7FAFD"
BorderBrush="#CFE0F1"
BorderThickness="1"
Opacity="0">
<Border.Effect>
<DropShadowEffect BlurRadius="28"
Opacity="0.24"
ShadowDepth="0"
Color="#0F2238" />
</Border.Effect>
<Border.RenderTransform>
<TranslateTransform x:Name="CardTranslate" Y="18" />
</Border.RenderTransform>
<StackPanel>
<Border HorizontalAlignment="Center"
Margin="0,0,0,14"
Padding="12,5"
CornerRadius="999"
Background="#E6F0FA">
<TextBlock Text="页面切换中"
FontSize="12"
FontWeight="SemiBold"
Foreground="#245E95" />
</Border>
<Grid Width="92"
Height="92"
Margin="0,0,0,20"
HorizontalAlignment="Center">
<Ellipse Width="92"
Height="92"
Fill="#EAF2FB" />
<Ellipse Width="72"
Height="72"
Fill="#F7FAFD">
<Ellipse.Effect>
<DropShadowEffect BlurRadius="16"
Opacity="0.12"
ShadowDepth="0"
Color="#2A7FD1" />
</Ellipse.Effect>
</Ellipse>
<Canvas Width="56"
Height="56"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<RotateTransform x:Name="SpinnerRotate" />
</Canvas.RenderTransform>
<Canvas.Effect>
<DropShadowEffect BlurRadius="10"
Opacity="0.26"
ShadowDepth="0"
Color="#2A7FD1" />
</Canvas.Effect>
<Canvas.LayoutTransform>
<ScaleTransform x:Name="SpinnerGlowScale" />
</Canvas.LayoutTransform>
<Ellipse Width="12" Height="12" Fill="#2A7FD1" Canvas.Left="22" Canvas.Top="0" />
<Ellipse Width="10" Height="10" Fill="#4F98DE" Canvas.Left="39" Canvas.Top="7" />
<Ellipse Width="8" Height="8" Fill="#76B0E8" Canvas.Left="48" Canvas.Top="23" />
<Ellipse Width="7" Height="7" Fill="#A8D1F4" Canvas.Left="43" Canvas.Top="40" />
<Ellipse Width="6" Height="6" Fill="#D3E8FA" Canvas.Left="25" Canvas.Top="49" />
<Ellipse Width="7" Height="7" Fill="#9BC9F0" Canvas.Left="9" Canvas.Top="42" />
<Ellipse Width="8" Height="8" Fill="#69A8E4" Canvas.Left="1" Canvas.Top="24" />
<Ellipse Width="10" Height="10" Fill="#3B8BD7" Canvas.Left="8" Canvas.Top="7" />
</Canvas>
</Grid>
<TextBlock x:Name="TitleText"
Text="正在切换检测页面"
FontSize="26"
FontWeight="Bold"
Foreground="#17324D"
HorizontalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBlock x:Name="SubtitleText"
Text="正在打开检测页面,请稍候..."
Margin="0,10,0,6"
FontSize="14"
Foreground="#4C637A"
HorizontalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBlock x:Name="HintText"
Text="系统正在加载界面资源并同步设备状态,请稍候..."
Margin="0,0,0,18"
FontSize="12"
Foreground="#6B7F93"
HorizontalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap" />
<Border Height="8"
CornerRadius="999"
Background="#DCE8F4">
<Grid Width="110"
HorizontalAlignment="Left">
<Rectangle RadiusX="999"
RadiusY="999"
Fill="#2A7FD1" />
<Rectangle Margin="12,0"
RadiusX="999"
RadiusY="999"
Fill="#72B1EA"
Opacity="0.68" />
</Grid>
</Border>
</StackPanel>
</Border>
</Grid>
</Window>

View File

@@ -1,133 +0,0 @@
using System;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Threading;
namespace
{
public partial class LoadingOverlayWindow : Window
{
private static readonly TimeSpan MinimumDisplayDuration = TimeSpan.FromMilliseconds(700);
private static readonly TimeSpan DismissAnimationDuration = TimeSpan.FromMilliseconds(240);
private readonly DateTime _shownAtUtc;
private bool _closeRequested;
public LoadingOverlayWindow()
{
InitializeComponent();
_shownAtUtc = DateTime.UtcNow;
}
public void AlignTo(Window referenceWindow)
{
if (referenceWindow == null)
{
return;
}
WindowState = WindowState.Normal;
double width = referenceWindow.ActualWidth > 0 ? referenceWindow.ActualWidth : referenceWindow.Width;
double height = referenceWindow.ActualHeight > 0 ? referenceWindow.ActualHeight : referenceWindow.Height;
if (width <= 0 || height <= 0)
{
Rect restoreBounds = referenceWindow.RestoreBounds;
width = restoreBounds.Width > 0 ? restoreBounds.Width : width;
height = restoreBounds.Height > 0 ? restoreBounds.Height : height;
}
Left = referenceWindow.Left;
Top = referenceWindow.Top;
Width = width;
Height = height;
}
public void MatchTopmost(Window referenceWindow)
{
if (referenceWindow == null)
{
return;
}
Topmost = referenceWindow.Topmost;
}
public void SetMessage(string title, string subtitle)
{
if (!string.IsNullOrWhiteSpace(title))
{
TitleText.Text = title;
}
if (!string.IsNullOrWhiteSpace(subtitle))
{
SubtitleText.Text = subtitle;
}
}
public void CloseWhenReady()
{
if (_closeRequested)
{
return;
}
_closeRequested = true;
TimeSpan remaining = MinimumDisplayDuration - (DateTime.UtcNow - _shownAtUtc);
if (remaining <= TimeSpan.Zero)
{
CloseOverlay();
return;
}
DispatcherTimer timer = new DispatcherTimer(
remaining,
DispatcherPriority.Background,
OnCloseTimerTick,
Dispatcher);
timer.Start();
}
private void OnCloseTimerTick(object sender, EventArgs e)
{
DispatcherTimer timer = sender as DispatcherTimer;
if (timer != null)
{
timer.Stop();
timer.Tick -= OnCloseTimerTick;
}
CloseOverlay();
}
private void CloseOverlay()
{
if (Dispatcher.HasShutdownStarted || Dispatcher.HasShutdownFinished || !IsLoaded)
{
return;
}
DoubleAnimation fadeOutAnimation = new DoubleAnimation
{
From = Opacity,
To = 0,
Duration = new Duration(DismissAnimationDuration),
FillBehavior = FillBehavior.Stop
};
fadeOutAnimation.Completed += (sender, args) =>
{
if (Dispatcher.HasShutdownStarted || Dispatcher.HasShutdownFinished || !IsLoaded)
{
return;
}
Close();
};
BeginAnimation(OpacityProperty, fadeOutAnimation);
}
}
}

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:自救器呼吸器综合检验仪"
Title="自救器呼吸器综合检验仪" Height="600" Width="1024" WindowState="Maximized"
Title="自救器呼吸器综合检验仪" Height="730" Width="1024"
WindowStartupLocation="CenterScreen"
Background="Transparent"
FontFamily="Microsoft YaHeui" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing">
@@ -61,6 +61,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 主标题 -->
@@ -70,13 +71,10 @@
<!--<TextBlock Text="定量供应检验系统"
FontSize="14" Foreground="#CCFFFFFF" Margin="0,5,0,0"/>-->
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="样品编号:" FontSize="26" FontWeight="Bold" Foreground="White" Style="{StaticResource LabelStyle}"/>
<StackPanel Orientation="Horizontal" Margin="2" HorizontalAlignment="Center">
<TextBlock Text="样品编号:" FontSize="26" FontWeight="Bold" Foreground="White" Margin="200 0 0 0" Style="{StaticResource LabelStyle}"/>
<TextBox x:Name="pressureDiff2" Text="" Width="180" Style="{StaticResource TextBoxStyle}" LostFocus="pressureDiff2_GotFocus"/>
<Border Background="White" Padding="15,8" Margin="15,0,0,0" VerticalAlignment="Center">
<TextBlock Text="{Binding CurrentTime, StringFormat='yyyy-MM-dd HH:mm:ss'}"
FontSize="12" FontWeight="Bold" Foreground="#2C3E50"/>
</Border>
</StackPanel>
<!-- 状态指示 -->
@@ -89,14 +87,20 @@
</Border>
</StackPanel>
<!-- 系统时间 -->
<Border Grid.Column="2" Background="White" Padding="15,8">
<TextBlock Text="{Binding CurrentTime, StringFormat='yyyy-MM-dd HH:mm:ss'}"
FontSize="12" FontWeight="Bold" Foreground="#2C3E50"/>
</Border>
</Grid>
</Border>
<!-- 主内容区域 -->
<Grid Grid.Row="1" Margin="0,0,0,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!-- 左侧:配置与监控区 -->
@@ -116,42 +120,30 @@
<!-- 检验时间配置 -->
<Grid Margin="0,0,0,15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="检验时间:" VerticalAlignment="Center"
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
<TextBlock Text="检验时间:" Width="84" VerticalAlignment="Center"
FontSize="14" FontWeight="SemiBold" Foreground="#2C3E50"/>
<TextBox Grid.Column="1" x:Name="settingtime" Text="0" Width="100" Height="35"
<TextBox x:Name="settingtime" Text="0" Width="66" Height="34"
VerticalContentAlignment="Center" TextAlignment="Center"
BorderBrush="#DCDFE6" BorderThickness="1" Background="#FAFBFC"
FontSize="14" TextChanged="settingtime_TextChanged"/>
<TextBlock Grid.Column="2" Text="秒" Margin="15,0,20,0" VerticalAlignment="Center"
<TextBlock Text="秒" Margin="15,0,40,0" VerticalAlignment="Center"
FontSize="14" Foreground="#7F8C8D"/>
<Button Content="🔧 设置参数" Click="BtnWrite401_Click"
Grid.Row="1" Grid.Column="0"
Background="#3498DB" Foreground="White" FontSize="13" FontWeight="Bold" Height="38" BorderThickness="0" Margin="0,12,53,0"
Cursor="Hand" Grid.ColumnSpan="2"/>
Background="#3498DB" Foreground="White" FontSize="13" FontWeight="Bold"
Width="100" Height="38" BorderThickness="0" Margin="-30,0,25,0"
Cursor="Hand"/>
<Button x:Name="btn_flow2" Content="定量供氧L/min" Click="BtnWrite400_Click"
Grid.Row="1" Grid.Column="1"
Background="#3498DB" Foreground="White" FontSize="13" FontWeight="Bold" Height="38" BorderThickness="0" Margin="91,12,8,0"
Cursor="Hand" Grid.ColumnSpan="3"/>
Background="#3498DB" Foreground="White" FontSize="13" FontWeight="Bold"
Width="100" Height="38" BorderThickness="0" Margin="-20,0,25,0"
Cursor="Hand"/>
<Button x:Name="btn_flow3" Content="自动/手动补给供氧(L/min)" Click="BtnWrite400_Click1"
Grid.Row="1" Grid.Column="4" Grid.ColumnSpan="2"
Background="#3498DB" Foreground="White" FontSize="12" FontWeight="Bold"
Height="38" BorderThickness="0" Padding="12,0" Margin="44,12,24,0" Cursor="Hand"/>
Background="#3498DB" Foreground="White" FontSize="13" FontWeight="Bold"
Width="157" Height="38" BorderThickness="0" Margin="-20,0,25,0"
Cursor="Hand"/>
@@ -160,7 +152,7 @@
FontSize="12" FontWeight="Bold" Foreground="#3498DB"/>-->
<!--</Border>-->
</Grid>
</StackPanel>
<!-- 试验时间显示 -->
<!--<StackPanel Orientation="Horizontal">
@@ -295,7 +287,7 @@
<Button Content="🔬 定量供应检验"
Background="#3498DB" Foreground="White" FontSize="12" FontWeight="Bold"
Width="140" Height="40" BorderThickness="0" Margin="8,5" Cursor="Hand"/>
Width="140" Height="40" BorderThickness="0" Margin="8,5" Cursor="Hand" Click="Button_Click_8"/>
<Button Content="📉 负压气密性检验" Click="Button_Click_5"
Background="White" Foreground="#2C3E50" FontSize="12" FontWeight="Bold"
@@ -314,5 +306,6 @@
</StackPanel>
</Border>
</Grid>
</Grid>
</Window>

View File

@@ -14,6 +14,7 @@ using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
@@ -37,10 +38,6 @@ namespace 自救器呼吸器综合检验仪
private bool _wasRunning = false; // 上次检验的运行状态
private bool _recordAdded = false; // 本轮测试是否已插入记录
private DateTime _testStartTime; // 测试开始时间
private Button _selectedParameterButton;
private static readonly Brush ParameterButtonDefaultBrush = CreateParameterButtonBrush("#3498DB");
private static readonly Brush ParameterButtonSelectedBrush = CreateParameterButtonBrush("#F39C12");
int retryCount = 0; // 连接失败重试次数
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
@@ -229,7 +226,6 @@ namespace 自救器呼吸器综合检验仪
{
_modbusMaster.WriteSingleCoil(1, 75, true);
isReset = true;
UpdateParameterButtonSelection(sender as Button);
}
@@ -241,39 +237,6 @@ namespace 自救器呼吸器综合检验仪
});
}
private static Brush CreateParameterButtonBrush(string colorCode)
{
return new SolidColorBrush((Color)ColorConverter.ConvertFromString(colorCode));
}
private void UpdateParameterButtonSelection(Button selectedButton)
{
if (selectedButton == null)
{
return;
}
if (_selectedParameterButton != null && !ReferenceEquals(_selectedParameterButton, selectedButton))
{
ApplyParameterButtonStyle(_selectedParameterButton, false);
}
_selectedParameterButton = selectedButton;
ApplyParameterButtonStyle(_selectedParameterButton, true);
}
private void ApplyParameterButtonStyle(Button button, bool isSelected)
{
if (button == null)
{
return;
}
button.Background = isSelected ? ParameterButtonSelectedBrush : ParameterButtonDefaultBrush;
button.BorderBrush = Brushes.Transparent;
button.BorderThickness = new Thickness(0);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 170);
@@ -299,27 +262,28 @@ namespace 自救器呼吸器综合检验仪
private void Button_Click_4(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow, () => new MainWindow(), "正在进入定量供应检验", "正在准备定量供应检验页面...");
SwitchWindow(ref _mainWindow, () => new MainWindow());
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow2, () => new MainWindow2(), "正在进入负压气密性检验", "正在切换到负压气密性检验页面...");
SwitchWindow(ref _mainWindow2, () => new MainWindow2());
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow3, () => new MainWindow3(), "正在进入正压气密性检验", "正在切换到正压气密性检验页面...");
SwitchWindow(ref _mainWindow3, () => new MainWindow3());
}
private void Button_Click_7(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow4, () => new MainWindow4(), "正在进入排气阀压力测试", "正在切换到排气阀压力测试页面...");
SwitchWindow(ref _mainWindow4, () => new MainWindow4());
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string plcIp = "192.168.1.10";
//string plcIp = "127.0.0.1";
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
if (!initSuccess)
{
@@ -357,6 +321,11 @@ namespace 自救器呼吸器综合检验仪
pressureDiff2.Text = ConfigurationManager.AppSettings["No"]?.ToString();
string imagePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources/sleep2.jpg");
ImageBrush brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri(imagePath, UriKind.Absolute));
this.Background = brush;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
@@ -373,12 +342,18 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
// 清理其他窗口实例
//_mainWindow?.Close();
_mainWindow2?.Close();
_mainWindow3?.Close();
_mainWindow4?.Close();
_mainWindow5?.Close();
_reportWindow?.Close();
}
private void BtnWrite401_Click(object sender, RoutedEventArgs e)
{
@@ -400,7 +375,6 @@ namespace 自救器呼吸器综合检验仪
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
UpdateParameterButtonSelection(sender as Button);
//await ReadAddr400DataAsync(); // 刷新显示(确认写入成功)
}
@@ -410,36 +384,108 @@ namespace 自救器呼吸器综合检验仪
}
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc, string loadingTitle = null, string loadingSubtitle = null) where T : Window, new()
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 1. 停止当前窗口的定时器(不释放资源)
// 停止当前窗口的定时器(不释放资源)
_readTimer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
// 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
// 创建一个简易的加载覆盖窗口,作为状态栏/遮罩,避免白屏
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this, () => _readTimer?.Start());
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
// 取消遮罩背景色,使用完全透明背景以避免暗色遮罩
Background = Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
// 4. 目标窗口完成首帧渲染后再切换,避免白屏
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance, loadingTitle, loadingSubtitle);
// 内容:底部居中的状态文本(不遮挡背景)
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = Brushes.Black,
Background = Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
// 显示遮罩
overlay.Show();
void ShowTargetWindow(T target)
{
// 如果目标已可见,直接激活并隐藏当前
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
// 创建或复用窗口实例
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
_readTimer?.Start();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
// 添加重连方法
@@ -590,7 +636,6 @@ namespace 自救器呼吸器综合检验仪
{
_modbusMaster.WriteSingleCoil(1, 75, false);
isReset = false;
UpdateParameterButtonSelection(sender as Button);
}
//private void pressureDiff2_GotFocus(object sender, RoutedEventArgs e)
@@ -654,6 +699,11 @@ namespace 自救器呼吸器综合检验仪
{
}
private void Button_Click_8(object sender, RoutedEventArgs e)
{
}
}

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:自救器呼吸器综合检验仪"
Title="自救器呼吸器综合检验仪" Height="600" Width="1024" WindowState="Maximized"
Title="自救器呼吸器综合检验仪" Height="730" Width="1024"
WindowStartupLocation="CenterScreen"
Background="Transparent"
FontFamily="Microsoft YaHeui" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing">

View File

@@ -17,6 +17,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using ;
using .Data;
@@ -419,22 +420,22 @@ namespace 自救器呼吸器综合检验仪
private void Button_Click_4(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow, () => new MainWindow(), "正在进入定量供应检验", "正在准备定量供应检验页面...");
SwitchWindow(ref _mainWindow, () => new MainWindow());
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow2, () => new MainWindow2(), "正在进入负压气密性检验", "正在切换到负压气密性检验页面...");
SwitchWindow(ref _mainWindow2, () => new MainWindow2());
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow3, () => new MainWindow3(), "正在进入正压气密性检验", "正在切换到正压气密性检验页面...");
SwitchWindow(ref _mainWindow3, () => new MainWindow3());
}
private void Button_Click_7(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow4, () => new MainWindow4(), "正在进入排气阀压力测试", "正在切换到排气阀压力测试页面...");
SwitchWindow(ref _mainWindow4, () => new MainWindow4());
}
@@ -476,36 +477,100 @@ namespace 自救器呼吸器综合检验仪
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc, string loadingTitle = null, string loadingSubtitle = null) where T : Window, new()
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 1. 停止当前窗口的定时器(不释放资源)
_readTimer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this, () => _readTimer?.Start());
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
// 4. 目标窗口完成首帧渲染后再切换,避免白屏
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance, loadingTitle, loadingSubtitle);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = Brushes.Black,
Background = Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
_readTimer?.Start();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
// 添加重连方法
private bool TryReconnect()
@@ -633,7 +698,7 @@ namespace 自救器呼吸器综合检验仪
}
string No = ConfigurationManager.AppSettings["No"]?.ToString();
// 添加记录到窗口(无论窗口是否显示)
_reportWindow2.AddRecord(currentTime, currentDate, startPress, endPress, diffPress, ProtectTime,No);
_reportWindow2.AddRecord(currentTime, currentDate, startPress, endPress, diffPress, ProtectTime, No);
});
}
@@ -658,12 +723,17 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
// 清理其他窗口实例
//_mainWindow2?.Close();
_mainWindow3?.Close();
_mainWindow4?.Close();
_mainWindow?.Close();
_reportWindow2?.Close();
}
//private void number_GotFocus(object sender, RoutedEventArgs e)

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:自救器呼吸器综合检验仪"
Title="自救器呼吸器综合检验仪" Height="600" Width="1024" WindowState="Maximized"
Title="自救器呼吸器综合检验仪" Height="730" Width="1024"
WindowStartupLocation="CenterScreen"
Background="Transparent"
FontFamily="Microsoft YaHeui"

View File

@@ -17,6 +17,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using ;
using .Data;
@@ -394,22 +395,22 @@ namespace 自救器呼吸器综合检验仪
private void Button_Click_4(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow, () => new MainWindow(), "正在进入定量供应检验", "正在准备定量供应检验页面...");
SwitchWindow(ref _mainWindow, () => new MainWindow());
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow2, () => new MainWindow2(), "正在进入负压气密性检验", "正在切换到负压气密性检验页面...");
SwitchWindow(ref _mainWindow2, () => new MainWindow2());
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow3, () => new MainWindow3(), "正在进入正压气密性检验", "正在切换到正压气密性检验页面...");
SwitchWindow(ref _mainWindow3, () => new MainWindow3());
}
private void Button_Click_7(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow4, () => new MainWindow4(), "正在进入排气阀压力测试", "正在切换到排气阀压力测试页面...");
SwitchWindow(ref _mainWindow4, () => new MainWindow4());
}
private void Window_Loaded(object sender, RoutedEventArgs e)
@@ -449,36 +450,100 @@ namespace 自救器呼吸器综合检验仪
System.Threading.Tasks.Task.Delay(50);
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc, string loadingTitle = null, string loadingSubtitle = null) where T : Window, new()
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 1. 停止当前窗口的定时器(不释放资源)
_readTimer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this, () => _readTimer?.Start());
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
// 4. 目标窗口完成首帧渲染后再切换,避免白屏
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance, loadingTitle, loadingSubtitle);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = Brushes.Black,
Background = Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
_readTimer?.Start();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
// 添加重连方法
private bool TryReconnect()
@@ -661,12 +726,17 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
// 清理其他窗口实例
_mainWindow?.Close();
_mainWindow2?.Close();
//_mainWindow3?.Close();
_mainWindow4?.Close();
_reportWindow3?.Close();
}
}
}

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:自救器呼吸器综合检验仪"
Title="自救器呼吸器综合检验仪" Height="600" Width="1024" WindowState="Maximized"
Title="自救器呼吸器综合检验仪" Height="730" Width="1024"
WindowStartupLocation="CenterScreen"
Background="Transparent"
FontFamily="Microsoft YaHeui"

View File

@@ -17,6 +17,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using ;
using .Data;
@@ -238,22 +239,22 @@ namespace 自救器呼吸器综合检验仪
private void Button_Click_4(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow, () => new MainWindow(), "正在进入定量供应检验", "正在准备定量供应检验页面...");
SwitchWindow(ref _mainWindow, () => new MainWindow());
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow2, () => new MainWindow2(), "正在进入负压气密性检验", "正在切换到负压气密性检验页面...");
SwitchWindow(ref _mainWindow2, () => new MainWindow2());
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow3, () => new MainWindow3(), "正在进入正压气密性检验", "正在切换到正压气密性检验页面...");
SwitchWindow(ref _mainWindow3, () => new MainWindow3());
}
private void Button_Click_7(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow4, () => new MainWindow4(), "正在进入排气阀压力测试", "正在切换到排气阀压力测试页面...");
SwitchWindow(ref _mainWindow4, () => new MainWindow4());
}
private void Window_Loaded(object sender, RoutedEventArgs e)
@@ -294,36 +295,100 @@ namespace 自救器呼吸器综合检验仪
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc, string loadingTitle = null, string loadingSubtitle = null) where T : Window, new()
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 1. 停止当前窗口的定时器(不释放资源)
_readTimer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this, () => _readTimer?.Start());
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
// 4. 目标窗口完成首帧渲染后再切换,避免白屏
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance, loadingTitle, loadingSubtitle);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = Brushes.Black,
Background = Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
_readTimer?.Start();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
private bool TryReconnect()
{
@@ -495,12 +560,17 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
// 清理其他窗口实例
_mainWindow2?.Close();
_mainWindow3?.Close();
//_mainWindow4?.Close();
_mainWindow?.Close();
_reportWindow4?.Close();
}
}
}

View File

@@ -1,7 +1,7 @@
<Window x:Class="自救器呼吸器综合检验仪.ParameterSettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="参数设置" Height="600" Width="800"
Title="参数设置" Height="730" Width="1024"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing">

View File

@@ -6,6 +6,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using .Data;
namespace
@@ -29,17 +30,6 @@ namespace 自救器呼吸器综合检验仪
_readTimer = InitDispatcherTimer();
}
private void EnsureWindowedLayout()
{
WindowState = WindowState.Normal;
Width = 1024;
Height = 600;
Rect workArea = SystemParameters.WorkArea;
Left = workArea.Left + (workArea.Width - Width) / 2;
Top = workArea.Top + (workArea.Height - Height) / 2;
}
private DispatcherTimer InitDispatcherTimer()
{
var timer = new DispatcherTimer
@@ -129,38 +119,100 @@ namespace 自救器呼吸器综合检验仪
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 1. 停止当前窗口的定时器(不释放资源)
// 停止当前窗口的定时器(不释放资源)
_readTimer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this, () => _readTimer?.Start());
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
else
{
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
return;
}
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = System.Windows.Media.Brushes.Black,
Background = System.Windows.Media.Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
_readTimer?.Start();
this.Show();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
@@ -457,8 +509,6 @@ _modbusMaster?.ReadHoldingRegisters(1, 290, 2)
private void Window_Loaded(object sender, RoutedEventArgs e)
{
EnsureWindowedLayout();
string plcIp = "192.168.1.10";
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
if (!initSuccess)
@@ -495,12 +545,18 @@ _modbusMaster?.ReadHoldingRegisters(1, 290, 2)
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
// 清理其他窗口实例
_mainWindow?.Close();
_mainWindow2?.Close();
_mainWindow3?.Close();
//_mainWindow4?.Close();
_mainWindow4?.Close();
}
// 重置为默认值
private void ResetToDefaults()

View File

@@ -1,7 +1,7 @@
<Window x:Class="自救器呼吸器综合检验仪.ReportWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="定量供氧检验报表" Height="600" Width="1024" WindowState="Maximized"
Title="定量供氧检验报表" Height="730" Width="1024"
WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing" >
<Grid>
<Grid.RowDefinitions>

View File

@@ -10,6 +10,7 @@ using System.Text;
using System.Windows;
using System.Windows.Controls;
using .Data;
using System.Windows.Media.Animation;
namespace
{
@@ -218,23 +219,26 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
//_mainWindow4?.Close();
_mainWindow?.Close();
}
private void BtnPrint_Click(object sender, RoutedEventArgs e)
{
// 判断是否有数据可打印
if (_records == null || _records.Count == 0)
{
MessageBox.Show("无数据,不可打印", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show("当前没有可打印的数据。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// 触发打印/硬件动作
ma.BtnClickFunctionForNew(Function.ButtonType., 15);
}
@@ -259,36 +263,96 @@ namespace 自救器呼吸器综合检验仪
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this);
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
else
{
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
return;
}
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = System.Windows.Media.Brushes.Black,
Background = System.Windows.Media.Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
this.Show();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
//ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
private void BtnClose_Click(object sender, RoutedEventArgs e)

View File

@@ -1,7 +1,7 @@
<Window x:Class="自救器呼吸器综合检验仪.ReportWindow2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="负压气密性检验报表" Height="600" Width="1024" WindowState="Maximized"
Title="负压气密性检验报表" Height="730" Width="1024"
WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing">
<Grid>
<Grid.RowDefinitions>

View File

@@ -10,6 +10,7 @@ using System.Text;
using System.Windows;
using System.Windows.Controls;
using .Data;
using System.Windows.Media.Animation;
namespace
{
@@ -232,12 +233,14 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
//_mainWindow4?.Close();
_reportWindow2?.Close();
}
//private void BtnClose_Click(object sender, RoutedEventArgs e)
@@ -248,13 +251,12 @@ namespace 自救器呼吸器综合检验仪
private void BtnPrint_Click(object sender, RoutedEventArgs e)
{
// 判断是否有数据可打印
if (_records == null || _records.Count == 0)
{
MessageBox.Show("无数据,不可打印", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show("当前没有可打印的数据。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
ma.BtnClickFunctionForNew(Function.ButtonType., 15);
}
@@ -279,36 +281,96 @@ namespace 自救器呼吸器综合检验仪
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this);
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
else
{
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
return;
}
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = System.Windows.Media.Brushes.Black,
Background = System.Windows.Media.Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
this.Show();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
//ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
private void BtnClose_Click(object sender, RoutedEventArgs e)

View File

@@ -1,7 +1,7 @@
<Window x:Class="自救器呼吸器综合检验仪.ReportWindow3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="正压气密性检验报表" Height="600" Width="1024" WindowState="Maximized"
Title="正压气密性检验报表" Height="730" Width="1024"
WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing">
<Grid>
<Grid.RowDefinitions>

View File

@@ -10,6 +10,8 @@ using System.Text;
using System.Windows;
using System.Windows.Controls;
using .Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace
{
@@ -191,13 +193,12 @@ namespace 自救器呼吸器综合检验仪
private void BtnPrint_Click(object sender, RoutedEventArgs e)
{
// 判断是否有数据可打印
if (_records == null || _records.Count == 0)
{
MessageBox.Show("无数据,不可打印", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show("当前没有可打印的数据。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
ma.BtnClickFunctionForNew(Function.ButtonType., 15);
}
@@ -237,12 +238,14 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
//_mainWindow4?.Close();
_reportWindow3?.Close();
}
//private void BtnClose_Click(object sender, RoutedEventArgs e)
@@ -277,36 +280,96 @@ namespace 自救器呼吸器综合检验仪
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this);
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
else
{
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
return;
}
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = System.Windows.Media.Brushes.Black,
Background = System.Windows.Media.Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
this.Show();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
//ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
private void BtnClose_Click(object sender, RoutedEventArgs e)

View File

@@ -1,7 +1,7 @@
<Window x:Class="自救器呼吸器综合检验仪.ReportWindow4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="排气阀检验报表" Height="600" Width="1024" WindowState="Maximized"
Title="排气阀检验报表" Height="730" Width="1024"
WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" Closed="Window_Closed" Closing="Window_Closing" >
<Grid>
<Grid.RowDefinitions>

View File

@@ -10,6 +10,8 @@ using System.Text;
using System.Windows;
using System.Windows.Controls;
using .Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace
{
@@ -233,13 +235,12 @@ namespace 自救器呼吸器综合检验仪
private void BtnPrint_Click(object sender, RoutedEventArgs e)
{
// 判断是否有数据可打印
if (_records == null || _records.Count == 0)
{
MessageBox.Show("无数据,不可打印", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show("当前没有可打印的数据。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
ma.BtnClickFunctionForNew(Function.ButtonType., 15);
}
@@ -278,12 +279,14 @@ namespace 自救器呼吸器综合检验仪
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
//_mainWindow4?.Close();
_reportWindow4?.Close();
}
//private void BtnClose_Click(object sender, RoutedEventArgs e)
@@ -318,36 +321,96 @@ namespace 自救器呼吸器综合检验仪
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
Window overlay = null;
try
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
overlay = new Window
{
WindowNavigationHelper.RestoreWindow(this);
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
}
else
{
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
return;
}
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = System.Windows.Media.Brushes.Black,
Background = System.Windows.Media.Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
this.Show();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
MessageBox.Show($"切换窗口失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void BtnClose_Click(object sender, RoutedEventArgs e)

View File

@@ -1,257 +0,0 @@
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
namespace
{
internal static class WindowNavigationHelper
{
private const string SlideTransformResourceKey = "__WindowNavigationHelperSlideTransform";
private static readonly TimeSpan TargetFadeDuration = TimeSpan.FromMilliseconds(420);
private static readonly TimeSpan ContentSlideDuration = TimeSpan.FromMilliseconds(360);
private static readonly CubicEase SlideEase = new CubicEase { EasingMode = EasingMode.EaseOut };
public static void ShowWithoutWhiteFlash(Window currentWindow, Window targetWindow, string loadingTitle = null, string loadingSubtitle = null)
{
if (!CanInteractWith(currentWindow) || !CanInteractWith(targetWindow))
{
return;
}
ApplyWindowPlacement(currentWindow, targetWindow);
PrepareTargetWindowForReveal(targetWindow);
if (targetWindow.IsVisible)
{
RevealTargetWindow(currentWindow, targetWindow, null);
return;
}
LoadingOverlayWindow loadingOverlay = ShowLoadingOverlay(currentWindow, loadingTitle, loadingSubtitle);
if (targetWindow.IsLoaded)
{
targetWindow.Show();
targetWindow.Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(() => RevealTargetWindow(currentWindow, targetWindow, loadingOverlay)));
return;
}
EventHandler contentRenderedHandler = null;
contentRenderedHandler = (sender, args) =>
{
targetWindow.ContentRendered -= contentRenderedHandler;
RevealTargetWindow(currentWindow, targetWindow, loadingOverlay);
};
targetWindow.ContentRendered += contentRenderedHandler;
targetWindow.Show();
}
public static void RestoreWindow(Window windowToRestore, Action beforeRestore = null)
{
if (!CanInteractWith(windowToRestore))
{
return;
}
beforeRestore?.Invoke();
if (!windowToRestore.IsVisible)
{
windowToRestore.Show();
}
windowToRestore.Activate();
}
private static void ApplyWindowPlacement(Window currentWindow, Window targetWindow)
{
targetWindow.WindowStartupLocation = WindowStartupLocation.Manual;
targetWindow.WindowState = currentWindow.WindowState;
if (currentWindow.WindowState != WindowState.Normal)
{
return;
}
targetWindow.Left = currentWindow.Left;
targetWindow.Top = currentWindow.Top;
targetWindow.Width = currentWindow.ActualWidth > 0 ? currentWindow.ActualWidth : currentWindow.Width;
targetWindow.Height = currentWindow.ActualHeight > 0 ? currentWindow.ActualHeight : currentWindow.Height;
}
private static void PrepareTargetWindowForReveal(Window targetWindow)
{
targetWindow.Opacity = 0;
FrameworkElement contentRoot = targetWindow.Content as FrameworkElement;
if (contentRoot == null)
{
return;
}
TranslateTransform slideTransform = GetOrCreateSlideTransform(contentRoot);
slideTransform.X = 72;
contentRoot.Opacity = 0.9;
}
private static void RevealTargetWindow(Window currentWindow, Window targetWindow, LoadingOverlayWindow loadingOverlay)
{
if (!CanInteractWith(currentWindow) || !CanInteractWith(targetWindow))
{
CloseLoadingOverlay(loadingOverlay);
return;
}
currentWindow.Hide();
AnimateTargetWindow(targetWindow);
targetWindow.Activate();
targetWindow.Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(() => CloseLoadingOverlay(loadingOverlay)));
}
private static LoadingOverlayWindow ShowLoadingOverlay(Window currentWindow, string loadingTitle, string loadingSubtitle)
{
if (!CanInteractWith(currentWindow))
{
return null;
}
LoadingOverlayWindow loadingOverlay = new LoadingOverlayWindow();
loadingOverlay.AlignTo(currentWindow);
loadingOverlay.MatchTopmost(currentWindow);
loadingOverlay.SetMessage(
loadingTitle ?? "正在切换检测页面",
loadingSubtitle ?? "正在加载页面资源和设备状态,请稍候...");
loadingOverlay.Show();
return loadingOverlay;
}
private static void CloseLoadingOverlay(LoadingOverlayWindow loadingOverlay)
{
if (loadingOverlay == null)
{
return;
}
if (loadingOverlay.Dispatcher.HasShutdownStarted || loadingOverlay.Dispatcher.HasShutdownFinished)
{
return;
}
if (!loadingOverlay.IsLoaded)
{
return;
}
loadingOverlay.CloseWhenReady();
}
private static void AnimateTargetWindow(Window targetWindow)
{
if (targetWindow == null || targetWindow.Dispatcher.HasShutdownStarted || targetWindow.Dispatcher.HasShutdownFinished)
{
return;
}
DoubleAnimation fadeInAnimation = new DoubleAnimation
{
From = targetWindow.Opacity,
To = 1,
Duration = new Duration(TargetFadeDuration),
FillBehavior = FillBehavior.HoldEnd
};
targetWindow.BeginAnimation(UIElement.OpacityProperty, fadeInAnimation);
FrameworkElement contentRoot = targetWindow.Content as FrameworkElement;
if (contentRoot == null)
{
return;
}
TranslateTransform slideTransform = GetOrCreateSlideTransform(contentRoot);
DoubleAnimation slideAnimation = new DoubleAnimation
{
From = slideTransform.X,
To = 0,
Duration = new Duration(ContentSlideDuration),
EasingFunction = SlideEase,
FillBehavior = FillBehavior.HoldEnd
};
slideTransform.BeginAnimation(TranslateTransform.XProperty, slideAnimation);
DoubleAnimation contentFadeAnimation = new DoubleAnimation
{
From = contentRoot.Opacity,
To = 1,
Duration = new Duration(ContentSlideDuration),
EasingFunction = SlideEase,
FillBehavior = FillBehavior.HoldEnd
};
contentRoot.BeginAnimation(UIElement.OpacityProperty, contentFadeAnimation);
}
private static TranslateTransform GetOrCreateSlideTransform(FrameworkElement contentRoot)
{
if (contentRoot.Resources[SlideTransformResourceKey] is TranslateTransform cachedTransform)
{
return cachedTransform;
}
TranslateTransform slideTransform = null;
Transform renderTransform = contentRoot.RenderTransform;
if (renderTransform is TranslateTransform existingTranslate)
{
slideTransform = existingTranslate;
}
else if (renderTransform is TransformGroup existingGroup)
{
foreach (Transform child in existingGroup.Children)
{
if (child is TranslateTransform childTranslate)
{
slideTransform = childTranslate;
break;
}
}
if (slideTransform == null)
{
slideTransform = new TranslateTransform();
existingGroup.Children.Add(slideTransform);
}
}
else if (renderTransform == null || renderTransform == Transform.Identity || renderTransform.Value.IsIdentity)
{
slideTransform = new TranslateTransform();
contentRoot.RenderTransform = slideTransform;
}
else
{
TransformGroup transformGroup = new TransformGroup();
transformGroup.Children.Add(renderTransform);
slideTransform = new TranslateTransform();
transformGroup.Children.Add(slideTransform);
contentRoot.RenderTransform = transformGroup;
}
contentRoot.RenderTransformOrigin = new Point(0.5, 0.5);
contentRoot.Resources[SlideTransformResourceKey] = slideTransform;
return slideTransform;
}
private static bool CanInteractWith(Window window)
{
return window != null
&& !AppShutdownCoordinator.IsShutdownInProgress
&& !window.Dispatcher.HasShutdownStarted
&& !window.Dispatcher.HasShutdownFinished;
}
}
}

56
oxygen_testsystem.sql Normal file
View File

@@ -0,0 +1,56 @@
-- --------------------------------------------------------
-- 主机: 127.0.0.1
-- 服务器版本: 10.3.2-MariaDB - mariadb.org binary distribution
-- 服务器操作系统: Win64
-- HeidiSQL 版本: 9.4.0.5125
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- 导出 oxygen_testsystem 的数据库结构
DROP DATABASE IF EXISTS `oxygen_testsystem`;
CREATE DATABASE IF NOT EXISTS `oxygen_testsystem` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `oxygen_testsystem`;
-- 导出 表 oxygen_testsystem.test_records 结构
DROP TABLE IF EXISTS `test_records`;
CREATE TABLE IF NOT EXISTS `test_records` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Time` varchar(10) NOT NULL,
`Date` varchar(10) NOT NULL,
`FlowRate` decimal(10,2) NOT NULL,
`Duration` varchar(10) NOT NULL,
`CreateTime` datetime NOT NULL,
`Type` int(11) NOT NULL,
`FlowRate2` decimal(10,2) unsigned zerofill DEFAULT NULL,
`No` varchar(50) NOT NULL,
PRIMARY KEY (`Id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=139 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- 数据导出被取消选择。
-- 导出 表 oxygen_testsystem.test_recordsfornegativepressure 结构
DROP TABLE IF EXISTS `test_recordsfornegativepressure`;
CREATE TABLE IF NOT EXISTS `test_recordsfornegativepressure` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Time` varchar(10) NOT NULL,
`Date` varchar(10) NOT NULL,
`StartPress` decimal(10,2) NOT NULL,
`Duration` varchar(10) DEFAULT NULL,
`CreateTime` datetime NOT NULL,
`EndPress` decimal(10,2) NOT NULL,
`DiffPress` decimal(10,2) NOT NULL,
`ProtectTime` decimal(10,2) NOT NULL,
`Type` int(11) NOT NULL,
`No` varchar(50) NOT NULL,
PRIMARY KEY (`Id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- 数据导出被取消选择。
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

View File

@@ -152,9 +152,6 @@
<Compile Include="DetectionMenuWindow.xaml.cs">
<DependentUpon>DetectionMenuWindow.xaml</DependentUpon>
</Compile>
<Compile Include="LoadingOverlayWindow.xaml.cs">
<DependentUpon>LoadingOverlayWindow.xaml</DependentUpon>
</Compile>
<Compile Include="ParameterSettingsWindow.xaml.cs">
<DependentUpon>ParameterSettingsWindow.xaml</DependentUpon>
</Compile>
@@ -182,9 +179,7 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="AppShutdownCoordinator.cs" />
<Compile Include="MainViewModel.cs" />
<Compile Include="WindowNavigationHelper.cs" />
<Compile Include="MainWindow2.xaml.cs">
<DependentUpon>MainWindow2.xaml</DependentUpon>
</Compile>
@@ -210,10 +205,6 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="LoadingOverlayWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow2.xaml">
<SubType>Designer</SubType>
<Generator>XamlIntelliSenseFileGenerator</Generator>