This commit is contained in:
@@ -126,9 +126,30 @@ namespace MembranePoreTester.ViewModels
|
||||
_plcConfig = App.PlcConfig;
|
||||
|
||||
PressCommand = new RelayCommand(async () => await TogglePressAsync());
|
||||
//BurstCommand = new RelayCommand(async () => await ReadBurstPressureAsync());
|
||||
StartCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.StartCoil, true));
|
||||
StopCommand = new RelayCommand(async () => await WriteCoilAsync(_plcConfig.StopCoil, true));
|
||||
|
||||
|
||||
// 在 StationItem 构造函数中
|
||||
StartCommand = new RelayCommand(async () =>
|
||||
{
|
||||
// 启动PLC
|
||||
await WriteCoilAsync(_plcConfig.StartCoil, true);
|
||||
|
||||
// 启动孔分布自动采集
|
||||
PoreDistributionVM.StartCollecting();
|
||||
|
||||
});
|
||||
|
||||
StopCommand = new RelayCommand(async () =>
|
||||
{
|
||||
// 停止自动采集
|
||||
PoreDistributionVM.StopCollecting();
|
||||
// 停止PLC
|
||||
await WriteCoilAsync(_plcConfig.StopCoil, true);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// 启动定时器,每秒读取一次 M21 状态
|
||||
_timer = new System.Windows.Threading.DispatcherTimer();
|
||||
_timer.Interval = TimeSpan.FromSeconds(1);
|
||||
@@ -242,7 +263,12 @@ namespace MembranePoreTester.ViewModels
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool _isPoreDistributionActive;
|
||||
public bool IsPoreDistributionActive
|
||||
{
|
||||
get => _isPoreDistributionActive;
|
||||
set => SetProperty(ref _isPoreDistributionActive, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,17 +3,171 @@ using MembranePoreTester.Helpers;
|
||||
using MembranePoreTester.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Win32;
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Legends;
|
||||
using OxyPlot.Series;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
|
||||
namespace MembranePoreTester.ViewModels
|
||||
{
|
||||
public class PoreDistributionViewModel : ViewModelBase, IStationViewModel
|
||||
{
|
||||
|
||||
#region
|
||||
|
||||
public class PressureModeItem
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public int Value { get; set; }
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text; // 直接返回要显示的文本
|
||||
}
|
||||
}
|
||||
|
||||
private PressureModeItem _selectedPressureMode;
|
||||
private List<PressureModeItem> _pressureModeList;
|
||||
|
||||
public List<PressureModeItem> PressureModeList => _pressureModeList ??= new List<PressureModeItem>
|
||||
{
|
||||
new PressureModeItem { Text = "小流量", Value = 1 },
|
||||
new PressureModeItem { Text = "大流量", Value = 0 }
|
||||
};
|
||||
|
||||
public PressureModeItem SelectedPressureMode
|
||||
{
|
||||
get => _selectedPressureMode;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedPressureMode, value))
|
||||
{
|
||||
Task.Run(async () => await WriteFlowModeAsync(value?.Text ?? "小流量"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
// 添加字段
|
||||
private System.Windows.Threading.DispatcherTimer _autoCollectTimer;
|
||||
private bool _isCollecting = false;
|
||||
|
||||
// 添加公共方法供工位调用
|
||||
public void StartCollecting()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
// 如果当前不在孔分布界面,不启动采集
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isCollecting) return;
|
||||
_isCollecting = true;
|
||||
_autoCollectTimer = new System.Windows.Threading.DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(1)
|
||||
};
|
||||
_autoCollectTimer.Tick += AutoCollectTimer_Tick;
|
||||
_autoCollectTimer.Start();
|
||||
}
|
||||
|
||||
public void StopCollecting()
|
||||
{
|
||||
_isCollecting = false;
|
||||
_autoCollectTimer?.Stop();
|
||||
_autoCollectTimer = null;
|
||||
}
|
||||
|
||||
private async void AutoCollectTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (!IsActive) return; // 不在当前标签页,跳过采集
|
||||
try
|
||||
{
|
||||
// 1. 读取当前压力
|
||||
float rawPressure = await _plcService.ReadPressureAsync(StationId);
|
||||
double pressure = Math.Round(rawPressure,2);
|
||||
|
||||
double flow = 0;
|
||||
if (TestMode == "湿膜")
|
||||
{
|
||||
float rawFlow = await _plcService.ReadWetFlowAsync();
|
||||
flow = rawFlow;
|
||||
}
|
||||
else
|
||||
{
|
||||
float rawFlow = await _plcService.ReadDryFlowAsync();
|
||||
flow = rawFlow;
|
||||
}
|
||||
|
||||
flow = Math.Round(flow,2);
|
||||
// 3. 在 DataPoints 中查找是否存在相同压力的行(允许微小误差)
|
||||
var existing = Record.DataPoints.FirstOrDefault(p => Math.Abs(p.Pressure - pressure) < 0.001);
|
||||
if (existing != null)
|
||||
{
|
||||
// 更新对应列
|
||||
if (TestMode == "湿膜")
|
||||
existing.WetFlow = flow;
|
||||
else
|
||||
existing.DryFlow = flow;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 新增一行
|
||||
var newPoint = new Models.DataPoint { Pressure = pressure };
|
||||
if (TestMode == "湿膜")
|
||||
newPoint.WetFlow = flow;
|
||||
else
|
||||
newPoint.DryFlow = flow;
|
||||
Record.DataPoints.Add(newPoint);
|
||||
}
|
||||
|
||||
// 4. 刷新曲线
|
||||
UpdatePlot();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"自动采集失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有数据点,重置表格和曲线
|
||||
/// </summary>
|
||||
public void ClearData()
|
||||
{
|
||||
// 清空数据点集合
|
||||
Record.DataPoints.Clear();
|
||||
|
||||
// 重置曲线
|
||||
UpdatePlot();
|
||||
|
||||
// 重置计算结果
|
||||
AveragePoreSize = 0;
|
||||
RangePercentage = 0;
|
||||
|
||||
// 可选:显示提示
|
||||
System.Diagnostics.Debug.WriteLine("孔分布数据已清空");
|
||||
}
|
||||
|
||||
private bool _isActive;
|
||||
public bool IsActive
|
||||
{
|
||||
get => _isActive;
|
||||
set => SetProperty(ref _isActive, value);
|
||||
}
|
||||
|
||||
|
||||
private PoreDistributionRecord _record = new();
|
||||
private TestLiquid _selectedLiquid;
|
||||
private bool _isCustomLiquid;
|
||||
@@ -27,11 +181,11 @@ namespace MembranePoreTester.ViewModels
|
||||
// 添加字段
|
||||
private readonly IPlcService _plcService;
|
||||
private readonly PlcConfiguration _plcConfig;
|
||||
private DataPoint _selectedDataPoint;
|
||||
private Models.DataPoint _selectedDataPoint;
|
||||
|
||||
|
||||
// 添加属性
|
||||
public DataPoint SelectedDataPoint
|
||||
public Models.DataPoint SelectedDataPoint
|
||||
{
|
||||
get => _selectedDataPoint;
|
||||
set => SetProperty(ref _selectedDataPoint, value);
|
||||
@@ -127,8 +281,49 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
|
||||
Record.DataPoints.CollectionChanged += (s, e) => UpdatePlot();
|
||||
|
||||
|
||||
|
||||
// 延迟2秒后读取,确保连接稳定
|
||||
Task.Delay(2000).ContinueWith(async _ =>
|
||||
{
|
||||
await ReadPressureModeAsync();
|
||||
}, TaskScheduler.Default);
|
||||
|
||||
}
|
||||
|
||||
private async Task ReadPressureModeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
ushort[] values = await _plcService.ReadHoldingRegistersAsync(_plcConfig.FlowModeRegister, 1);
|
||||
ushort val = values[0];
|
||||
string newValue = val == 0 ? "大流量" : "小流量";
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
// 更新选中项
|
||||
HighLowPressure = newValue;
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"读取流量模式失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public string HighLowPressure
|
||||
{
|
||||
get => _selectedPressureMode?.Text ?? "小流量";
|
||||
set
|
||||
{
|
||||
var mode = PressureModeList.FirstOrDefault(m => m.Text == value);
|
||||
if (mode != null)
|
||||
{
|
||||
SelectedPressureMode = mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReadPlcAsync()
|
||||
{
|
||||
@@ -156,7 +351,7 @@ namespace MembranePoreTester.ViewModels
|
||||
else
|
||||
{
|
||||
// 新增一行
|
||||
var newPoint = new DataPoint { Pressure = pressure };
|
||||
var newPoint = new Models.DataPoint { Pressure = pressure };
|
||||
if (TestMode == "湿膜")
|
||||
{
|
||||
float rawWet = await _plcService.ReadWetFlowAsync();
|
||||
@@ -178,7 +373,7 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
private void AddDataPoint()
|
||||
{
|
||||
Record.DataPoints.Add(new DataPoint());
|
||||
Record.DataPoints.Add(new Models.DataPoint());
|
||||
}
|
||||
|
||||
private void RemoveDataPoint()
|
||||
@@ -302,7 +497,7 @@ namespace MembranePoreTester.ViewModels
|
||||
Record.DataPoints.Clear();
|
||||
foreach (var dp in entity.DataPoints)
|
||||
{
|
||||
Record.DataPoints.Add(new DataPoint
|
||||
Record.DataPoints.Add(new Models.DataPoint
|
||||
{
|
||||
Pressure = dp.Pressure,
|
||||
WetFlow = dp.WetFlow,
|
||||
@@ -347,19 +542,6 @@ namespace MembranePoreTester.ViewModels
|
||||
set => SetProperty(ref _testMode, value);
|
||||
}
|
||||
|
||||
private string _selectedFlowModeIndex; // 0=大流量,1=小流量
|
||||
public string SelectedFlowModeIndex
|
||||
{
|
||||
get => _selectedFlowModeIndex;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedFlowModeIndex, value))
|
||||
{
|
||||
// 当选择变化时,写入 PLC 压力模式寄存器
|
||||
Task.Run(async () => await WriteFlowModeAsync(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private OxyPlot.PlotModel _plotModel;
|
||||
@@ -371,10 +553,10 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
private async Task WriteFlowModeAsync(string mode)
|
||||
{
|
||||
float val = mode == "大流量" ? 0.0f : 1.0f;
|
||||
ushort val = mode.ToString().Contains("大流量") ? (ushort)0 : (ushort)1;
|
||||
try
|
||||
{
|
||||
await _plcService.WriteMultipleRegistersAsync(_plcConfig.PressureModeRegister, val);
|
||||
await _plcService.WriteSingleRegisterAsync(_plcConfig.FlowModeRegister, val);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -382,6 +564,8 @@ namespace MembranePoreTester.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UpdatePlot()
|
||||
{
|
||||
var sorted = Record.DataPoints.OrderBy(p => p.Pressure).ToList();
|
||||
@@ -391,12 +575,53 @@ namespace MembranePoreTester.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
var model = new OxyPlot.PlotModel { Title = "流量-压力曲线" };
|
||||
model.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Bottom, Title = "压力" });
|
||||
model.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Left, Title = "流量 (L/min)" });
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "流量-压力曲线",
|
||||
TitleFontSize = 14,
|
||||
TitleFontWeight = 1
|
||||
};
|
||||
|
||||
var wetSeries = new OxyPlot.Series.LineSeries { Title = "湿膜流量", Color = OxyPlot.OxyColors.Blue, MarkerType = OxyPlot.MarkerType.Circle };
|
||||
var drySeries = new OxyPlot.Series.LineSeries { Title = "干膜流量", Color = OxyPlot.OxyColors.Red, MarkerType = OxyPlot.MarkerType.Circle };
|
||||
|
||||
|
||||
// 添加坐标轴
|
||||
model.Axes.Add(new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
Title = "压力 (kPa)",
|
||||
TitleFontSize = 12
|
||||
});
|
||||
|
||||
model.Axes.Add(new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
Title = "流量 (L/min)",
|
||||
TitleFontSize = 12
|
||||
});
|
||||
|
||||
// 湿膜流量 - 使用更清晰的标题
|
||||
var wetSeries = new LineSeries
|
||||
{
|
||||
Title = "● 湿膜流量 (Wet Flow)",
|
||||
Color = OxyColors.Blue,
|
||||
MarkerType = MarkerType.Circle,
|
||||
MarkerSize = 4,
|
||||
MarkerStroke = OxyColors.Blue,
|
||||
MarkerFill = OxyColors.Blue,
|
||||
StrokeThickness = 2
|
||||
};
|
||||
|
||||
// 干膜流量 - 使用更清晰的标题
|
||||
var drySeries = new LineSeries
|
||||
{
|
||||
Title = "▲ 干膜流量 (Dry Flow)",
|
||||
Color = OxyColors.Red,
|
||||
MarkerType = MarkerType.Triangle,
|
||||
MarkerSize = 5,
|
||||
MarkerStroke = OxyColors.Red,
|
||||
MarkerFill = OxyColors.Red,
|
||||
StrokeThickness = 2
|
||||
};
|
||||
|
||||
foreach (var dp in sorted)
|
||||
{
|
||||
@@ -411,5 +636,10 @@ namespace MembranePoreTester.ViewModels
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,25 @@
|
||||
<UserControl x:Class="MembranePoreTester.Views.BubblePointView"
|
||||
<!-- BubblePointView.xaml -->
|
||||
<UserControl x:Class="MembranePoreTester.Views.BubblePointView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:MembranePoreTester.ViewModels"
|
||||
xmlns:conv="clr-namespace:MembranePoreTester.Converters">
|
||||
<UserControl.Resources>
|
||||
<conv:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="10">
|
||||
|
||||
<Grid Margin="10" Background="#F5F7FA">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
@@ -15,7 +28,7 @@
|
||||
|
||||
<!-- 输入区域 -->
|
||||
<StackPanel Grid.Row="0">
|
||||
<GroupBox Header="样品信息" Margin="0,0,0,10">
|
||||
<GroupBox Header="📄 样品信息">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
@@ -29,8 +42,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}"
|
||||
SelectedItem="{Binding Record.SampleType}" Margin="5"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}" SelectedItem="{Binding Record.SampleType}" Margin="5"/>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="2" Content="规格:"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.SampleSpec}" Margin="5"/>
|
||||
@@ -43,51 +55,49 @@
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="测试液体" Margin="0,0,0,10">
|
||||
<GroupBox Header="🧪 测试液体">
|
||||
<StackPanel>
|
||||
<RadioButton Content="预定义" IsChecked="{Binding IsCustomLiquid, Converter={StaticResource InverseBooleanConverter}}" Margin="5"/>
|
||||
<ComboBox ItemsSource="{Binding Liquids}" SelectedItem="{Binding SelectedLiquid}"
|
||||
DisplayMemberPath="Name" IsEnabled="{Binding IsCustomLiquid, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Margin="5,0,5,5"/>
|
||||
<ComboBox ItemsSource="{Binding Liquids}" SelectedItem="{Binding SelectedLiquid}" DisplayMemberPath="Name" IsEnabled="{Binding IsCustomLiquid, Converter={StaticResource InverseBooleanConverter}}" Margin="5,0,5,5"/>
|
||||
<RadioButton Content="自定义" IsChecked="{Binding IsCustomLiquid}" Margin="5"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="20,0,0,0" IsEnabled="{Binding IsCustomLiquid}">
|
||||
<Label Content="表面张力(mN/m):"/>
|
||||
<TextBox Text="{Binding CustomSurfaceTension}" Width="100" Margin="5"/>
|
||||
</StackPanel>
|
||||
<!--<Label Content="生产厂家:" Margin="5"/>
|
||||
<TextBox Text="{Binding Record.LiquidManufacturer}" Margin="5"/>-->
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<GroupBox Header="当前压力" Margin="0,0,0,10">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding Record.BubbleCurrentPressure}" Width="150" Margin="5"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<GroupBox Header="泡点压力" Margin="0,0,0,10">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding Record.BubblePointPressure}" Width="150" Margin="5"/>
|
||||
|
||||
<Button Content="涨破" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5"/>
|
||||
<ComboBox ItemsSource="{Binding PressureUnits}" SelectedItem="{Binding Record.PressureUnit}" Width="80" Margin="5"/>
|
||||
<Button Content="计算最大孔径" Command="{Binding CalculateCommand}" Padding="10,5" Margin="5"/>
|
||||
<GroupBox Header="📊 压力数据">
|
||||
<StackPanel>
|
||||
<Label Content="当前压力(kPa)" FontWeight="Normal" Margin="5,0,0,0"/>
|
||||
<TextBox Text="{Binding Record.BubbleCurrentPressure}" Width="150" Margin="5,0,5,5"/>
|
||||
<Label Content="泡点压力(kPa)" FontWeight="Normal" Margin="5,0,0,0"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding Record.BubblePointPressure}" Width="150" Margin="5"/>
|
||||
<Button Content="涨破" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5" Background="#FF9800"/>
|
||||
<ComboBox ItemsSource="{Binding PressureUnits}" SelectedItem="{Binding Record.PressureUnit}" Width="80" Margin="5"/>
|
||||
<Button Content="计算最大孔径" Command="{Binding CalculateCommand}" Padding="10,5" Margin="5" Background="#2196F3"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 结果显示 -->
|
||||
<GroupBox Grid.Row="1" Header="测试结果" VerticalAlignment="Center">
|
||||
<TextBlock FontSize="36" TextAlignment="Center"
|
||||
Text="{Binding MaxPoreSize, StringFormat={}{0:F3} μm}"/>
|
||||
</GroupBox>
|
||||
<Border Grid.Row="1" Margin="0,10" Background="White" CornerRadius="8" BorderBrush="#E9ECF0" BorderThickness="1">
|
||||
<Grid>
|
||||
<GroupBox Header="✨ 测试结果" BorderThickness="0" Margin="0">
|
||||
<TextBlock FontSize="48" FontWeight="Bold" TextAlignment="Center"
|
||||
Text="{Binding MaxPoreSize, StringFormat={}{0:F3} μm}" Foreground="#2196F3"/>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Content="压力校准" Command="{Binding OpenPressureCalibCommand}" Padding="15,8" Margin="5"/>
|
||||
<Button Content="保存到历史" Command="{Binding SaveCommand}" Padding="15,8" Margin="5"/>
|
||||
<Button Content="生成报告" Command="{Binding GenerateReportCommand}" Padding="15,8" Margin="5"/>
|
||||
<Button Content="导出Excel" Command="{Binding ExportCommand}" Padding="15,8" Margin="5"/>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
|
||||
<Button Content="⚙ 压力校准" Command="{Binding OpenPressureCalibCommand}" Padding="15,8" Background="#607D8B"/>
|
||||
<Button Content="💾 保存到历史" Command="{Binding SaveCommand}" Padding="15,8" Background="#4CAF50"/>
|
||||
<Button Content="📄 生成报告" Command="{Binding GenerateReportCommand}" Padding="15,8" Background="#2196F3"/>
|
||||
<Button Content="📊 导出Excel" Command="{Binding ExportCommand}" Padding="15,8" Background="#FF9800"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -60,7 +60,7 @@
|
||||
</StackPanel>
|
||||
|
||||
<!-- 测试类型选项卡 -->
|
||||
<TabControl>
|
||||
<TabControl x:Name="stationTabControl" ItemsSource="{Binding Stations}" SelectionChanged="TabControl_SelectionChanged">
|
||||
<TabItem Header="泡点法测试最大孔径">
|
||||
<local:BubblePointView DataContext="{Binding BubblePointVM}"/>
|
||||
</TabItem>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using MembranePoreTester.ViewModels;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MembranePoreTester.Views
|
||||
{
|
||||
@@ -53,5 +55,53 @@ namespace MembranePoreTester.Views
|
||||
win.ShowDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var selectedStation = stationTabControl.SelectedItem as MainViewModel.StationItem;
|
||||
if (selectedStation != null)
|
||||
{
|
||||
var content = stationTabControl.SelectedContent as ContentPresenter;
|
||||
if (content != null)
|
||||
{
|
||||
var innerTabControl = FindVisualChild<TabControl>(content);
|
||||
if (innerTabControl != null)
|
||||
{
|
||||
var selectedTabItem = innerTabControl.SelectedItem as TabItem;
|
||||
bool isPoreDistributionActive = selectedTabItem?.Header?.ToString() == "孔分布测试";
|
||||
|
||||
// 关键:设置 StationItem 的状态
|
||||
selectedStation.IsPoreDistributionActive = isPoreDistributionActive;
|
||||
selectedStation.PoreDistributionVM.IsActive = isPoreDistributionActive;
|
||||
|
||||
if (isPoreDistributionActive)
|
||||
{
|
||||
// 切换到孔分布时,清空之前的数据
|
||||
selectedStation.PoreDistributionVM.ClearData();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 离开孔分布界面时,停止自动采集
|
||||
selectedStation.PoreDistributionVM.StopCollecting();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法:查找 Visual Tree 中的指定类型元素
|
||||
private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
|
||||
{
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(parent, i);
|
||||
if (child is T t) return t;
|
||||
var result = FindVisualChild<T>(child);
|
||||
if (result != null) return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@
|
||||
<TextBox x:Name="txtPressureUpper" Grid.Row="0" Grid.Column="1"/>
|
||||
<Label Grid.Row="1" Grid.Column="0">加压速率(D280):</Label>
|
||||
<TextBox x:Name="txtPressureRate" Grid.Row="1" Grid.Column="1"/>
|
||||
<Label Grid.Row="2" Grid.Column="0">加压系数(D282):</Label>
|
||||
<TextBox x:Name="txtPressureCoeff" Grid.Row="2" Grid.Column="1"/>
|
||||
<!--<Label Grid.Row="2" Grid.Column="0">加压系数(D282):</Label>
|
||||
<TextBox x:Name="txtPressureCoeff" Grid.Row="2" Grid.Column="1"/>-->
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace MembranePoreTester.Views
|
||||
{
|
||||
[txtPressureUpper] = (_config.PressureUpperLimit, "加压上限"),
|
||||
[txtPressureRate] = (_config.PressureRate, "加压速率"),
|
||||
[txtPressureCoeff] = (_config.PressureCoeff, "加压系数"),
|
||||
//[txtPressureCoeff] = (_config.PressureCoeff, "加压系数"),
|
||||
|
||||
[txtHPCoeff1] = (_config.HPCoeff1, "工位1高压系数"),
|
||||
[txtLPCoeff1] = (_config.LPCoeff1, "工位1低压系数"),
|
||||
|
||||
@@ -2,139 +2,291 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:oxy="http://oxyplot.org/wpf"
|
||||
xmlns:conv="clr-namespace:MembranePoreTester.Converters">
|
||||
xmlns:conv="clr-namespace:MembranePoreTester.Converters"
|
||||
Background="#F5F7FA" >
|
||||
<UserControl.Resources>
|
||||
<conv:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<GroupBox Grid.Row="0" Header="样品信息" Margin="0,0,0,10">
|
||||
<Grid>
|
||||
<!-- 统一按钮样式 -->
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#2196F3"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Padding" Value="12,6"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}" CornerRadius="4" Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#1976D2"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" Value="#0D47A1"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- 统一文本框样式 -->
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Height" Value="28"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#D0D3D9"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Padding" Value="5,2"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- 统一组合框样式 -->
|
||||
<Style TargetType="ComboBox">
|
||||
<Setter Property="Height" Value="28"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#D0D3D9"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- 统一标签样式 -->
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
</Style>
|
||||
|
||||
<!-- 统一GroupBox样式(自定义,圆角白色背景) -->
|
||||
<Style TargetType="GroupBox">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#E9ECF0"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Margin" Value="0,0,0,10"/>
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="GroupBox">
|
||||
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="6">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="{TemplateBinding Header}" FontWeight="SemiBold" FontSize="14" Margin="0,0,0,10"/>
|
||||
<ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- DataGrid 样式 -->
|
||||
<Style TargetType="DataGrid">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#E9ECF0"/>
|
||||
<Setter Property="RowHeight" Value="28"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="GridLinesVisibility" Value="Horizontal"/>
|
||||
<Setter Property="HeadersVisibility" Value="Column"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 样品信息区域 -->
|
||||
<GroupBox Grid.Row="0" Header="📄 样品信息">
|
||||
<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"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}"
|
||||
SelectedItem="{Binding Record.SampleType}"/>
|
||||
<!--<Label Grid.Row="0" Grid.Column="2" Content="规格:"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.SampleSpec}"/>-->
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="2" Content="室温(°C):"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.RoomTemperature}"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="2" Content="浸润时间(h):"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding Record.SoakingTime}"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="测试液体:"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Liquids}"
|
||||
SelectedItem="{Binding SelectedLiquid}" DisplayMemberPath="Name"/>
|
||||
<!--<Label Grid.Row="2" Grid.Column="2" Content="生产厂家:"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding Record.LiquidManufacturer}"/>-->
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="压力单位:"/>
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" ItemsSource="{Binding PressureUnits}"
|
||||
SelectedItem="{Binding Record.PressureUnit}"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 数据表格与图表区域 -->
|
||||
<Grid Grid.Row="1">
|
||||
<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"/>
|
||||
<!-- 新增第4行 -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 第0行 -->
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}"
|
||||
SelectedItem="{Binding Record.SampleType}" Margin="5"/>
|
||||
<Label Grid.Row="0" Grid.Column="2" Content="规格:"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.SampleSpec}" Margin="5"/>
|
||||
<!-- 左侧数据表格 --><!--
|
||||
<GroupBox Grid.Column="0" Header="📊 压力-流量数据" Margin="0,0,5,0">
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="➕ 添加行" Command="{Binding AddDataPointCommand}" Background="#4CAF50"/>
|
||||
<Button Content="➖ 删除行" Command="{Binding RemoveDataPointCommand}" Background="#F44336"/>
|
||||
|
||||
<!-- 第1行 -->
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="室温(°C):"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Record.RoomTemperature}" Margin="5"/>
|
||||
<Label Grid.Row="1" Grid.Column="2" Content="浸润时间(h):"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding Record.SoakingTime}" Margin="5"/>
|
||||
|
||||
<!-- 第2行 -->
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="测试液体:"/>
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" ItemsSource="{Binding Liquids}"
|
||||
SelectedItem="{Binding SelectedLiquid}" DisplayMemberPath="Name" Margin="5"/>
|
||||
<Label Grid.Row="2" Grid.Column="2" Content="生产厂家:"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding Record.LiquidManufacturer}" Margin="5"/>
|
||||
|
||||
<!-- 第3行:压力单位 -->
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="压力单位:"/>
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" ItemsSource="{Binding PressureUnits}"
|
||||
SelectedItem="{Binding Record.PressureUnit}" Margin="5"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<ComboBox SelectedItem="{Binding TestMode}" Width="80">
|
||||
<ComboBoxItem Content="湿膜" IsSelected="True"/>
|
||||
<ComboBoxItem Content="干膜"/>
|
||||
</ComboBox>
|
||||
<ComboBox ItemsSource="{Binding PressureModeList}"
|
||||
SelectedItem="{Binding SelectedPressureMode}" Width="100"/>
|
||||
|
||||
<!-- 数据表格和简单图表(此处用ListView代替图表) -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 左侧数据输入表格 -->
|
||||
<GroupBox Grid.Column="0" Header="压力-流量数据" Margin="0,0,5,0">
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,5">
|
||||
<Button Content="添加行" Command="{Binding AddDataPointCommand}" Padding="10,5" Margin="5"/>
|
||||
<Button Content="删除行" Command="{Binding RemoveDataPointCommand}" Padding="10,5" Margin="5"/>
|
||||
|
||||
--><!--<Button Content="📡 读取PLC" Command="{Binding ReadPlcCommand}" Background="#FF9800"/>--><!--
|
||||
</StackPanel>
|
||||
|
||||
<!-- 新增:模式选择 -->
|
||||
<ComboBox SelectedItem="{Binding TestMode}" Width="80" Margin="5">
|
||||
<ComboBoxItem Content="湿膜" IsSelected="True"/>
|
||||
<ComboBoxItem Content="干膜"/>
|
||||
</ComboBox>
|
||||
<ComboBox SelectedIndex="{Binding SelectedFlowModeIndex}" Width="100" Margin="5">
|
||||
<ComboBoxItem IsSelected="True" Content="大流量"/>
|
||||
<ComboBoxItem Content="小流量"/>
|
||||
</ComboBox>
|
||||
<Button Content="读取PLC" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5"/>
|
||||
</StackPanel>
|
||||
<DataGrid ItemsSource="{Binding Record.DataPoints}" AutoGenerateColumns="False" CanUserAddRows="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="压力" Binding="{Binding Pressure, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
|
||||
<DataGridTextColumn Header="湿膜流量(L/min)" Binding="{Binding WetFlow, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
|
||||
<DataGridTextColumn Header="干膜流量(L/min)" Binding="{Binding DryFlow, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="400">
|
||||
<DataGrid ItemsSource="{Binding Record.DataPoints}"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
ColumnWidth="*">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="压力"
|
||||
Binding="{Binding Pressure, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="120"/>
|
||||
<DataGridTextColumn Header="湿膜流量(L/min)"
|
||||
Binding="{Binding WetFlow, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="120"/>
|
||||
<DataGridTextColumn Header="干膜流量(L/min)"
|
||||
Binding="{Binding DryFlow, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="120"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</ScrollViewer>
|
||||
</DockPanel>
|
||||
</GroupBox>-->
|
||||
|
||||
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- 右侧简易数据展示(可用图表库,此处仅用ListBox预览) -->
|
||||
<GroupBox Grid.Column="2" Header="数据预览" Margin="5,0,0,0">
|
||||
<!--<ListBox ItemsSource="{Binding Record.DataPoints}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<!-- 左侧数据表格区域,改为两列 Grid -->
|
||||
<Grid Grid.Column="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 湿膜表格 -->
|
||||
<GroupBox Grid.Column="0" Header="💧 湿膜数据" Margin="0,0,5,0">
|
||||
<DataGrid ItemsSource="{Binding Record.DataPoints}"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
ColumnWidth="*">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="压力"
|
||||
Binding="{Binding Pressure, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="100"/>
|
||||
<DataGridTextColumn Header="湿膜流量(L/min)"
|
||||
Binding="{Binding WetFlow, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="100"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 干膜表格 -->
|
||||
<GroupBox Grid.Column="1" Header="🔥 干膜数据" Margin="5,0,0,0">
|
||||
<DataGrid ItemsSource="{Binding Record.DataPoints}"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
ColumnWidth="*">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="压力"
|
||||
Binding="{Binding Pressure, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="100"/>
|
||||
<DataGridTextColumn Header="干膜流量(L/min)"
|
||||
Binding="{Binding DryFlow, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="100"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
|
||||
|
||||
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" Background="#E9ECF0"/>
|
||||
|
||||
<!-- 右侧曲线图 -->
|
||||
<GroupBox Grid.Column="2" Header="📈 流量-压力曲线" Margin="5,0,0,0">
|
||||
<StackPanel>
|
||||
<Border Background="#F5F5F5" CornerRadius="4" Padding="8,4" Margin="0,0,0,5" HorizontalAlignment="Right">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Pressure, StringFormat=P:{0:F2}}"/>
|
||||
<TextBlock Text=" "/>
|
||||
<TextBlock Text="{Binding WetFlow, StringFormat=W:{0:F3}}"/>
|
||||
<TextBlock Text=" "/>
|
||||
<TextBlock Text="{Binding DryFlow, StringFormat=D:{0:F3}}"/>
|
||||
<Rectangle Width="20" Height="2" Fill="Blue" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="湿膜流量 (Wet Flow)" FontSize="11" Margin="0,0,15,0"/>
|
||||
<Rectangle Width="20" Height="2" Fill="Red" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="干膜流量 (Dry Flow)" FontSize="11"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>-->
|
||||
<GroupBox Grid.Column="2" Header="流量-压力曲线" Margin="5,0,0,0">
|
||||
<oxy:PlotView Model="{Binding PlotModel}" Height="300" Margin="5"/>
|
||||
</Border>
|
||||
<oxy:PlotView Model="{Binding PlotModel}" Height="300" Margin="5"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- 计算结果区域 -->
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="0,10,0,0">
|
||||
<GroupBox Header="平均孔径" Margin="5">
|
||||
<TextBlock Text="{Binding AveragePoreSize, StringFormat={}{0:F3} μm}" FontSize="16"/>
|
||||
</GroupBox>
|
||||
<GroupBox Header="孔分布区间计算" Margin="5">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding LowerPore}" Width="60" Margin="5"/>
|
||||
<TextBlock Text="~" VerticalAlignment="Center"/>
|
||||
<TextBox Text="{Binding UpperPore}" Width="60" Margin="5"/>
|
||||
<TextBlock Text="μm" VerticalAlignment="Center"/>
|
||||
<Button Content="计算" Command="{Binding CalculateCommand}" Margin="10,0" Padding="10,5"/>
|
||||
<TextBlock Text="{Binding RangePercentage, StringFormat={}{0:F1}%}" FontSize="16" VerticalAlignment="Center" Margin="10,0"/>
|
||||
<!-- 计算结果及操作按钮区域 -->
|
||||
<Border Grid.Row="2" Margin="0,10,0,0" Background="White" CornerRadius="6" Padding="10" BorderBrush="#E9ECF0" BorderThickness="1">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<GroupBox Header="📏 平均孔径" Margin="5" BorderThickness="0">
|
||||
<TextBlock Text="{Binding AveragePoreSize, StringFormat={}{0:F3} μm}" FontSize="20" FontWeight="Bold" Foreground="#2196F3"/>
|
||||
</GroupBox>
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="10,0"/>
|
||||
<GroupBox Header="🎯 孔分布区间计算" Margin="5" BorderThickness="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="{Binding LowerPore}" Width="60" Margin="2"/>
|
||||
<TextBlock Text="~" VerticalAlignment="Center" Margin="2"/>
|
||||
<TextBox Text="{Binding UpperPore}" Width="60" Margin="2"/>
|
||||
<TextBlock Text="μm" VerticalAlignment="Center" Margin="5,0,10,0"/>
|
||||
<Button Content="计算" Command="{Binding CalculateCommand}" Margin="5,0" Padding="12,5" Background="#2196F3"/>
|
||||
<TextBlock Text="{Binding RangePercentage, StringFormat={}{0:F1}%}" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" Margin="10,0" Foreground="#4CAF50"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="10,0"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="🔧 流量校准" Command="{Binding OpenFlowCalibCommand}" Background="#607D8B"/>
|
||||
<Button Content="📄 生成报告" Command="{Binding GenerateReportCommand}" Background="#2196F3"/>
|
||||
<Button Content="💾 保存到历史" Command="{Binding SaveCommand}" Background="#4CAF50"/>
|
||||
<Button Content="📊 导出Excel" Command="{Binding ExportCommand}" Background="#FF9800"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<Button Content="流量校准" Command="{Binding OpenFlowCalibCommand}" Padding="15,8" Margin="5"/>
|
||||
<Button Content="生成报告" Command="{Binding GenerateReportCommand}" Padding="15,8" Margin="5"/>
|
||||
<Button Content="保存到历史" Command="{Binding SaveCommand}" Padding="15,8" Margin="5"/>
|
||||
<Button Content="导出Excel" Command="{Binding ExportCommand}" Padding="15,8" Margin="5"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Windows.Controls;
|
||||
using MembranePoreTester.ViewModels;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MembranePoreTester.Views
|
||||
{
|
||||
@@ -8,6 +9,20 @@ namespace MembranePoreTester.Views
|
||||
{
|
||||
InitializeComponent();
|
||||
//DataContext = new ViewModels.PoreDistributionViewModel();
|
||||
|
||||
// 监听 IsVisible 变化
|
||||
this.IsVisibleChanged += (s, e) =>
|
||||
{
|
||||
if (this.DataContext is ViewModels.PoreDistributionViewModel vm)
|
||||
{
|
||||
vm.IsActive = this.IsVisible;
|
||||
if (!this.IsVisible)
|
||||
{
|
||||
// 离开孔分布界面时,停止自动采集
|
||||
vm.StopCollecting();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
"PressureFactor": 1.0,
|
||||
|
||||
// 流量寄存器地址(每个工位共用,但需配合流量模式切换)
|
||||
"WetFlowRegister": 2, // 湿膜流量寄存器起始地址(D2~D3)
|
||||
"WetFlowRegister": 12, // 湿膜流量寄存器起始地址(D2~D3)
|
||||
"DryFlowRegister": 4, // 干膜流量寄存器起始地址(D4~D5)
|
||||
"WetFlowFactor": 1.0, // 湿膜流量系数
|
||||
"DryFlowFactor": 1.0, // 干膜流量系数
|
||||
|
||||
Reference in New Issue
Block a user