2 Commits

Author SHA1 Message Date
ab49681acd 更改了曲线的时间字段的标注名称 2025-12-15 13:56:29 +08:00
45bba87b4e 历史曲线数据的多天的选择 2025-12-13 21:34:42 +08:00
5 changed files with 282 additions and 170 deletions

View File

@@ -1,4 +1,5 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using System.ComponentModel;
namespace CapMachine.Model namespace CapMachine.Model
{ {
@@ -49,5 +50,23 @@ namespace CapMachine.Model
/// </summary> /// </summary>
public long HistoryExpId { get; set; } public long HistoryExpId { get; set; }
public HistoryExp? HistoryExp { get; set; } public HistoryExp? HistoryExp { get; set; }
[Column(IsIgnore = true)]
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_isSelected = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
}
}
}
private bool _isSelected;
public event PropertyChangedEventHandler? PropertyChanged;
} }
} }

View File

@@ -20,9 +20,9 @@ namespace CapMachine.Wpf.Models
public string WorkDay { get; set; } public string WorkDay { get; set; }
/// <summary> /// <summary>
/// 时间 /// 时间信息
/// </summary> /// </summary>
[Name("时间")] [Name("时间信息")]
public string Time { get; set; } public string Time { get; set; }
/// <summary> /// <summary>

View File

