添加项目文件。

This commit is contained in:
xyy
2026-02-12 17:03:23 +08:00
parent f7be80dc4d
commit 6ee66e47d6
13 changed files with 833 additions and 0 deletions

9
App.xaml Normal file
View File

@@ -0,0 +1,9 @@
<Application x:Class="PetroleumViscosityTest.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PetroleumViscosityTest"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

14
App.xaml.cs Normal file
View File

@@ -0,0 +1,14 @@
using System.Configuration;
using System.Data;
using System.Windows;
namespace PetroleumViscosityTest
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

10
AssemblyInfo.cs Normal file
View File

@@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

View File

@@ -0,0 +1,76 @@
<UserControl x:Class="PetroleumViscosityTest.Controls.TestRecordControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
FontFamily="SimSun" FontSize="11">
<Border BorderBrush="Black" BorderThickness="1" Padding="8">
<StackPanel>
<TextBlock Text="石油产品运动粘度测定原始记录" FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,15"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="试样编号:" Margin="2"/>
<TextBox x:Name="txtSampleID" Grid.Row="0" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="试样名称:" Margin="20,2,2,2"/>
<TextBox x:Name="txtSampleName" Grid.Row="0" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="试验温度(℃):" Margin="2"/>
<TextBox x:Name="txtTestTemp" Grid.Row="1" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="恒温时间(min):" Margin="20,2,2,2"/>
<TextBox x:Name="txtThermostatTime" Grid.Row="1" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="粘度计常数 C:" Margin="2"/>
<TextBox x:Name="txtConstant" Grid.Row="2" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="密度 ρ (g/cm³):" Margin="20,2,2,2"/>
<TextBox x:Name="txtDensity" Grid.Row="2" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="流动时间记录(s):" Margin="2" VerticalAlignment="Top"/>
<ListBox x:Name="lstTimes" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Height="80" IsHitTestVisible="False" BorderThickness="0"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="平均流动时间 τ:" Margin="2"/>
<TextBox x:Name="txtAvgTime" Grid.Row="4" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="4" Grid.Column="2" Text="运动粘度 ν (mm²/s):" Margin="20,2,2,2"/>
<TextBox x:Name="txtViscosity" Grid.Row="4" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent" FontWeight="Bold"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="动力粘度 η (mPa·s):" Margin="2"/>
<TextBox x:Name="txtDynamicViscosity" Grid.Row="5" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="5" Grid.Column="2" Text="有效测量次数:" Margin="20,2,2,2"/>
<TextBox x:Name="txtValidCount" Grid.Row="5" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
</Grid>
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="操作者:" Margin="2"/>
<TextBox x:Name="txtOperator" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Column="2" Text="试验日期:" Margin="20,2,2,2"/>
<TextBox x:Name="txtTestDate" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
</Grid>
<Grid Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="备注:" Margin="2"/>
<TextBox x:Name="txtRemark" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent" TextWrapping="Wrap"/>
</Grid>
</StackPanel>
</Border>
</UserControl>

View File

@@ -0,0 +1,36 @@
using System;
using System.Linq;
using System.Windows.Controls;
using PetroleumViscosityTest.Models;
namespace PetroleumViscosityTest.Controls
{
public partial class TestRecordControl : UserControl
{
public TestRecordControl()
{
InitializeComponent();
}
public void LoadData(ViscosityTestData data)
{
txtSampleID.Text = data.SampleID;
txtSampleName.Text = data.SampleName;
txtTestTemp.Text = data.TestTemp.ToString("F1");
txtThermostatTime.Text = Constants.GetThermostatTime(data.TestTemp).ToString();
txtConstant.Text = data.Constant.ToString("G5");
txtDensity.Text = data.Density.HasValue ? data.Density.Value.ToString("F3") : "—";
txtAvgTime.Text = data.AvgTime.ToString("F3");
txtViscosity.Text = data.Viscosity.ToString("G4");
txtDynamicViscosity.Text = data.DynamicViscosity > 0 ? data.DynamicViscosity.ToString("G4") : "—";
txtValidCount.Text = $"{data.ValidTimes.Count} / {data.RawTimes.Count}";
txtOperator.Text = data.Operator;
txtTestDate.Text = data.TestDate.ToString("yyyy-MM-dd");
txtRemark.Text = data.Remark;
// 显示所有流动时间
var timeItems = data.RawTimes.Select((t, i) => new { Display = $"第{i + 1}次: {t:F3}s" }).ToList();
lstTimes.ItemsSource = timeItems;
}
}
}

