This commit is contained in:
@@ -67,24 +67,33 @@ namespace MembranePoreTester.ViewModels
|
||||
private bool _isCollecting = false;
|
||||
|
||||
// 添加公共方法供工位调用
|
||||
//public void StartCollecting()
|
||||
//{
|
||||
// System.Diagnostics.Debug.WriteLine($"StartCollecting 工位{StationId}, IsActive={IsActive}");
|
||||
// //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 StartCollecting()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
// 如果当前不在孔分布界面,不启动采集
|
||||
return;
|
||||
}
|
||||
|
||||
// 不再依赖 IsActive,定时器始终启动
|
||||
if (_isCollecting) return;
|
||||
_isCollecting = true;
|
||||
_autoCollectTimer = new System.Windows.Threading.DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(1)
|
||||
};
|
||||
_autoCollectTimer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
|
||||
_autoCollectTimer.Tick += AutoCollectTimer_Tick;
|
||||
_autoCollectTimer.Start();
|
||||
}
|
||||
|
||||
public void StopCollecting()
|
||||
{
|
||||
_isCollecting = false;
|
||||
@@ -94,7 +103,7 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
private async void AutoCollectTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
//if (!IsActive) return;
|
||||
if (!IsActive) return;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -762,7 +771,7 @@ namespace MembranePoreTester.ViewModels
|
||||
StationId = this.StationId,
|
||||
TestDate = Record.TestDate,
|
||||
Tester = Record.Tester ?? "系统操作员",
|
||||
SampleType = Record.SampleType,
|
||||
SampleType = Record.SampleType ?? "膜类型缺省值",
|
||||
SampleSpec = Record.SampleSpec ?? "缺省值",
|
||||
RoomTemperature = Record.RoomTemperature,
|
||||
SoakingTime = Record.SoakingTime,
|
||||
@@ -924,9 +933,111 @@ namespace MembranePoreTester.ViewModels
|
||||
|
||||
|
||||
|
||||
|
||||
//private void UpdatePlot()
|
||||
//{
|
||||
// // 确保在 UI 线程执行
|
||||
// if (Application.Current != null && !Application.Current.Dispatcher.CheckAccess())
|
||||
// {
|
||||
// Application.Current.Dispatcher.BeginInvoke((Action)UpdatePlot);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// var sorted = Record.DataPoints.OrderBy(p => p.Pressure).ToList();
|
||||
// if (sorted.Count == 0)
|
||||
// {
|
||||
// PlotModel = null;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// var model = new PlotModel
|
||||
// {
|
||||
// Title = "流量-压力曲线",
|
||||
// TitleFontSize = 14,
|
||||
// TitleFontWeight = 1
|
||||
// };
|
||||
|
||||
// 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,
|
||||
// Minimum = 0,
|
||||
// MajorGridlineStyle = LineStyle.Solid,
|
||||
// MinorGridlineStyle = LineStyle.Dot
|
||||
// });
|
||||
|
||||
// // 根据当前模式绘制对应的曲线(只绘制流量 > 0 的点)
|
||||
// if (TestMode != null && TestMode.Contains("湿膜"))
|
||||
// {
|
||||
// var wetSeries = new LineSeries
|
||||
// {
|
||||
// Title = "湿膜流量 (Wet Flow)",
|
||||
// Color = OxyColors.Blue,
|
||||
// MarkerType = MarkerType.None,
|
||||
// StrokeThickness = 1
|
||||
// };
|
||||
// foreach (var dp in sorted.Where(p => p.WetFlow > 0))
|
||||
// wetSeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.WetFlow));
|
||||
// if (wetSeries.Points.Count > 0)
|
||||
// model.Series.Add(wetSeries);
|
||||
// }
|
||||
// else if (TestMode != null && TestMode.Contains("干膜"))
|
||||
// {
|
||||
// var drySeries = new LineSeries
|
||||
// {
|
||||
// Title = "干膜流量 (Dry Flow)",
|
||||
// Color = OxyColors.Red,
|
||||
// MarkerType = MarkerType.None,
|
||||
// StrokeThickness = 1
|
||||
// };
|
||||
// foreach (var dp in sorted.Where(p => p.DryFlow > 0))
|
||||
// drySeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.DryFlow));
|
||||
// if (drySeries.Points.Count > 0)
|
||||
// model.Series.Add(drySeries);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // “全部”模式:同时显示两条曲线,但仍过滤掉 0 值点
|
||||
// var wetSeries = new LineSeries
|
||||
// {
|
||||
// Title = "湿膜流量 (Wet Flow)",
|
||||
// Color = OxyColors.Blue,
|
||||
// MarkerType = MarkerType.None,
|
||||
// StrokeThickness = 1
|
||||
// };
|
||||
// var drySeries = new LineSeries
|
||||
// {
|
||||
// Title = "干膜流量 (Dry Flow)",
|
||||
// Color = OxyColors.Red,
|
||||
// MarkerType = MarkerType.None,
|
||||
// StrokeThickness = 1
|
||||
// };
|
||||
// foreach (var dp in sorted)
|
||||
// {
|
||||
// if (dp.WetFlow > 0) wetSeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.WetFlow));
|
||||
// if (dp.DryFlow > 0) drySeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.DryFlow));
|
||||
// }
|
||||
// if (wetSeries.Points.Count > 0) model.Series.Add(wetSeries);
|
||||
// if (drySeries.Points.Count > 0) model.Series.Add(drySeries);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// PlotModel = model;
|
||||
//}
|
||||
|
||||
|
||||
private void UpdatePlot()
|
||||
{
|
||||
// Ensure we run on UI thread because we update PlotModel (bound to UI)
|
||||
// 确保在 UI 线程执行
|
||||
if (Application.Current != null && !Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke((Action)UpdatePlot);
|
||||
@@ -947,81 +1058,100 @@ namespace MembranePoreTester.ViewModels
|
||||
TitleFontWeight = 1
|
||||
};
|
||||
|
||||
// 让线条更平滑:使用线性插值(OxyPlot 默认即可),同时关闭区域填充等
|
||||
model.DefaultColors = new[] { OxyColors.Blue, OxyColors.Red };
|
||||
|
||||
|
||||
|
||||
// 添加坐标轴
|
||||
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,
|
||||
Minimum = 0, // 从0开始绘制,避免覆盖整个Y轴
|
||||
Minimum = 0,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Dot
|
||||
});
|
||||
|
||||
// 湿膜流量 - 使用更清晰的标题
|
||||
var wetSeries = new LineSeries
|
||||
// 干膜半流量曲线(绿色虚线,每个压力点干膜流量的一半)
|
||||
var halfDrySeries = new LineSeries
|
||||
{
|
||||
Title = "湿膜流量 (Wet Flow)",
|
||||
Color = OxyColors.Blue,
|
||||
Title = "干膜半流量 (Half of Dry Flow)",
|
||||
Color = OxyColors.Green,
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 1
|
||||
StrokeThickness = 1,
|
||||
LineStyle = LineStyle.Dash
|
||||
};
|
||||
|
||||
// 干膜流量 - 使用更清晰的标题
|
||||
var drySeries = new LineSeries
|
||||
foreach (var dp in sorted.Where(p => p.DryFlow > 0))
|
||||
{
|
||||
Title = "干膜流量 (Dry Flow)",
|
||||
Color = OxyColors.Red,
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
|
||||
// 始终按记录填充两个序列(保留历史数据),但只在当前测试模式下将对应序列添加到图表
|
||||
foreach (var dp in sorted)
|
||||
{
|
||||
wetSeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.WetFlow));
|
||||
drySeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.DryFlow));
|
||||
halfDrySeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.DryFlow / 2.0));
|
||||
}
|
||||
|
||||
// 根据当前 TestMode 决定显示哪条曲线,切换回另一种模式时其历史数据会从 Record 恢复并显示
|
||||
// 根据当前模式绘制对应的曲线(只绘制流量 > 0 的点)
|
||||
if (TestMode != null && TestMode.Contains("湿膜"))
|
||||
{
|
||||
var wetSeries = new LineSeries
|
||||
{
|
||||
Title = "湿膜流量 (Wet Flow)",
|
||||
Color = OxyColors.Blue,
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
foreach (var dp in sorted.Where(p => p.WetFlow > 0))
|
||||
wetSeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.WetFlow));
|
||||
if (wetSeries.Points.Count > 0)
|
||||
model.Series.Add(wetSeries);
|
||||
// 湿膜模式下也显示半流量线(便于观察交点)
|
||||
if (halfDrySeries.Points.Count > 0)
|
||||
model.Series.Add(halfDrySeries);
|
||||
}
|
||||
else if (TestMode != null && TestMode.Contains("干膜"))
|
||||
{
|
||||
var drySeries = new LineSeries
|
||||
{
|
||||
Title = "干膜流量 (Dry Flow)",
|
||||
Color = OxyColors.Red,
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
foreach (var dp in sorted.Where(p => p.DryFlow > 0))
|
||||
drySeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.DryFlow));
|
||||
if (drySeries.Points.Count > 0)
|
||||
model.Series.Add(drySeries);
|
||||
if (halfDrySeries.Points.Count > 0)
|
||||
model.Series.Add(halfDrySeries);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果没有明确模式,默认显示两条曲线(适用于同时显示的情况)
|
||||
if (wetSeries.Points.Count > 0)
|
||||
model.Series.Add(wetSeries);
|
||||
if (drySeries.Points.Count > 0)
|
||||
model.Series.Add(drySeries);
|
||||
// “全部”模式:同时显示两条曲线,但仍过滤掉 0 值点
|
||||
var wetSeries = new LineSeries
|
||||
{
|
||||
Title = "湿膜流量 (Wet Flow)",
|
||||
Color = OxyColors.Blue,
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
var drySeries = new LineSeries
|
||||
{
|
||||
Title = "干膜流量 (Dry Flow)",
|
||||
Color = OxyColors.Red,
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
foreach (var dp in sorted)
|
||||
{
|
||||
if (dp.WetFlow > 0) wetSeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.WetFlow));
|
||||
if (dp.DryFlow > 0) drySeries.Points.Add(new OxyPlot.DataPoint(dp.Pressure, dp.DryFlow));
|
||||
}
|
||||
if (wetSeries.Points.Count > 0) model.Series.Add(wetSeries);
|
||||
if (drySeries.Points.Count > 0) model.Series.Add(drySeries);
|
||||
if (halfDrySeries.Points.Count > 0) model.Series.Add(halfDrySeries);
|
||||
}
|
||||
|
||||
lock (_plotLock)
|
||||
{
|
||||
PlotModel = model;
|
||||
}
|
||||
PlotModel = model;
|
||||
}
|
||||
|
||||
|
||||
public ICommand ClearAllCommand { get; }
|
||||
|
||||
|
||||
|
||||
@@ -261,9 +261,17 @@
|
||||
<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"/>
|
||||
<!-- 新增:干膜半流量标注(绿色虚线) -->
|
||||
<Rectangle Width="20" Height="2" Fill="Green" Margin="10,0,5,0"/>
|
||||
<TextBlock Text="干膜半流量 (Half of Dry Flow)" FontSize="11"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<oxy:PlotView Model="{Binding PlotModel}" Height="300" Margin="5"/>
|
||||
<!--<oxy:PlotView Model="{Binding PlotModel}" Height="300" Margin="5"/>-->
|
||||
|
||||
<oxy:PlotView x:Name="PlotViewStation1" Height="300" Margin="5" Visibility="Collapsed"/>
|
||||
<oxy:PlotView x:Name="PlotViewStation2" Height="300" Margin="5" Visibility="Collapsed"/>
|
||||
<oxy:PlotView x:Name="PlotViewStation3" Height="300" Margin="5" Visibility="Collapsed"/>
|
||||
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
|
||||
@@ -6,51 +6,92 @@ namespace MembranePoreTester.Views
|
||||
{
|
||||
public partial class PoreDistributionView : UserControl
|
||||
{
|
||||
private MainViewModel _mainVM;
|
||||
|
||||
public PoreDistributionView()
|
||||
{
|
||||
InitializeComponent();
|
||||
//DataContext = new ViewModels.PoreDistributionViewModel();
|
||||
|
||||
// 监听 IsVisible 变化
|
||||
this.IsVisibleChanged += (s, e) =>
|
||||
{
|
||||
if (this.DataContext is ViewModels.PoreDistributionViewModel vm)
|
||||
|
||||
if (this.DataContext is PoreDistributionViewModel vm)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"工位{vm.StationId} IsVisible={this.IsVisible}");
|
||||
vm.IsActive = this.IsVisible;
|
||||
if (!this.IsVisible)
|
||||
{
|
||||
// 离开孔分布界面时,停止自动采集
|
||||
//vm.StopCollecting();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.Loaded += OnLoaded;
|
||||
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 保留原有滚动功能
|
||||
var vm = this.DataContext as PoreDistributionViewModel;
|
||||
if (vm != null)
|
||||
{
|
||||
vm.Record.DataPoints.CollectionChanged += DataPoints_CollectionChanged;
|
||||
}
|
||||
|
||||
// 获取主窗口 ViewModel
|
||||
_mainVM = Application.Current.MainWindow?.DataContext as MainViewModel;
|
||||
if (_mainVM == null) return;
|
||||
|
||||
// 为每个工位订阅 PropertyChanged,实时更新对应的 PlotView 模型
|
||||
for (int i = 0; i < _mainVM.Stations.Count; i++)
|
||||
{
|
||||
int stationId = i + 1;
|
||||
var stationVm = _mainVM.Stations[i].PoreDistributionVM;
|
||||
stationVm.PropertyChanged += (s, ev) =>
|
||||
{
|
||||
if (ev.PropertyName == nameof(PoreDistributionViewModel.PlotModel))
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
switch (stationId)
|
||||
{
|
||||
case 1: PlotViewStation1.Model = stationVm.PlotModel; break;
|
||||
case 2: PlotViewStation2.Model = stationVm.PlotModel; break;
|
||||
case 3: PlotViewStation3.Model = stationVm.PlotModel; break;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
// 初始化当前模型
|
||||
if (stationVm.PlotModel != null)
|
||||
{
|
||||
switch (stationId)
|
||||
{
|
||||
case 1: PlotViewStation1.Model = stationVm.PlotModel; break;
|
||||
case 2: PlotViewStation2.Model = stationVm.PlotModel; break;
|
||||
case 3: PlotViewStation3.Model = stationVm.PlotModel; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听当前 DataContext 变化,切换可见性
|
||||
this.DataContextChanged += (s, ev) => UpdateVisibility();
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
private void UpdateVisibility()
|
||||
{
|
||||
|
||||
if (this.DataContext is PoreDistributionViewModel vm)
|
||||
{
|
||||
PlotViewStation1.Visibility = vm.StationId == 1 ? Visibility.Visible : Visibility.Collapsed;
|
||||
PlotViewStation2.Visibility = vm.StationId == 2 ? Visibility.Visible : Visibility.Collapsed;
|
||||
PlotViewStation3.Visibility = vm.StationId == 3 ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e) { }
|
||||
|
||||
private void DataPoints_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
// 滚动湿膜表格到底部
|
||||
ScrollDataGridToEnd(dgWetData);
|
||||
// 滚动干膜表格到底部
|
||||
ScrollDataGridToEnd(dgDryData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user