@@ -16,7 +16,7 @@ namespace CapMachine.Wpf.Models
public CsvRecordModelMap() public CsvRecordModelMap()
{ {
Map(m => m.WorkDay).Name("日期"); Map(m => m.WorkDay).Name("日期");
Map(m => m.Time).Name("时间"); Map(m => m.Time).Name("时间信息");
Map(m => m.WorkCond).Name("工况"); Map(m => m.WorkCond).Name("工况");
Map(m => m.Speed).Name("转速[rpm]"); Map(m => m.Speed).Name("转速[rpm]");
Map(m => m.ExPress).Name("排气压力[BarA]"); Map(m => m.ExPress).Name("排气压力[BarA]");

View File

@@ -15,8 +15,8 @@ using Prism.Events;
using Prism.Regions; using Prism.Regions;
using Prism.Services.Dialogs; using Prism.Services.Dialogs;
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@@ -51,7 +51,7 @@ namespace CapMachine.Wpf.ViewModels
/// <param name="eventAggregator"></param> /// <param name="eventAggregator"></param>
/// <param name="mapper"></param> /// <param name="mapper"></param>
/// <param name="logger"></param> /// <param name="logger"></param>
public HistoryDataViewModel(IDialogService dialogService, IFreeSql freeSql, IEventAggregator eventAggregator, IMapper mapper,ConfigService configService) public HistoryDataViewModel(IDialogService dialogService, IFreeSql freeSql, IEventAggregator eventAggregator, IMapper mapper, ConfigService configService)
{ {
DialogService = dialogService; DialogService = dialogService;
FreeSql = freeSql; FreeSql = freeSql;
@@ -132,6 +132,20 @@ namespace CapMachine.Wpf.ViewModels
set { _IsLeftDrawerOpen = value; RaisePropertyChanged(); } set { _IsLeftDrawerOpen = value; RaisePropertyChanged(); }
} }
private bool _IsBusy;
public bool IsBusy
{
get { return _IsBusy; }
set { _IsBusy = value; RaisePropertyChanged(); }
}
private string _BusyMessage = "正在加载,请稍候...";
public string BusyMessage
{
get { return _BusyMessage; }
set { _BusyMessage = value; RaisePropertyChanged(); }
}
/// <summary> /// <summary>
@@ -224,15 +238,7 @@ namespace CapMachine.Wpf.ViewModels
set { _SelectedHistoryExp = value; RaisePropertyChanged(); } set { _SelectedHistoryExp = value; RaisePropertyChanged(); }
} }
private HistoryWorkCondFile _SelectedHistoryWorkCondFile;
/// <summary>
/// 选中的历史数据文件
/// </summary>
public HistoryWorkCondFile SelectedHistoryWorkCondFile
{
get { return _SelectedHistoryWorkCondFile; }
set { _SelectedHistoryWorkCondFile = value; RaisePropertyChanged(); }
}
/// <summary> /// <summary>
/// 当前搜索的工况条件 /// 当前搜索的工况条件
@@ -268,7 +274,13 @@ namespace CapMachine.Wpf.ViewModels
if (par is HistoryExp) if (par is HistoryExp)
{ {
SelectedHistoryExp = par as HistoryExp; SelectedHistoryExp = par as HistoryExp;
ListHistoryWorkCondFile = SelectedHistoryExp!.HistoryWorkCondFiles!; var files = SelectedHistoryExp!.HistoryWorkCondFiles!;
foreach (var f in files)
{
if (f != null) f.IsSelected = false;
}
ListHistoryWorkCondFile = files.ToList();
//ListHistoryWorkCondFile = ListHistoryWorkCondFile.ToList();
return; return;
} }
if ((par as SelectionChangedEventArgs)!.AddedItems.Count == 0) if ((par as SelectionChangedEventArgs)!.AddedItems.Count == 0)
@@ -290,63 +302,18 @@ namespace CapMachine.Wpf.ViewModels
if (Selecteddata != null) if (Selecteddata != null)
{ {
SelectedHistoryExp = Selecteddata; SelectedHistoryExp = Selecteddata;
ListHistoryWorkCondFile = SelectedHistoryExp.HistoryWorkCondFiles!; var files = SelectedHistoryExp.HistoryWorkCondFiles!;
} foreach (var f in files)
}
private DelegateCommand<object> _FileGridSelectionChangedCmd;
/// <summary>
/// 试验信息选中行数据命令
/// </summary>
public DelegateCommand<object> FileGridSelectionChangedCmd
{
set
{
_FileGridSelectionChangedCmd = value;
}
get
{
if (_FileGridSelectionChangedCmd == null)
{ {
_FileGridSelectionChangedCmd = new DelegateCommand<object>((par) => FileGridSelectionChangedCmdMethod(par)); if (f != null) f.IsSelected = false;
} }
return _FileGridSelectionChangedCmd; ListHistoryWorkCondFile = files;
ListHistoryWorkCondFile = ListHistoryWorkCondFile.ToList();
} }
} }
private void FileGridSelectionChangedCmdMethod(object par)
{
if (par == null)
{
return;
}
if (par is HistoryWorkCondFile)
{
SelectedHistoryWorkCondFile = par as HistoryWorkCondFile;
return;
}
if ((par as SelectionChangedEventArgs)!.AddedItems.Count == 0)
{
return;
}
//先判断是否是正确的集合数据防止DataGrid的数据源刷新导致的触发事件
var Selecteddata = (par as SelectionChangedEventArgs)!.AddedItems[0] as HistoryWorkCondFile;
////选中的行数据
//var Selecteddata = (par as DataGrid)!.SelectedItem as HistoryExp;
////选中的列数据
//var selectedColumn = (par as DataGrid)!.CurrentColumn;
//SelectedIndex= ProParsHelper.GetIndexByName(selectedColumn);
//SelectedProStepDto = par as ProStepDto;
if (Selecteddata != null)
{
SelectedHistoryWorkCondFile = Selecteddata;
}
}
private DelegateCommand _FilterHistoryDataFileCmd; private DelegateCommand _FilterHistoryDataFileCmd;
/// <summary> /// <summary>
@@ -397,6 +364,48 @@ namespace CapMachine.Wpf.ViewModels
HasHeaderRecord = false, HasHeaderRecord = false,
}; };
private DelegateCommand<object> _SelectAllFilesCmd;
public DelegateCommand<object> SelectAllFilesCmd
{
set
{
_SelectAllFilesCmd = value;
}
get
{
if (_SelectAllFilesCmd == null)
{
_SelectAllFilesCmd = new DelegateCommand<object>((par) => SelectAllFilesCmdMethod(par));
}
return _SelectAllFilesCmd;
}
}
private void SelectAllFilesCmdMethod(object par)
{
bool isChecked = false;
if (par is bool b) { isChecked = b; }
else
{
var nb = par as bool?;
if (nb.HasValue) isChecked = nb.Value;
else
{
var sb = par as string;
if (!string.IsNullOrWhiteSpace(sb))
{
bool.TryParse(sb, out isChecked);
}
}
}
if (ListHistoryWorkCondFile == null) return;
foreach (var f in ListHistoryWorkCondFile)
{
if (f != null) f.IsSelected = isChecked;
}
// 触发刷新
ListHistoryWorkCondFile = ListHistoryWorkCondFile.ToList();
}
Stopwatch stopwatch = new Stopwatch(); Stopwatch stopwatch = new Stopwatch();
private DelegateCommand _HistoryDataFileCmd; private DelegateCommand _HistoryDataFileCmd;
@@ -422,118 +431,134 @@ namespace CapMachine.Wpf.ViewModels
/// <summary> /// <summary>
/// 获取试验数据的命令的执行方法 /// 获取试验数据的命令的执行方法
/// </summary> /// </summary>
private void HistoryDataFileCmdMethod() private async void HistoryDataFileCmdMethod()
{ {
//SelectedHistoryWorkCondFile if (SelectedHistoryExp == null)
if (SelectedHistoryExp != null && SelectedHistoryWorkCondFile != null)
{
CsvRecordModels = new List<CsvRecordModel>();
////第一次计时
stopwatch.Start(); //启动Stopwatch
if (!string.IsNullOrEmpty(SelectedHistoryWorkCondFile.FilePath))
{
if (File.Exists(SelectedHistoryWorkCondFile.FilePath))//是否存在文件
{
lock (ConfigService.CsvFileLock)
{
using (var reader = new StreamReader(SelectedHistoryWorkCondFile.FilePath))
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
{
csv.Context.RegisterClassMap<CsvRecordModelMap>();
//GetRecords<CsvRecordModel>().ToList();
CsvRecordModels.AddRange(csv.GetRecords<CsvRecordModel>().ToList());
}
}
}
else
{
System.Windows.MessageBox.Show("没有发现地址对应的文件");
}
}
else
{
System.Windows.MessageBox.Show("发现空的文件地址");
}
//数据加载完毕后进入到Chart曲线中
if (CsvRecordModels.Count > 0)
{
EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
}
stopwatch.Stop(); //停止Stopwatch
Console.WriteLine("加载CSV数据耗时:{0}", stopwatch.Elapsed.TotalSeconds.ToString());
stopwatch.Reset();
IsLeftDrawerOpen = false;
}
else
{ {
System.Windows.MessageBox.Show("请选中后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); System.Windows.MessageBox.Show("请选中后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
return;
} }
var files = new List<HistoryWorkCondFile>();
if (ListHistoryWorkCondFile != null)
{
foreach (var f in ListHistoryWorkCondFile)
{
if (f != null && f.IsSelected)
{
files.Add(f);
}
}
}
#region files = files
//整个试验工况一起加载数据 .Where(f => f != null)
//if (SelectedHistoryExp != null && SelectedHistoryExp.HistoryWorkCondFiles != null) .GroupBy(f => string.IsNullOrWhiteSpace(f.FilePath) ? $"ID:{f.Id}" : f.FilePath)
//{ .Select(g => g.First())
// CsvRecordModels = new List<CsvRecordModel>(); .ToList();
// ////第一次计时 if (files.Count == 0)
// stopwatch.Start(); //启动Stopwatch {
System.Windows.MessageBox.Show("请先在右侧勾选至少一个CSV文件", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// foreach (var item in SelectedHistoryExp.HistoryWorkCondFiles) BusyMessage = "正在加载CSV数据请稍候...";
// { IsBusy = true;
// if (!string.IsNullOrEmpty(item.FilePath))
// {
// if (File.Exists(item.FilePath))//是否存在文件
// {
// lock (ConfigService.CsvFileLock)
// {
// using (var reader = new StreamReader(item.FilePath))
// using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
// {
// csv.Context.RegisterClassMap<CsvRecordModelMap>();
// //GetRecords<CsvRecordModel>().ToList();
// CsvRecordModels.AddRange(csv.GetRecords<CsvRecordModel>().ToList()); var loaded = new List<CsvRecordModel>();
// } string errorText = string.Empty;
// }
// } stopwatch.Start();
// else
// {
// System.Windows.MessageBox.Show("没有发现地址对应的文件");
// }
// }
// else
// {
// System.Windows.MessageBox.Show("发现空的文件地址");
// }
// }
// //数据加载完毕后进入到Chart曲线中 try
// if (CsvRecordModels.Count > 0) {
// { await Task.Run(() =>
// EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels }); {
// } var errors = new StringBuilder();
for (int i = 0; i < files.Count; i++)
{
var f = files[i];
try
{
Application.Current.Dispatcher.Invoke(() =>
{
BusyMessage = $"正在加载({i + 1}/{files.Count}){System.IO.Path.GetFileName(f?.FilePath)}";
});
// stopwatch.Stop(); //停止Stopwatch if (f == null) continue;
// Console.WriteLine("加载CSV数据耗时:{0}", stopwatch.Elapsed.TotalSeconds.ToString()); if (string.IsNullOrWhiteSpace(f.FilePath))
// stopwatch.Reset(); {
errors.AppendLine("发现空的文件地址");
continue;
}
if (!File.Exists(f.FilePath))
{
errors.AppendLine($"没有发现地址对应的文件: {f.FilePath}");
continue;
}
// IsLeftDrawerOpen = false; var rec = ReadCsvFile(f.FilePath);
//} if (rec != null && rec.Count > 0)
//else {
//{ loaded.AddRange(rec);
// System.Windows.MessageBox.Show("请选中后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); }
//} }
catch (Exception ex)
{
errors.AppendLine($"读取CSV失败: {ex.Message}");
}
}
errorText = errors.ToString();
});
#endregion if (!string.IsNullOrWhiteSpace(errorText))
{
System.Windows.MessageBox.Show(errorText, "读取提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
CsvRecordModels = new List<CsvRecordModel>();
if (loaded != null && loaded.Count > 0)
{
CsvRecordModels = loaded
.Where(r => r != null)
.OrderBy(r => r.CreateTime)
.ToList();
Application.Current.Dispatcher.Invoke(() =>
{
EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
});
}
}
finally
{
stopwatch.Stop();
Console.WriteLine("加载CSV数据耗时:{0}", stopwatch.Elapsed.TotalSeconds.ToString());
stopwatch.Reset();
IsBusy = false;
IsLeftDrawerOpen = false;
}
}
private List<CsvRecordModel> ReadCsvFile(string filePath)
{
var result = new List<CsvRecordModel>();
lock (ConfigService.CsvFileLock)
{
using (var reader = new StreamReader(filePath, Encoding.UTF8))
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
{
csv.Context.RegisterClassMap<CsvRecordModelMap>();
var list = csv.GetRecords<CsvRecordModel>().ToList();
if (list != null && list.Count > 0)
{
// 过滤无效时间,避免排序异常
result = list.Where(r => r != null && r.CreateTime != default && r.CreateTime != DateTime.MinValue).ToList();
}
}
}
return result;
} }
@@ -1075,7 +1100,7 @@ namespace CapMachine.Wpf.ViewModels
SeletedGroup6ListViewTabIndex = 0; SeletedGroup6ListViewTabIndex = 0;
SeletedGroup7ListViewTabIndex = 0; SeletedGroup7ListViewTabIndex = 0;
SeletedGroup8ListViewTabIndex = 0; SeletedGroup8ListViewTabIndex = 0;
} }
else else
{ {

View File

@@ -26,6 +26,7 @@
<Setter Property="BorderThickness" Value="0" /> <Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" /> <Setter Property="BorderBrush" Value="Transparent" />
</Style> </Style>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</UserControl.Resources> </UserControl.Resources>
<materialDesign:DrawerHost <materialDesign:DrawerHost
x:Name="HistoryDrawerHost" x:Name="HistoryDrawerHost"
@@ -265,28 +266,95 @@
AutoGenerateColumns="False" AutoGenerateColumns="False"
BorderBrush="Black" BorderBrush="Black"
BorderThickness="1" BorderThickness="1"
CanUserAddRows="False"
FontWeight="Bold" FontWeight="Bold"
IsReadOnly="True" IsReadOnly="True"
ItemsSource="{Binding ListHistoryWorkCondFile}" ItemsSource="{Binding ListHistoryWorkCondFile}"
SelectionMode="Extended" SelectionMode="Single"
SelectionUnit="FullRow"> SelectionUnit="FullRow">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn MinWidth="300" Binding="{Binding WorkDay}"> <DataGridTemplateColumn Width="80">
<DataGridTemplateColumn.Header>
<CheckBox
x:Name="HeaderSelectAll"
Content="全选"
DataContext="{Binding DataContext, ElementName=DetailDatagrid}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<prism:InvokeCommandAction Command="{Binding SelectAllFilesCmd}" CommandParameter="True" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<prism:InvokeCommandAction Command="{Binding SelectAllFilesCmd}" CommandParameter="False" />
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox
HorizontalAlignment="Center"
VerticalAlignment="Center"
Focusable="False"
IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsThreeState="False" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<CheckBox
HorizontalAlignment="Center"
VerticalAlignment="Center"
Focusable="False"
IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsThreeState="False" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
MinWidth="200"
Binding="{Binding WorkDay}"
IsReadOnly="True">
<DataGridTextColumn.Header> <DataGridTextColumn.Header>
<TextBlock FontWeight="Bold" Text="文件名称/日期" /> <TextBlock FontWeight="Bold" Text="文件名称/日期" />
</DataGridTextColumn.Header> </DataGridTextColumn.Header>
</DataGridTextColumn> </DataGridTextColumn>
</DataGrid.Columns> </DataGrid.Columns>
<!-- CommandParameter="{Binding ElementName=MainDatagrid, Path=SelectedItem}" --> <!-- CommandParameter="{Binding ElementName=MainDatagrid, Path=SelectedItem}" -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<prism:InvokeCommandAction Command="{Binding FileGridSelectionChangedCmd}" CommandParameter="{Binding ElementName=DetailDatagrid, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid> </DataGrid>
<!-- 忙碌遮罩 -->
<Grid
x:Name="BusyOverlay"
Grid.Row="1"
Panel.ZIndex="999"
Background="#66000000"
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibilityConverter}}">
<Border
Padding="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="White"
CornerRadius="6">
<StackPanel>
<ProgressBar
Width="220"
Height="6"
IsIndeterminate="True" />
<TextBlock
Margin="0,10,0,0"
HorizontalAlignment="Center"
FontSize="14"
Foreground="Black"
Text="{Binding BusyMessage}" />
</StackPanel>
</Border>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>