View File

@@ -0,0 +1,50 @@
<UserControl x:Class="PetroleumViscosityTest.Controls.TestReportControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
FontFamily="SimSun" FontSize="11">
<Border BorderBrush="Black" BorderThickness="1" Padding="10">
<StackPanel>
<TextBlock Text="石油产品运动粘度测试报告" FontSize="16" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,15"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="报告编号:" Margin="2"/>
<TextBox x:Name="txtReportNo" Grid.Row="0" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="测试日期:" Margin="20,2,2,2"/>
<TextBox x:Name="txtTestDate" Grid.Row="0" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="试样编号:" Margin="2"/>
<TextBox x:Name="txtSampleID" Grid.Row="1" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="试样名称:" Margin="20,2,2,2"/>
<TextBox x:Name="txtSampleName" Grid.Row="1" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="试验温度(℃):" Margin="2"/>
<TextBox x:Name="txtTestTemp" Grid.Row="2" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="粘度计常数:" Margin="20,2,2,2"/>
<TextBox x:Name="txtConstant" Grid.Row="2" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="运动粘度 ν (mm²/s):" Margin="2" FontWeight="Bold"/>
<TextBox x:Name="txtViscosity" Grid.Row="3" Grid.Column="1" IsReadOnly="True" BorderThickness="0" Background="Transparent" FontWeight="Bold"/>
<TextBlock Grid.Row="3" Grid.Column="2" Text="动力粘度 η (mPa·s):" Margin="20,2,2,2"/>
<TextBox x:Name="txtDynamicViscosity" Grid.Row="3" Grid.Column="3" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="精密度判定:" Margin="2"/>
<TextBox x:Name="txtPrecision" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" IsReadOnly="True" BorderThickness="0" Background="Transparent" Foreground="Red"/>
</Grid>
<TextBlock Text="以下空白" HorizontalAlignment="Center" Margin="0,20,0,0"/>
<TextBlock Text="本报告仅对本次测试样品负责" HorizontalAlignment="Center" FontSize="10"/>
</StackPanel>
</Border>
</UserControl>

View File

@@ -0,0 +1,27 @@
using System;
using System.Windows.Controls;
using PetroleumViscosityTest.Models;
namespace PetroleumViscosityTest.Controls
{
public partial class TestReportControl : UserControl
{
public TestReportControl()
{
InitializeComponent();
txtReportNo.Text = "R" + DateTime.Now.ToString("yyyyMMddHHmmss");
}
public void LoadData(ViscosityTestData data)
{
txtTestDate.Text = data.TestDate.ToString("yyyy-MM-dd");
txtSampleID.Text = data.SampleID;
txtSampleName.Text = data.SampleName;
txtTestTemp.Text = data.TestTemp.ToString("F1");
txtConstant.Text = data.Constant.ToString("G5");
txtViscosity.Text = data.Viscosity.ToString("G4");
txtDynamicViscosity.Text = data.DynamicViscosity > 0 ? data.DynamicViscosity.ToString("G4") : "—";
txtPrecision.Text = data.IsRepeatabilityOK ? "符合重复性要求" : "重复性超差,数据仅供参考";
}
}
}

203
MainWindow.xaml Normal file
View File

@@ -0,0 +1,203 @@
<Window x:Class="PetroleumViscosityTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="石油产品运动粘度测试系统 (GB/T 265-1988)"
Width="1024" Height="768"
WindowStartupLocation="CenterScreen"
FontSize="13">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ========== 顶部:试样信息、粘度计常数、恒温条件 ========= -->
<Border Grid.Row="0" BorderBrush="DarkGray" BorderThickness="1" Padding="5" CornerRadius="3" Margin="0,0,0,5">
<StackPanel>
<!-- 第一行:试样信息 -->
<WrapPanel Margin="0,0,0,3">
<TextBlock Text="试样编号:" VerticalAlignment="Center"/>
<TextBox x:Name="txtSampleID" Width="120" Margin="5,0,10,0"/>
<TextBlock Text="试样名称:" VerticalAlignment="Center"/>
<TextBox x:Name="txtSampleName" Width="150" Margin="5,0,10,0"/>
<TextBlock Text="试验温度(℃)" VerticalAlignment="Center"/>
<TextBox x:Name="txtTestTemp" Width="60" Margin="5,0,10,0" TextChanged="TxtTestTemp_TextChanged"/>
<TextBlock Text="恒温时间(min)" VerticalAlignment="Center"/>
<TextBox x:Name="txtThermostatTime" Width="50" IsReadOnly="True" Background="LightGray" Margin="5,0,0,0"/>
</WrapPanel>
<!-- 第二行:粘度计常数、密度、操作者 -->
<WrapPanel Margin="0,3,0,3">
<TextBlock Text="粘度计常数 C (mm²/s²)" VerticalAlignment="Center"/>
<TextBox x:Name="txtConstant" Width="100" Margin="5,0,10,0"/>
<TextBlock Text="密度 ρ (g/cm³)" VerticalAlignment="Center"/>
<TextBox x:Name="txtDensity" Width="80" Margin="5,0,10,0"/>
<TextBlock Text="操作者:" VerticalAlignment="Center"/>
<TextBox x:Name="txtOperator" Width="100" Margin="5,0,10,0"/>
<TextBlock Text="试验日期:" VerticalAlignment="Center"/>
<DatePicker x:Name="dpTestDate" Width="120" Margin="5,0,0,0"/>
</WrapPanel>
<!-- 第三行:备注、控制按钮 -->
<WrapPanel Margin="0,3,0,0">
<TextBlock Text="备注:" VerticalAlignment="Center"/>
<TextBox x:Name="txtRemark" Width="300" Margin="5,0,10,0"/>
<Button x:Name="btnClearAll" Content="清空所有" Width="80" Margin="5,0" Click="BtnClearAll_Click"/>
<Button x:Name="btnLoadExample" Content="加载示例" Width="80" Margin="5,0" Click="BtnLoadExample_Click"/>
</WrapPanel>
</StackPanel>
</Border>
<!-- ========== 中间:流动时间测量及计算 ========= -->
<TabControl Grid.Row="1" Margin="0,5,0,5">
<!-- 流动时间录入 -->
<TabItem Header="流动时间测量">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="5">
<GroupBox Header="流动时间记录 (秒)" Padding="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 第一行4个时间输入框 -->
<StackPanel Grid.Row="0" Grid.Column="0" Margin="5">
<TextBlock Text="第1次" FontWeight="Bold"/>
<TextBox x:Name="txtTime1" Width="80" Margin="0,2"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" Margin="5">
<TextBlock Text="第2次" FontWeight="Bold"/>
<TextBox x:Name="txtTime2" Width="80" Margin="0,2"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="2" Margin="5">
<TextBlock Text="第3次" FontWeight="Bold"/>
<TextBox x:Name="txtTime3" Width="80" Margin="0,2"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="3" Margin="5">
<TextBlock Text="第4次" FontWeight="Bold"/>
<TextBox x:Name="txtTime4" Width="80" Margin="0,2"/>
</StackPanel>
<!-- 第二行更多时间输入支持最多6次 -->
<StackPanel Grid.Row="1" Grid.Column="0" Margin="5">
<TextBlock Text="第5次 (可选)"/>
<TextBox x:Name="txtTime5" Width="80" Margin="0,2"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="5">
<TextBlock Text="第6次 (可选)"/>
<TextBox x:Name="txtTime6" Width="80" Margin="0,2"/>
</StackPanel>
</Grid>
</GroupBox>
<WrapPanel Margin="0,10,0,10" HorizontalAlignment="Center">
<Button x:Name="btnCalcViscosity" Content="计算运动粘度" Width="150" Height="30" Margin="5" Click="BtnCalcViscosity_Click"/>
<Button x:Name="btnAddMeasurement" Content="增加一次测量" Width="120" Margin="5" Click="BtnAddMeasurement_Click"/>
<Button x:Name="btnClearTimes" Content="清空时间" Width="100" Margin="5" Click="BtnClearTimes_Click"/>
</WrapPanel>
<!-- 计算结果展示 -->
<GroupBox Header="计算结果" Padding="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="平均流动时间 τ (s)" Margin="5"/>
<TextBox x:Name="txtAvgTime" Grid.Row="0" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="运动粘度 ν (mm²/s)" Margin="5"/>
<TextBox x:Name="txtViscosity" Grid.Row="1" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5" FontWeight="Bold"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="动力粘度 η (mPa·s)" Margin="5"/>
<TextBox x:Name="txtDynamicViscosity" Grid.Row="2" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="有效测量次数:" Margin="5"/>
<TextBox x:Name="txtValidCount" Grid.Row="3" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="精密度判定:" Margin="5"/>
<TextBox x:Name="txtPrecisionJudge" Grid.Row="4" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5" Foreground="Red"/>
</Grid>
</GroupBox>
<!-- 流动时间原始数据显示 -->
<GroupBox Header="流动时间原始记录" Margin="0,10,0,0">
<ListBox x:Name="lstRawTimes" Height="80" DisplayMemberPath="Display"/>
</GroupBox>
</StackPanel>
</ScrollViewer>
</TabItem>
<!-- 精密度及报告 -->
<TabItem Header="精密度与报告">
<StackPanel Margin="5">
<GroupBox Header="精密度要求 (GB/T 265-1988)" Padding="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="重复性 (同一操作者)" Margin="5"/>
<TextBox x:Name="txtRepeatability" Grid.Row="0" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="再现性 (不同实验室)" Margin="5"/>
<TextBox x:Name="txtReproducibility" Grid.Row="1" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="本次测量重复性 (%)" Margin="5"/>
<TextBox x:Name="txtMeasuredRepeatability" Grid.Row="2" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="重复性判定:" Margin="5"/>
<TextBox x:Name="txtRepeatJudge" Grid.Row="3" Grid.Column="1" IsReadOnly="True" Background="LightGray" Margin="5" Foreground="Red"/>
</Grid>
</GroupBox>
<WrapPanel Margin="0,10" HorizontalAlignment="Center">
<Button x:Name="btnGenRecord" Content="生成原始记录 (附录样式)" Width="180" Margin="5" Padding="5" Click="BtnGenRecord_Click"/>
<Button x:Name="btnGenReport" Content="生成测试报告" Width="150" Margin="5" Padding="5" Click="BtnGenReport_Click"/>
<Button x:Name="btnPrintPreview" Content="打印预览" Width="100" Margin="5" Padding="5" Click="BtnPrintPreview_Click"/>
</WrapPanel>
<Border BorderBrush="LightBlue" BorderThickness="1" Height="220" CornerRadius="2" Background="WhiteSmoke">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<ContentControl x:Name="ReportContent" Margin="5"/>
</ScrollViewer>
</Border>
</StackPanel>
</TabItem>
</TabControl>
<!-- ========== 底部:状态栏 ========= -->
<StatusBar Grid.Row="2" Background="LightGray">
<StatusBarItem>
<TextBlock x:Name="txtStatus" Text="就绪"/>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>

314
MainWindow.xaml.cs Normal file
View File

@@ -0,0 +1,314 @@
using Microsoft.VisualBasic;
using PetroleumViscosityTest.Controls;
using PetroleumViscosityTest.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace PetroleumViscosityTest
{
public partial class MainWindow : Window
{
private ViscosityTestData currentData;
private List<double> rawTimes = new List<double>();
public MainWindow()
{
InitializeComponent();
currentData = new ViscosityTestData();
dpTestDate.SelectedDate = DateTime.Today;
UpdateThermostatTime();
}
// 温度变化时自动更新恒温时间表2
private void TxtTestTemp_TextChanged(object sender, TextChangedEventArgs e)
{
UpdateThermostatTime();
}
private void UpdateThermostatTime()
{
if (double.TryParse(txtTestTemp.Text, out double temp))
{
int time = Models.Constants.GetThermostatTime(temp);
txtThermostatTime.Text = time.ToString();
}
else
{
txtThermostatTime.Text = "";
}
}
// 加载示例数据
private void BtnLoadExample_Click(object sender, RoutedEventArgs e)
{
txtSampleID.Text = "S2026-001";
txtSampleName.Text = "润滑油";
txtTestTemp.Text = "50";
txtConstant.Text = "0.4780";
txtDensity.Text = "0.85";
txtOperator.Text = "张三";
txtRemark.Text = "示例数据";
txtTime1.Text = "322.4";
txtTime2.Text = "322.6";
txtTime3.Text = "321.0";
txtTime4.Text = "";
txtTime5.Text = "";
txtTime6.Text = "";
UpdateThermostatTime();
txtStatus.Text = "示例数据已加载";
}
// 清空所有输入
private void BtnClearAll_Click(object sender, RoutedEventArgs e)
{
txtSampleID.Clear();
txtSampleName.Clear();
txtTestTemp.Clear();
txtConstant.Clear();
txtDensity.Clear();
txtOperator.Clear();
txtRemark.Clear();
txtTime1.Clear();
txtTime2.Clear();
txtTime3.Clear();
txtTime4.Clear();
txtTime5.Clear();
txtTime6.Clear();
txtAvgTime.Clear();
txtViscosity.Clear();
txtDynamicViscosity.Clear();
txtValidCount.Clear();
txtPrecisionJudge.Clear();
txtRepeatability.Clear();
txtReproducibility.Clear();
txtMeasuredRepeatability.Clear();
txtRepeatJudge.Clear();
lstRawTimes.ItemsSource = null;
rawTimes.Clear();
txtStatus.Text = "已清空";
}
// 清空流动时间
private void BtnClearTimes_Click(object sender, RoutedEventArgs e)
{
txtTime1.Clear();
txtTime2.Clear();
txtTime3.Clear();
txtTime4.Clear();
txtTime5.Clear();
txtTime6.Clear();
rawTimes.Clear();
lstRawTimes.ItemsSource = null;
}
// 增加一次测量在界面中添加更多输入框为简化我们已预留6个
private void BtnAddMeasurement_Click(object sender, RoutedEventArgs e)
{
// 本版本固定6个输入框无需动态增加
MessageBox.Show("已支持最多6次测量请直接在对应框中输入。", "提示");
}
// 核心计算:运动粘度、动力粘度、精密度
private void BtnCalcViscosity_Click(object sender, RoutedEventArgs e)
{
try
{
// 1. 读取流动时间
rawTimes = GetTimeValues();
if (rawTimes.Count < 4)
{
MessageBox.Show("至少需要输入4次流动时间", "数据不足", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// 2. 读取常数、密度、温度
if (!double.TryParse(txtConstant.Text, out double constant))
{
MessageBox.Show("请输入有效的粘度计常数 C", "参数错误", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (!double.TryParse(txtTestTemp.Text, out double temp))
{
MessageBox.Show("请输入试验温度", "参数错误", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
double density = 0;
if (!string.IsNullOrWhiteSpace(txtDensity.Text))
{
if (!double.TryParse(txtDensity.Text, out density))
{
MessageBox.Show("密度格式错误,将不计算动力粘度", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
// 3. 根据温度获取允许偏差(%
double allowedDeviationPercent = Models.Constants.GetAllowedDeviation(temp);
double allowedDeviation = 0;
// 4. 计算平均值、筛选有效数据
List<double> validTimes = new List<double>();
double avg = rawTimes.Average();
bool continueCalc = true;
int maxIterations = 10; // 防止死循环
while (continueCalc && maxIterations-- > 0)
{
validTimes = rawTimes.Where(t => Math.Abs(t - avg) <= avg * allowedDeviationPercent / 100.0).ToList();
if (validTimes.Count >= 3)
{
double newAvg = validTimes.Average();
if (Math.Abs(newAvg - avg) < 0.0001)
continueCalc = false;
else
avg = newAvg;
}
else
{
break;
}
}
if (validTimes.Count < 3)
{
MessageBox.Show("有效测量次数不足3次无法计算请检查数据是否离散过大。", "精密度超差", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
double finalAvg = validTimes.Average();
// 5. 计算运动粘度
double viscosity = constant * finalAvg;
// 6. 计算动力粘度(如果有密度)
double dynamicViscosity = 0;
if (density > 0)
{
dynamicViscosity = viscosity * density;
}
// 7. 计算本次测量的重复性(相对极差)
double measuredRepeatability = 0;
if (validTimes.Count > 1)
{
measuredRepeatability = (validTimes.Max() - validTimes.Min()) / finalAvg * 100;
}
// 8. 获取标准重复性限
double stdRepeatability = Models.Constants.GetRepeatabilityLimit(temp);
// 9. 更新UI
txtAvgTime.Text = finalAvg.ToString("F3");
txtViscosity.Text = viscosity.ToString("G4"); // 四位有效数字
if (density > 0)
txtDynamicViscosity.Text = dynamicViscosity.ToString("G4");
else
txtDynamicViscosity.Text = "未计算";
txtValidCount.Text = $"{validTimes.Count} / {rawTimes.Count}";
txtMeasuredRepeatability.Text = measuredRepeatability.ToString("F2") + "%";
txtRepeatability.Text = stdRepeatability.ToString("F1") + "%";
txtReproducibility.Text = Models.Constants.GetReproducibilityLimit(temp).ToString("F1") + "%";
bool repeatOK = measuredRepeatability <= stdRepeatability;
txtRepeatJudge.Text = repeatOK ? "合格" : $"超差 (允许 ≤ {stdRepeatability:F1}%)";
txtRepeatJudge.Foreground = repeatOK ? System.Windows.Media.Brushes.Green : System.Windows.Media.Brushes.Red;
txtPrecisionJudge.Text = repeatOK ? "精密度符合要求" : "精密度不符合要求,建议重新测试";
// 10. 显示原始数据
lstRawTimes.ItemsSource = rawTimes.Select((t, i) => new { Display = $"第{i + 1}次: {t:F3}s" }).ToList();
// 11. 保存当前数据到模型
currentData.SampleID = txtSampleID.Text;
currentData.SampleName = txtSampleName.Text;
currentData.TestTemp = temp;
currentData.Constant = constant;
currentData.Density = density > 0 ? density : (double?)null;
currentData.RawTimes = rawTimes;
currentData.ValidTimes = validTimes;
currentData.AvgTime = finalAvg;
currentData.Viscosity = viscosity;
currentData.DynamicViscosity = dynamicViscosity;
currentData.Operator = txtOperator.Text;
currentData.TestDate = dpTestDate.SelectedDate ?? DateTime.Now;
currentData.Remark = txtRemark.Text;
currentData.Repeatability = measuredRepeatability;
currentData.IsRepeatabilityOK = repeatOK;
txtStatus.Text = $"计算完成,有效次数 {validTimes.Count},运动粘度 {viscosity:G4} mm²/s";
}
catch (Exception ex)
{
MessageBox.Show($"计算错误: {ex.Message}", "异常", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// 从文本框获取流动时间列表
private List<double> GetTimeValues()
{
var list = new List<double>();
AddIfValid(txtTime1, list);
AddIfValid(txtTime2, list);
AddIfValid(txtTime3, list);
AddIfValid(txtTime4, list);
AddIfValid(txtTime5, list);
AddIfValid(txtTime6, list);
return list;
}
private void AddIfValid(TextBox tb, List<double> list)
{
if (!string.IsNullOrWhiteSpace(tb.Text) && double.TryParse(tb.Text, out double val))
{
list.Add(val);
}
}
// 生成原始记录
private void BtnGenRecord_Click(object sender, RoutedEventArgs e)
{
if (currentData.Viscosity <= 0)
{
MessageBox.Show("请先计算运动粘度!", "无数据", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var record = new TestRecordControl();
record.LoadData(currentData);
ReportContent.Content = record;
}
// 生成测试报告
private void BtnGenReport_Click(object sender, RoutedEventArgs e)
{
if (currentData.Viscosity <= 0)
{
MessageBox.Show("请先计算运动粘度!", "无数据", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var report = new TestReportControl();
report.LoadData(currentData);
ReportContent.Content = report;
}
// 打印预览
private void BtnPrintPreview_Click(object sender, RoutedEventArgs e)
{
if (ReportContent.Content == null)
{
MessageBox.Show("请先生成记录或报告", "无报表", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
if (ReportContent.Content is FrameworkElement visual)
{
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
printDialog.PrintVisual(visual, "粘度测试报表");
}
}
}
}
}

43
Models/Constants.cs Normal file
View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
namespace PetroleumViscosityTest.Models
{
public static class Constants
{
// 表2 粘度计在恒温水浴中的恒温时间
public static int GetThermostatTime(double temp)
{
if (temp == 80 || temp == 100) return 20;
if (temp == 40 || temp == 50) return 15;
if (temp >= 20 && temp <= 100) return 15; // 原文"10050"? 表2写“10050 15”? 实际根据逻辑
// 20℃及以下未明确默认10分钟
return 10;
}
// 根据温度获取允许偏差(%用于剔除异常值5.4条)
public static double GetAllowedDeviation(double temp)
{
if (temp >= 15 && temp <= 100) return 0.5;
if (temp >= -30 && temp < 15) return 1.5;
if (temp < -30) return 2.5;
return 0.5; // 默认
}
// 7.1 重复性(%
public static double GetRepeatabilityLimit(double temp)
{
if (temp >= 15 && temp <= 100) return 1.0;
if (temp >= -30 && temp < 15) return 3.0;
if (temp < -30) return 5.0;
return 1.0;
}
// 7.2 再现性(%
public static double GetReproducibilityLimit(double temp)
{
if (temp >= 15 && temp <= 100) return 2.2;
// 其他温度未给出按重复性的2倍左右估算
return 2.2;
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
namespace PetroleumViscosityTest.Models
{
public class ViscosityTestData
{
// 试样信息
public string SampleID { get; set; }
public string SampleName { get; set; }
public double TestTemp { get; set; }
// 粘度计常数
public double Constant { get; set; }
// 密度(可选)
public double? Density { get; set; }
// 流动时间
public List<double> RawTimes { get; set; } = new List<double>();
public List<double> ValidTimes { get; set; } = new List<double>();
public double AvgTime { get; set; }
// 结果
public double Viscosity { get; set; }
public double DynamicViscosity { get; set; }
// 人员日期
public string Operator { get; set; }
public DateTime TestDate { get; set; }
public string Remark { get; set; }
// 精密度
public double Repeatability { get; set; } // 实测重复性%
public bool IsRepeatabilityOK { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,3 @@
<Solution>
<Project Path="PetroleumViscosityTest.csproj" />
</Solution>