From 4c3eb7f334abb8129b57e86f2935d75d0b3070b4 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期一, 03 三月 2025 18:55:31 +0800
Subject: [PATCH] 完善UI;新增TestResult;
---
HMI.ParameterManage/ProductModal.xaml.cs | 91
HMI.SettingControl/SettingControl.xaml.cs | 72
HMI.ParameterManage/ParameterManage.xaml.cs | 113
HMI.IOMonitor/IPManageModal.xaml.cs | 1
Plugin.TestResult/Model/CellInfo.cs | 9
Plugin.TestResult/Resource/ready.png | 0
Plugin.TestResult/SingleCell.xaml | 101 +
HMI.LogViewer/LogViewer.xaml | 126 +
Plugin.TestResult/DataTable.xaml | 84
HMI.DataViewer/DataViewer.xaml | 31
Plugin.TestResult/Resource/checkInFailed2.png | 0
Plugin.TestResult/TestResultView.xaml.cs | 383 ++++
HMI.ParameterManage/Entity/ParameterData.cs | 8
Plugin.TestResult/Model/TcpServer.cs | 41
HMI.ParameterManage/Model/SqlModel.cs | 32
Plugin.TestResult/Properties/Resources.Designer.cs | 62
HMI.ParameterManage/HMI.ParameterManage.csproj | 3
Plugin.TestResult/Chart.xaml.cs | 314 +++
HMI.IOMonitor/IOMonitor.xaml | 12
WPFProject/LoadingWindow.xaml.cs | 7
Plugin.TestResult/InfoTable.xaml.cs | 153 +
HMI.ParameterManage/ParameterModal.xaml | 9
Plugin.TestResult/Chart.xaml | 14
HMI.LogViewer/Properties/Resources.Designer.cs | 62
Plugin.TestResult/Properties/Settings.settings | 7
HMI.ParameterManage/ParameterManage.xaml | 82
Plugin.TestResult/Model/DataTableModel.cs | 7
HMI.Core/Api/IConfigManager.cs | 17
Plugin.TestResult/Util/CommonCodeParser.cs | 27
Plugin.TestResult/ViewControl.xaml.cs | 288 +++
HMI.LogViewer/HMI.LogViewer.csproj | 132 +
HMI.DataViewer/DataViewer.xaml.cs | 59
Plugin.TestResult/TestResultView.xaml | 16
HMI.DataViewer/DbSettingModal.xaml.cs | 2
Plugin.TestResult/Model/Info.cs | 60
Plugin.TestResult/Resource/testing2.png | 0
HMI.LogViewer/Properties/AssemblyInfo.cs | 52
Plugin.TestResult/OpenTK.dll.config | 25
HMI.UI/Util/ToastHelper.cs | 5
HMI.UI/DpUtil/DataGridHelper.cs | 20
Plugin.TestResult/Properties/Settings.Designer.cs | 30
Plugin.TestResult/Scanner.xaml | 54
HMI.ParameterManage/Model/XmlModel.cs | 210 ++
Plugin.TestResult/Scanner.xaml.cs | 216 ++
HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml | 2
HMI.LogViewer/Properties/Resources.resx | 117 +
HMI.LogViewer/packages.config | 6
HMI.ParameterManage/ProductModal.xaml | 8
Plugin.TestResult/Model/BaseConfig.cs | 157 +
Plugin.TestResult/ChartWindow.xaml | 13
HMI.Core/HMI.Core.csproj | 1
HMI.UI/Style/FormStyle.xaml | 4
Plugin.TestResult/InfoTable.xaml | 81
WPFProject/WPFProject.csproj | 8
HMI.UI/Style/PanuonResource.xaml | 23
Plugin.TestResult/Model/BaseModel.cs | 21
HMI.DataViewer/DbSettingModal.xaml | 6
Plugin.TestResult/Properties/Resources.resx | 117 +
WPFProject/WPFProject.sln | 20
Plugin.TestResult/Resource/ng2.png | 0
HMI.LogViewer/Properties/Settings.settings | 7
Plugin.TestResult/Resource/checkIn.png | 0
Plugin.TestResult/Util/FontSizeConverter.cs | 33
Plugin.TestResult/Plugin.TestResult.csproj | 313 +++
Plugin.TestResult/Resource/waiting2.png | 0
HMI.ParameterManage/ParameterModal.xaml.cs | 66
Plugin.TestResult/InfoWindow.xaml | 25
Plugin.TestResult/Resource/alert.png | 0
HMI.UI/DpUtil/FormGroupHelper.cs | 7
HMI.LogViewer/Properties/Settings.Designer.cs | 30
HMI.SettingControl/SystemConfig.xaml.cs | 26
Plugin.TestResult/Util/DpUtil.cs | 232 ++
HMI.LogViewer/LogViewer.xaml.cs | 210 ++
HMI.IOMonitor/IPManageModal.xaml | 5
Plugin.TestResult/Properties/AssemblyInfo.cs | 53
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs | 2
Plugin.TestResult/Resource/ok2.png | 0
HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml.cs | 16
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml | 9
HMI.ParameterManage/Entity/ProductData.cs | 6
Plugin.TestResult/Resource/barcode.png | 0
Plugin.TestResult/Constant/CommonConstant.cs | 70
Plugin.TestResult/packages.config | 25
HMI.IOMonitor/IOMonitor.xaml.cs | 10
HMI.SettingControl/SystemConfig.xaml | 4
HMI.SettingControl/SettingControl.xaml | 38
Plugin.TestResult/InfoWindow.xaml.cs | 58
Plugin.TestResult/SingleCell.xaml.cs | 195 ++
Plugin.TestResult/ViewControl.xaml | 161 +
Plugin.TestResult/ChartWindow.xaml.cs | 45
Plugin.TestResult/DataTable.xaml.cs | 285 +++
HMI.UI/HMI.UI.csproj | 1
92 files changed, 5,253 insertions(+), 300 deletions(-)
diff --git a/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml b/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml
index 611a9c1..b6c507b 100644
--- a/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml
+++ b/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml
@@ -22,8 +22,6 @@
</pu:FormGroup>
</StackPanel>
</GroupBox>
-
- <Button Click="Button_Click">淇濆瓨</Button>
</StackPanel>
</Grid>
</UserControl>
diff --git a/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml.cs b/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml.cs
index 0baf7dd..1e0296a 100644
--- a/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml.cs
+++ b/HMI.AlermInfoManage/AlarmInfoManage_Setting.xaml.cs
@@ -1,4 +1,5 @@
锘縰sing HMI.AlarmInfoManage.Entity;
+using HMI.Core.Api;
using HMI.Core.Util;
using System.Windows;
using System.Windows.Controls;
@@ -8,7 +9,7 @@
/// <summary>
/// AlarmInfoManage_Setting.xaml 鐨勪氦浜掗�昏緫
/// </summary>
- public partial class AlarmInfoManage_Setting : UserControl
+ public partial class AlarmInfoManage_Setting : UserControl, IConfigManager
{
public AlarmInfoManage_Setting()
{
@@ -17,17 +18,26 @@
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
- DataContext = AimSetting.Instance.GetModel();
+ ResetConfig();
}
- private void Button_Click(object sender, RoutedEventArgs e)
+ public object GetConfig()
+ {
+ return AimSetting.Instance;
+ }
+
+ public void SaveConfig()
{
AimSettingModel model = (AimSettingModel)DataContext;
AimSetting newSetting = AimSetting.FromModel(model);
XmlHelper.SerializeToXml(PathHelper.ConfigFolder + "\\AimSetting.xml", model);
+ }
+ public void ResetConfig()
+ {
+ DataContext = AimSetting.Instance.GetModel();
}
}
}
diff --git a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
index 36941a7..6edad5f 100644
--- a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
+++ b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
@@ -8,6 +8,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
mc:Ignorable="d"
Title="Form"
SizeToContent="Height"
@@ -26,19 +27,19 @@
pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
<Grid Margin="10">
<StackPanel x:Name="formPanel">
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True"
- ui:FormGroupHelper.ValidateMethod="ValidateDBAddress"
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateDBAddress"
Header="DB鍦板潃" GroupName="MyFormGroup">
<pu:NumberInput Style="{StaticResource FormNumberInput}"
x:Name="dbAddress" Interval="1"/>
</pu:FormGroup>
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True"
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
Header="璧峰鍦板潃" GroupName="MyFormGroup">
<pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="startAddress" Interval="1"/>
</pu:FormGroup>
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True"
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
Header="闀垮害" GroupName="MyFormGroup">
<pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="length" Interval="1"/>
</pu:FormGroup>
diff --git a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
index 57ac994..f3f7f92 100644
--- a/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
+++ b/HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
@@ -1,6 +1,6 @@
锘縰sing HMI.AlarmInfoManage.Entity;
using HMI.Core.Util;
-using HMI.UI;
+using HMI.UI.DpUtil;
using HMI.UI.Util;
using log4net;
using Panuon.WPF.UI;
diff --git a/HMI.Core/Api/IConfigManager.cs b/HMI.Core/Api/IConfigManager.cs
new file mode 100644
index 0000000..4415b4c
--- /dev/null
+++ b/HMI.Core/Api/IConfigManager.cs
@@ -0,0 +1,17 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HMI.Core.Api
+{
+ public interface IConfigManager
+ {
+ object GetConfig();
+
+ void SaveConfig();
+
+ void ResetConfig();
+ }
+}
diff --git a/HMI.Core/HMI.Core.csproj b/HMI.Core/HMI.Core.csproj
index 3f23aae..caa4430 100644
--- a/HMI.Core/HMI.Core.csproj
+++ b/HMI.Core/HMI.Core.csproj
@@ -80,6 +80,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Api\IConfigManager.cs" />
<Compile Include="Api\IConfigRefresh.cs" />
<Compile Include="Api\IFolderOwner.cs" />
<Compile Include="Api\IPlugin.cs" />
diff --git a/HMI.DataViewer/DataViewer.xaml b/HMI.DataViewer/DataViewer.xaml
index 6e97d35..1b37283 100644
--- a/HMI.DataViewer/DataViewer.xaml
+++ b/HMI.DataViewer/DataViewer.xaml
@@ -55,10 +55,10 @@
</Grid>-->
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Left" Style="{StaticResource ButtonGroup}">
- <TextBlock Style="{StaticResource TitleBox}" Text="寮�濮嬫椂闂�"/>
- <pu:DateTimePicker Width="190" Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="startTimeInput"/>
- <TextBlock Style="{StaticResource TitleBox}" Text="缁撴潫鏃堕棿"/>
- <pu:DateTimePicker Width="190" Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="endTimeInput"/>
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="寮�濮嬫椂闂�"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="startTimeInput"/>
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="缁撴潫鏃堕棿"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{x:Null}" x:Name="endTimeInput"/>
<Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon=""
x:Name="srhBtn" Click="Button_Click">鏌ヨ</Button>
@@ -66,9 +66,9 @@
<Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon=""
x:Name="resetBtn" Click="Button_Click">閲嶇疆</Button>
- <Menu x:Name="anyBtn" >
+ <Menu x:Name="anyBtn" Style="{StaticResource CommonMenu}">
<MenuItem Header="鍒嗘瀽">
- <MenuItem Header="CPK" />
+ <MenuItem Header="CPK" Click="MenuItem_Click"/>
<MenuItem Header="RandR" />
</MenuItem>
</Menu>
@@ -77,8 +77,9 @@
<DockPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="0,10,0,0">
<pu:Drawer DockPanel.Dock="Left" x:Name="DrwMenu" MinWidth="34" MaxWidth="400"
+ Padding="0"
ShadowColor="{x:Null}"
- AnimationDuration="0" BorderThickness="2,2,0,2" BorderBrush="{StaticResource CommonBoarder}">
+ AnimationDuration="0" BorderThickness="2,0,0,2" BorderBrush="{StaticResource CommonBoarder}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
@@ -90,7 +91,7 @@
</Grid.ColumnDefinitions>
<DockPanel Grid.ColumnSpan="2" Background="{StaticResource CommonBoarder}">
- <ToggleButton Grid.Column="1" x:Name="drawerBtn" BorderThickness="0"
+ <ToggleButton x:Name="drawerBtn" BorderThickness="0"
DockPanel.Dock="Right"
Background="Transparent"
Width="34" Height="34" HorizontalAlignment="Right"
@@ -98,7 +99,7 @@
FontFamily="{StaticResource iconfont}"
Content="" IsChecked="{Binding IsOpen, ElementName=DrwMenu, Mode=TwoWay}">
<ToggleButton.Style>
- <Style TargetType="ToggleButton">
+ <Style TargetType="ToggleButton" BasedOn="{StaticResource CommonToggle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="False">
<Setter Property="RenderTransform">
@@ -122,7 +123,7 @@
</Style>
</ToggleButton.Style>
</ToggleButton>
-
+
<TextBlock Text="楂樼骇鏌ヨ" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DockPanel>
@@ -140,9 +141,10 @@
<Label Content="閫夋嫨鏌ヨ椤圭洰"/>
<ComboBox Grid.Column="1" x:Name="programInput" SelectionChanged="programInput_SelectionChanged"/>
</DockPanel>
-
+
<DataGrid Margin="10" Grid.Row="1" Grid.ColumnSpan="2" Style="{StaticResource DefaultDataGrid}"
IsReadOnly="False"
+ SelectionMode="Single"
BorderThickness="0"
ItemsSource="{Binding Datas}">
<DataGrid.Columns>
@@ -216,7 +218,12 @@
</Grid>
</pu:Drawer>
- <DataGrid BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}" x:Name="dataTable" Style="{StaticResource DefaultDataGrid}">
+ <DataGrid BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}" x:Name="dataTable"
+ Style="{StaticResource DefaultDataGrid}"
+ SelectionUnit="CellOrRowHeader"
+ SelectionMode="Extended"
+ pu:DataGridHelper.CellSelectedBackground="{StaticResource PrimaryColor}"
+ PreviewMouseLeftButtonDown="dataTable_PreviewMouseLeftButtonDown">
<DataGrid.Columns>
<DataGridTemplateColumn Header="#" IsReadOnly="True" CanUserResize="False">
<DataGridTemplateColumn.CellTemplate>
diff --git a/HMI.DataViewer/DataViewer.xaml.cs b/HMI.DataViewer/DataViewer.xaml.cs
index 0b7ca90..6c3ac20 100644
--- a/HMI.DataViewer/DataViewer.xaml.cs
+++ b/HMI.DataViewer/DataViewer.xaml.cs
@@ -2,6 +2,7 @@
using HMI.Core.Util;
using HMI.DataViewer.Entity;
using HMI.UI.Util;
+using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -10,7 +11,9 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
using System.Windows.Data;
+using System.Windows.Media;
namespace HMI.DataViewer
{
@@ -97,7 +100,7 @@
}
DataBase_Setting setting = Map[program];
-
+
string fields = string.Join(",", Datas?.Select(d => $"[{d.Key}]").ToList());
@@ -116,7 +119,7 @@
conditon += $" AND {timeCol} < '{endTimeInput.Text}'";
}
conditon = string.IsNullOrEmpty(conditon) ? string.Empty : $" WHERE {conditon}";
-
+
SqliteHelper helper = null;
string sql = string.Empty;
try
@@ -124,14 +127,13 @@
helper = new SqliteHelper(setting.DBFilePath);
sql = $"SELECT {fields} FROM {setting.TableName} {conditon}";
DataTable dt = helper.GetDataTable(sql);
-
+ HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
dataTable.ItemsSource = dt.DefaultView;
}
catch (Exception ex)
{
log.Error($"Select Data Failed. SQL: {sql}", ex);
ToastHelper.Error(Window.GetWindow(this), $"鏌ヨ澶辫触锛亄ex.Message}");
-
}
finally
{
@@ -191,6 +193,7 @@
setting?.Condition?.Select(d => new QueryData { Key = d.Key, Name = d.Desc, Condition = "=" }).ToList());
var temp = dataTable.Columns[0];
+ HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
dataTable.Columns.Clear();
dataTable.Columns.Add(temp);
foreach (var data in Datas)
@@ -204,11 +207,55 @@
DataGridTextColumn textColumn = new DataGridTextColumn
{
Header = header,
- Binding = new Binding(bindingPath)
- ,
+ Binding = new Binding(bindingPath),
Width = new DataGridLength(1, DataGridLengthUnitType.Star)
};
dataTable.Columns.Add(textColumn);
}
+
+ private void dataTable_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ // 鑾峰彇鐐瑰嚮鐨勫厓绱�
+ DependencyObject dep = (DependencyObject)e.OriginalSource;
+
+ // 閬嶅巻鎵惧埌 DataGridColumnHeader
+ while (dep != null && !(dep is DataGridColumnHeader) && !(dep is DataGridRow))
+ {
+ dep = VisualTreeHelper.GetParent(dep);
+ }
+ HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
+
+ if (dep is DataGridColumnHeader columnHeader)
+ {
+ // 鑾峰彇鍒楃储寮�
+ int columnIndex = columnHeader.Column.DisplayIndex;
+
+ // 娓呴櫎宸叉湁閫夋嫨
+ dataTable.SelectedCells.Clear();
+
+ // 閬嶅巻鎵�鏈夎锛岄�変腑璇ュ垪鐨勬墍鏈夊崟鍏冩牸
+ foreach (var item in dataTable.Items)
+ {
+ DataGridCellInfo cellInfo = new DataGridCellInfo(item, columnHeader.Column);
+ dataTable.SelectedCells.Add(cellInfo);
+ }
+ HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, columnHeader.Column);
+
+ e.Handled = true; // 闃叉榛樿琛屼负
+ }
+ else if (dep is DataGridRow row)
+ {
+ // 娓呴櫎宸叉湁閫夋嫨
+ dataTable.SelectedCells.Clear();
+ dataTable.SelectedItem = row.Item;
+ e.Handled = true;
+ }
+ }
+
+ private void MenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ DataGridColumn column = HMI.UI.DpUtil.DataGridHelper.GetSelectedColumn(dataTable);
+
+ }
}
}
diff --git a/HMI.DataViewer/DbSettingModal.xaml b/HMI.DataViewer/DbSettingModal.xaml
index b91d95f..ded1c50 100644
--- a/HMI.DataViewer/DbSettingModal.xaml
+++ b/HMI.DataViewer/DbSettingModal.xaml
@@ -27,11 +27,11 @@
pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
<Grid Margin="10">
<StackPanel x:Name="formPanel">
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True" Header="鍚嶇О" GroupName="MyFormGroup">
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="鍚嶇О" GroupName="MyFormGroup">
<TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="programInput"/>
</pu:FormGroup>
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True" Header="鏁版嵁鏂囦欢" GroupName="MyFormGroup">
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="鏁版嵁鏂囦欢" GroupName="MyFormGroup">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
@@ -42,7 +42,7 @@
</Grid>
</pu:FormGroup>
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True" Header="鏁版嵁琛�" GroupName="MyFormGroup">
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="鏁版嵁琛�" GroupName="MyFormGroup">
<ComboBox Style="{StaticResource FormComboxStyle}" SelectedValuePath="Content"
x:Name="tableNameInput" SelectionChanged="ComboxSelectionChanged"/>
</pu:FormGroup>
diff --git a/HMI.DataViewer/DbSettingModal.xaml.cs b/HMI.DataViewer/DbSettingModal.xaml.cs
index 31bf8f0..2902aad 100644
--- a/HMI.DataViewer/DbSettingModal.xaml.cs
+++ b/HMI.DataViewer/DbSettingModal.xaml.cs
@@ -1,6 +1,6 @@
锘縰sing HMI.Core.Util;
using HMI.DataViewer.Entity;
-using HMI.UI;
+using HMI.UI.DpUtil;
using HMI.UI.Util;
using log4net;
using Microsoft.Win32;
diff --git a/HMI.IOMonitor/IOMonitor.xaml b/HMI.IOMonitor/IOMonitor.xaml
index 3cd6837..8e1cf0f 100644
--- a/HMI.IOMonitor/IOMonitor.xaml
+++ b/HMI.IOMonitor/IOMonitor.xaml
@@ -62,7 +62,7 @@
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="DI鍚嶇О"
- FontSize="{StaticResource TitleFontSize}"/>
+ FontSize="{StaticResource ContentFontSize}"/>
<ComboBox Grid.Row="0" Grid.Column="1" x:Name="diName"
IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
@@ -73,13 +73,13 @@
x:Name="diReset" Click="Button_Click">DI閲嶇疆</Button>
<Label Grid.Row="1" Grid.Column="0" Content="DI缂栧彿"
- FontSize="{StaticResource TitleFontSize}"/>
+ FontSize="{StaticResource ContentFontSize}"/>
<ComboBox Grid.Row="1" Grid.Column="1" x:Name="diCode"
IsEditable="True"
Style="{StaticResource FormComboxStyle}"/>
<Label Grid.Row="2" Grid.Column="0" Content="DI鍒嗙粍"
- FontSize="{StaticResource TitleFontSize}"/>
+ FontSize="{StaticResource ContentFontSize}"/>
<ComboBox Grid.Row="2" Grid.Column="1" x:Name="diGroup"
IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
@@ -154,7 +154,7 @@
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="DO鍚嶇О"
- FontSize="{StaticResource TitleFontSize}"/>
+ FontSize="{StaticResource ContentFontSize}"/>
<ComboBox Grid.Row="0" Grid.Column="1" x:Name="doName"
IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
@@ -165,12 +165,12 @@
>DO閲嶇疆</Button>
<Label Grid.Row="1" Grid.Column="0" Content="DO缂栧彿"
- FontSize="{StaticResource TitleFontSize}"/>
+ FontSize="{StaticResource ContentFontSize}"/>
<ComboBox Grid.Row="1" Grid.Column="1" x:Name="doCode"
IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
<Label Grid.Row="2" Grid.Column="0" Content="DO鍒嗙粍"
- FontSize="{StaticResource TitleFontSize}"/>
+ FontSize="{StaticResource ContentFontSize}"/>
<ComboBox Grid.Row="2" Grid.Column="1" x:Name="doGroup"
IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
diff --git a/HMI.IOMonitor/IOMonitor.xaml.cs b/HMI.IOMonitor/IOMonitor.xaml.cs
index 99394ff..da9de42 100644
--- a/HMI.IOMonitor/IOMonitor.xaml.cs
+++ b/HMI.IOMonitor/IOMonitor.xaml.cs
@@ -48,20 +48,14 @@
/// <summary>The dis
/// DI鍙e璞�
/// </summary>
- private ObservableCollection<DIO> _dis = new ObservableCollection<DIO>() {
- new DIO(null,null,null,false),
- new DIO(null,null,null,true),
- };
+ private ObservableCollection<DIO> _dis = new ObservableCollection<DIO>();
public ObservableCollection<DIO> Dis
{
get => _dis;
set { Set(ref _dis, value); }
}
- private ObservableCollection<DIO> _dos = new ObservableCollection<DIO>() {
- new DIO(null,null,null,false),
- new DIO(null,null,null,true),
- };
+ private ObservableCollection<DIO> _dos = new ObservableCollection<DIO>();
public ObservableCollection<DIO> Dos
{
get => _dos;
diff --git a/HMI.IOMonitor/IPManageModal.xaml b/HMI.IOMonitor/IPManageModal.xaml
index 963a325..1b98673 100644
--- a/HMI.IOMonitor/IPManageModal.xaml
+++ b/HMI.IOMonitor/IPManageModal.xaml
@@ -8,6 +8,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
mc:Ignorable="d"
Title="Form"
SizeToContent="Height"
@@ -26,12 +27,12 @@
pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
<Grid Margin="10">
<StackPanel x:Name="formPanel">
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True"
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
Header="I鐐硅鍙栨爣绛�" GroupName="MyFormGroup">
<TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="iTag"/>
</pu:FormGroup>
- <pu:FormGroup ui:FormGroupHelper.IsRequired="True"
+ <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
Header="Q鐐硅鍙栨爣绛�" GroupName="MyFormGroup">
<TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="qTag"/>
</pu:FormGroup>
diff --git a/HMI.IOMonitor/IPManageModal.xaml.cs b/HMI.IOMonitor/IPManageModal.xaml.cs
index fbec583..eb443e9 100644
--- a/HMI.IOMonitor/IPManageModal.xaml.cs
+++ b/HMI.IOMonitor/IPManageModal.xaml.cs
@@ -1,6 +1,7 @@
锘縰sing HMI.Core.Util;
using HMI.IOMonitor.Entity;
using HMI.UI;
+using HMI.UI.DpUtil;
using HMI.UI.Util;
using log4net;
using Panuon.WPF.UI;
diff --git a/HMI.LogViewer/HMI.LogViewer.csproj b/HMI.LogViewer/HMI.LogViewer.csproj
new file mode 100644
index 0000000..09b77b7
--- /dev/null
+++ b/HMI.LogViewer/HMI.LogViewer.csproj
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{20C23602-B029-4E21-8C11-B9E5F2223237}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <RootNamespace>HMI.LogViewer</RootNamespace>
+ <AssemblyName>HMI.LogViewer</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <LangVersion>7.3</LangVersion>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <LangVersion>7.3</LangVersion>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
+ </Reference>
+ <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="LogViewer.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Compile Include="LogViewer.xaml.cs">
+ <DependentUpon>LogViewer.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj">
+ <Project>{2a6f9720-a890-4036-9d73-41a0dae28341}</Project>
+ <Name>HMI.Base</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj">
+ <Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project>
+ <Name>HMI.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj">
+ <Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project>
+ <Name>HMI.UI</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
+copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/HMI.LogViewer/LogViewer.xaml b/HMI.LogViewer/LogViewer.xaml
new file mode 100644
index 0000000..8fc848c
--- /dev/null
+++ b/HMI.LogViewer/LogViewer.xaml
@@ -0,0 +1,126 @@
+锘�<hb:PluginControl x:Class="HMI.LogViewer.LogViewer"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:local="clr-namespace:HMI.LogViewer"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ mc:Ignorable="d"
+ Loaded="UserControl_Loaded"
+ Background="{StaticResource WorkspaceBackground}"
+ d:DesignHeight="450" d:DesignWidth="800">
+
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/FormStyle.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
+ <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ <uic:PathImageConverter x:Key="path2Image"/>
+ <uic:DataGridRowNumberConverter x:Key="rowNumber"/>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <Border Style="{StaticResource CardBoarder}">
+
+
+ <Grid dp:GridHelper.Space="10" Cursor="">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <TextBlock FontSize="{StaticResource TitleFontSize}"
+VerticalAlignment="Center" HorizontalAlignment="Left" Text="鏃ュ織鏌ヨ"/>
+
+ <DockPanel Grid.Row="1" Cursor="">
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon=""
+ x:Name="queryBtn" Click="Button_Click">鏌ヨ</Button>
+ <Button Style="{StaticResource PrimaryButton}" pu:ButtonHelper.Icon=""
+ x:Name="resetBtn" Click="Button_Click" Cursor="Hand">閲嶇疆</Button>
+ <Button x:Name="exportBtn"
+ Style="{StaticResource PrimaryButton}" Click="Button_Click">瀵煎嚭</Button>
+ </StackPanel>
+
+ <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left">
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="绾у埆"/>
+ <ComboBox Style="{StaticResource FormComboxStyle}" x:Name="levelInput"
+ Width="180"
+ SelectedValuePath="Content">
+ <ComboBoxItem Content="info"/>
+ <ComboBoxItem Content="warn"/>
+ <ComboBoxItem Content="error"/>
+ </ComboBox>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="寮�濮嬫椂闂�"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="startTimeInput"/>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="缁撴潫鏃堕棿"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="endTimeInput"/>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="鏉ユ簮"/>
+ <!--<ComboBox Style="{StaticResource FormComboxStyle}" x:Name="sourceInput" Width="180"></ComboBox>-->
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="sourceInput" Width="180"/>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="瀹炴椂鍒锋柊"/>
+ <CheckBox x:Name="autoRfhInput" HorizontalAlignment="Center" VerticalAlignment="Center"
+ IsChecked="{Binding AutoRfh,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ />
+ </StackPanel>
+ </DockPanel>
+
+
+ <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}">
+ <DataGrid.RowStyle>
+ <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding type}" Value="warn">
+ <Setter Property="Background" Value="{StaticResource WarningColor}"/>
+ <Setter Property="Foreground" Value="Black"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding type}" Value="error">
+ <Setter Property="Background" Value="{StaticResource DangerColor}"/>
+ <Setter Property="Foreground" Value="Black"/>
+ </DataTrigger>
+ <Trigger Property="IsSelected" Value="True">
+ <Setter Property="Background" Value="Transparent"/>
+ </Trigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="Transparent"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </DataGrid.RowStyle>
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="#" CanUserResize="False">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTextColumn Width="*" Binding="{Binding type}" Header="绾у埆" />
+ <DataGridTextColumn Width="*" Binding="{Binding time}" Header="鏃堕棿" />
+ <DataGridTextColumn Width="*" Binding="{Binding source}" Header="鏉ユ簮" />
+ <DataGridTextColumn Width="*" Binding="{Binding text}" Header="鏂囨湰" />
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+ </Border>
+</hb:PluginControl>
\ No newline at end of file
diff --git a/HMI.LogViewer/LogViewer.xaml.cs b/HMI.LogViewer/LogViewer.xaml.cs
new file mode 100644
index 0000000..272d886
--- /dev/null
+++ b/HMI.LogViewer/LogViewer.xaml.cs
@@ -0,0 +1,210 @@
+锘縰sing HMI.Base;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+using System.Timers;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.LogViewer
+{
+ /// <summary>
+ /// UserControl1.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class LogViewer : PluginControl
+ {
+ private string logDir;
+ private string todayLogFile;
+
+ private bool autoRfh;
+
+ public bool AutoRfh
+ {
+ get { return autoRfh; }
+ set
+ {
+ Set(ref autoRfh, value);
+ if (autoRfhTimer != null) autoRfhTimer.Enabled = value;
+ }
+ }
+
+ private Timer autoRfhTimer;
+
+
+ public LogViewer()
+ {
+ string logDir = Path.Combine(PathHelper.AppFolder, "Log");
+ todayLogFile = Path.Combine(logDir, $"log{DateTime.Now.ToString("yyyy-MM-dd")}.db");
+
+ if (!Directory.Exists(logDir))
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ this.logDir = logDir;
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ public override void InitFinish()
+ {
+ base.InitFinish();
+ string baseFile = Path.Combine(logDir, "log.db");
+
+ try
+ {
+ if (!File.Exists(baseFile))
+ {
+ SqliteHelper.CreateDatabase(baseFile);
+ }
+ SqliteHelper sqliteHelper = new SqliteHelper(baseFile);
+ sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS log (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ type TEXT NOT NULL,
+ text TEXT NOT NULL,
+ source TEXT,
+ time TIME
+ );");
+ }
+ catch (Exception ex)
+ {
+ log.Error("Create Log File Failed.", ex);
+ }
+ }
+
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ autoRfhTimer = new Timer
+ {
+ Enabled = false,
+ Interval = 1000
+ };
+ autoRfhTimer.Elapsed += AutoRfhTimer_Elapsed;
+ Loaded -= UserControl_Loaded;
+ }
+
+ private void AutoRfhTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ Refresh100items();
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ switch (btn.Name)
+ {
+ case "queryBtn":
+ QueryLog();
+ break;
+ case "resetBtn":
+ QueryReset();
+ break;
+ case "exportBtn":
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void QueryLog()
+ {
+ try
+ {
+ queryBtn.IsEnabled = false;
+ autoRfhInput.IsEnabled = false;
+ Filtrate();
+ queryBtn.IsEnabled = true;
+ autoRfhInput.IsEnabled = true;
+ }
+ catch (Exception ex)
+ {
+ log.Error("Log Query Failed.", ex);
+ this.Error($"鏌ヨ澶辫触锛亄ex.Message}");
+ }
+ }
+
+ private void QueryReset()
+ {
+ levelInput.Text = null;
+ startTimeInput.SelectedDateTime = null;
+ endTimeInput.SelectedDateTime = null;
+ startTimeInput.Text = null;
+ table.ItemsSource = null;
+ }
+
+ private void Filtrate()
+ {
+ string str = LoadSql();
+ DataTable dt = new DataTable();
+ var files = Directory.GetFiles(logDir, "*.db");
+ foreach (string file in files)
+ {
+ SqliteHelper sql = new SqliteHelper(file);
+ dt.Merge(sql.GetDataTable(str));
+ sql.Close();
+ }
+
+ dt.DefaultView.Sort = "time Desc";
+ table.ItemsSource = dt.DefaultView;
+ }
+
+ /// <summary>
+ /// 鍔犺浇鐣岄潰鍒ゆ柇鏁版嵁搴撹鍙�
+ /// </summary>
+ /// <returns> str鏁版嵁搴撶殑璇彞 </returns>
+ private string LoadSql()
+ {
+ string sql = " select type,time,source,text from log";
+
+ List<string> datas = new List<string>();
+ if (!string.IsNullOrEmpty(levelInput.Text))
+ {
+ datas.Add($"type='{levelInput.Text}'");
+ }
+ if (!string.IsNullOrEmpty(startTimeInput.Text))
+ {
+ datas.Add($"time>='{startTimeInput.Text}'");
+ }
+ if (!string.IsNullOrEmpty(endTimeInput.Text))
+ {
+ datas.Add($"time<='{endTimeInput.Text}'");
+ }
+ if (!string.IsNullOrEmpty(sourceInput.Text))
+ {
+ datas.Add($"source='{sourceInput.Text}'");
+ }
+
+ string condition = string.Join(" AND ", datas);
+ condition = string.IsNullOrEmpty(condition) ? string.Empty : $" WHERE {condition}";
+
+ sql = $"{sql}{condition} order by time desc";
+ return sql;
+ }
+
+ /// <summary>
+ /// 鍒锋柊100鏉℃暟鎹�
+ /// </summary>
+ private void Refresh100items()
+ {
+ try
+ {
+ if (!File.Exists(todayLogFile)) return;
+ string str = "select type,time,source,text from log order by time desc limit 100";
+ SqliteHelper sql = new SqliteHelper(todayLogFile);
+ var dt = sql.GetDataTable(str);
+ this.Dispatcher.BeginInvoke((Action)delegate ()
+ {
+ table.ItemsSource = dt.DefaultView;
+ });
+ }
+ catch (Exception ex)
+ {
+ log.Error("Log Auto Refresh Failed.", ex);
+ this.Error($"鑷姩鍒锋柊澶辫触锛亄ex.Message}");
+ }
+ }
+ }
+}
diff --git a/HMI.LogViewer/Properties/AssemblyInfo.cs b/HMI.LogViewer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..8b227ca
--- /dev/null
+++ b/HMI.LogViewer/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+锘縰sing System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("HMI.LogViewer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HMI.LogViewer")]
+[assembly: AssemblyCopyright("Copyright 漏 2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+//鑻ヨ寮�濮嬬敓鎴愬彲鏈湴鍖栫殑搴旂敤绋嬪簭锛岃璁剧疆
+//.csproj 鏂囦欢涓殑 <UICulture>CultureYouAreCodingWith</UICulture>
+//鍦� <PropertyGroup> 涓�備緥濡傦紝濡傛灉浣犱娇鐢ㄧ殑鏄編鍥借嫳璇��
+//浣跨敤鐨勬槸缇庡浗鑻辫锛岃灏� <UICulture> 璁剧疆涓� en-US銆� 鐒跺悗鍙栨秷
+//瀵逛互涓� NeutralResourceLanguage 鐗规�х殑娉ㄩ噴銆� 鏇存柊
+//浠ヤ笅琛屼腑鐨勨�渆n-US鈥濅互鍖归厤椤圭洰鏂囦欢涓殑 UICulture 璁剧疆銆�
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //涓婚鐗瑰畾璧勬簮璇嶅吀鎵�澶勪綅缃�
+ //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+ //鎴栧簲鐢ㄧ▼搴忚祫婧愬瓧鍏镐腑鎵惧埌鏃朵娇鐢�)
+ ResourceDictionaryLocation.SourceAssembly //甯歌璧勬簮璇嶅吀鎵�澶勪綅缃�
+ //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+ //銆佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚涓撶敤璧勬簮瀛楀吀涓壘鍒版椂浣跨敤)
+)]
+
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�:
+//
+// 涓荤増鏈�
+// 娆$増鏈�
+// 鐢熸垚鍙�
+// 淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HMI.LogViewer/Properties/Resources.Designer.cs b/HMI.LogViewer/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..186ad9f
--- /dev/null
+++ b/HMI.LogViewer/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+// 姝や唬鐮佺敱宸ュ叿鐢熸垚銆�
+// 杩愯鏃剁増鏈�: 4.0.30319.42000
+//
+// 瀵规鏂囦欢鐨勬洿鏀瑰彲鑳藉鑷翠笉姝g‘鐨勮涓猴紝濡傛灉
+// 閲嶆柊鐢熸垚浠g爜锛屽垯鎵�鍋氭洿鏀瑰皢涓㈠け銆�
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HMI.LogViewer.Properties {
+
+
+ /// <summary>
+ /// 寮虹被鍨嬭祫婧愮被锛岀敤浜庢煡鎵炬湰鍦板寲瀛楃涓茬瓑銆�
+ /// </summary>
+ // 姝ょ被鏄敱 StronglyTypedResourceBuilder
+ // 绫婚�氳繃绫讳技浜� ResGen 鎴� Visual Studio 鐨勫伐鍏疯嚜鍔ㄧ敓鎴愮殑銆�
+ // 鑻ヨ娣诲姞鎴栫Щ闄ゆ垚鍛橈紝璇风紪杈� .ResX 鏂囦欢锛岀劧鍚庨噸鏂拌繍琛� ResGen
+ // (浠� /str 浣滀负鍛戒护閫夐」)锛屾垨閲嶆柊鐢熸垚 VS 椤圭洰銆�
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// 杩斿洖姝ょ被浣跨敤鐨勭紦瀛� ResourceManager 瀹炰緥銆�
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if ((resourceMan == null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HMI.LogViewer.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// 閲嶅啓褰撳墠绾跨▼鐨� CurrentUICulture 灞炴�э紝瀵�
+ /// 浣跨敤姝ゅ己绫诲瀷璧勬簮绫荤殑鎵�鏈夎祫婧愭煡鎵炬墽琛岄噸鍐欍��
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/HMI.LogViewer/Properties/Resources.resx b/HMI.LogViewer/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/HMI.LogViewer/Properties/Resources.resx
@@ -0,0 +1,117 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/HMI.LogViewer/Properties/Settings.Designer.cs b/HMI.LogViewer/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..0d5e3b2
--- /dev/null
+++ b/HMI.LogViewer/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HMI.LogViewer.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/HMI.LogViewer/Properties/Settings.settings b/HMI.LogViewer/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/HMI.LogViewer/Properties/Settings.settings
@@ -0,0 +1,7 @@
+锘�<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
\ No newline at end of file
diff --git a/HMI.LogViewer/packages.config b/HMI.LogViewer/packages.config
new file mode 100644
index 0000000..63cdc53
--- /dev/null
+++ b/HMI.LogViewer/packages.config
@@ -0,0 +1,6 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="log4net" version="3.0.3" targetFramework="net472" />
+ <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
+ <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+</packages>
\ No newline at end of file
diff --git a/HMI.ParameterManage/Entity/ParameterData.cs b/HMI.ParameterManage/Entity/ParameterData.cs
index 144ff47..c0d5e2b 100644
--- a/HMI.ParameterManage/Entity/ParameterData.cs
+++ b/HMI.ParameterManage/Entity/ParameterData.cs
@@ -1,12 +1,8 @@
-锘縰sing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+锘縰sing HMI.Core.Entity;
namespace HMI.ParameterManage.Entity
{
- public class ParameterData
+ public class ParameterData : SelectBase
{
public string Id { get; set; }
public string Name { get; set; }
diff --git a/HMI.ParameterManage/Entity/ProductData.cs b/HMI.ParameterManage/Entity/ProductData.cs
index ada68f8..e5a5b93 100644
--- a/HMI.ParameterManage/Entity/ProductData.cs
+++ b/HMI.ParameterManage/Entity/ProductData.cs
@@ -1,8 +1,12 @@
锘�
+using HMI.Core.Entity;
+using System.Xml.Serialization;
+
namespace HMI.ParameterManage.Entity
{
- public class ProductData
+ public class ProductData:SelectBase
{
+ [XmlIgnore]
public string Id { get; set; }
public string Name { get; set; }
public bool IsMaster { get; set; }
diff --git a/HMI.ParameterManage/HMI.ParameterManage.csproj b/HMI.ParameterManage/HMI.ParameterManage.csproj
index 5a8f5c7..f854a4d 100644
--- a/HMI.ParameterManage/HMI.ParameterManage.csproj
+++ b/HMI.ParameterManage/HMI.ParameterManage.csproj
@@ -81,11 +81,12 @@
<Compile Include="ProductModal.xaml.cs">
<DependentUpon>ProductModal.xaml</DependentUpon>
</Compile>
+ <Compile Include="Model\XmlModel.cs" />
<Page Include="ParameterManage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
- <Compile Include="ControlModel.cs" />
+ <Compile Include="Model\SqlModel.cs" />
<Compile Include="Entity\ParameterData.cs" />
<Compile Include="Entity\ProductData.cs" />
<Compile Include="ParameterManage.xaml.cs">
diff --git a/HMI.ParameterManage/ControlModel.cs b/HMI.ParameterManage/Model/SqlModel.cs
similarity index 72%
rename from HMI.ParameterManage/ControlModel.cs
rename to HMI.ParameterManage/Model/SqlModel.cs
index 67d0035..037a083 100644
--- a/HMI.ParameterManage/ControlModel.cs
+++ b/HMI.ParameterManage/Model/SqlModel.cs
@@ -1,16 +1,40 @@
锘縰sing System.Collections.ObjectModel;
using System.Data;
+using System.IO;
using HMI.Core.Entity;
using HMI.Core.Util;
using HMI.ParameterManage.Entity;
-namespace HMI.ParameterManage
+namespace HMI.ParameterManage.Model
{
- public class ControlModel : NotifyBase
+
+ public class SqlModel : NotifyBase
{
- public ControlModel(SqliteHelper sqliteHelper)
+ public SqlModel(string baseFolder)
{
- SqliteHelper = sqliteHelper;
+ string dbpath = Path.Combine(baseFolder, "ParameterManage.db");
+ if (!File.Exists(dbpath))
+ {
+ SqliteHelper.CreateDatabase(dbpath);
+ }
+ SqliteHelper = new SqliteHelper(dbpath);
+ SqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS product (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL,
+ isMaster INTEGER,
+ parentId INTEGER,
+ UNIQUE(name)
+ );
+CREATE TABLE IF NOT EXISTS parameter (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL,
+ value TEXT,
+ unit TEXT,
+ description TEXT,
+ pGroup TEXT,
+ productName TEXT,
+ UNIQUE(productName,name)
+ );");
}
public SqliteHelper SqliteHelper { get; private set; }
diff --git a/HMI.ParameterManage/Model/XmlModel.cs b/HMI.ParameterManage/Model/XmlModel.cs
new file mode 100644
index 0000000..287bcac
--- /dev/null
+++ b/HMI.ParameterManage/Model/XmlModel.cs
@@ -0,0 +1,210 @@
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Util;
+using HMI.ParameterManage.Entity;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+
+namespace HMI.ParameterManage.Model
+{
+ public class XmlModel : NotifyBase
+ {
+ private string ProductSettingFile;
+ private string ParameterSettingFolder;
+
+ public XmlModel(string baseFolder)
+ {
+ ProductSettingFile = Path.Combine(baseFolder, "Product.setting");
+ ParameterSettingFolder = Path.Combine(baseFolder, "Parameter");
+ if (!Directory.Exists(ParameterSettingFolder))
+ {
+ Directory.CreateDirectory(ParameterSettingFolder);
+ }
+ }
+
+ private ObservableCollection<ProductData> products;
+
+ public ObservableCollection<ProductData> Products
+ {
+ get { return products; }
+ set { Set(ref products, value); }
+ }
+
+ private ObservableCollection<ParameterData> parameters;
+
+ public ObservableCollection<ParameterData> Parameters
+ {
+ get { return parameters; }
+ set { Set(ref parameters, value); }
+ }
+
+ private ProductData selectedProduct;
+
+ public ProductData SelectedProduct
+ {
+ get { return selectedProduct; }
+ set
+ {
+ Set(ref selectedProduct, value);
+ LoadParameters();
+ }
+ }
+
+ private ParameterData selectedParameter;
+
+ public ParameterData SelectedParameter
+ {
+ get { return selectedParameter; }
+ set
+ {
+ Set(ref selectedParameter, value);
+ }
+ }
+
+ public bool ValidateProductName(object value, out string msg)
+ {
+ msg = null;
+ string name = value.ToString();
+ if (Products == null) return true;
+ var temp = Products.FirstOrDefault(p => p.Name == name);
+ if (temp != null && temp != SelectedProduct)
+ {
+ msg = "浜у搧鍚嶇О涓嶈兘閲嶅";
+ return false;
+ }
+ return true;
+ }
+
+ public bool ValidateParameterName(object value, out string msg)
+ {
+ msg = null;
+ string name = value.ToString();
+ if (Products == null) return true;
+ var temp = Parameters.FirstOrDefault(p => p.Name == name);
+ if (temp != null && temp != SelectedParameter)
+ {
+ msg = "鍙傛暟鍚嶇О涓嶈兘閲嶅";
+ return false;
+ }
+ return true;
+ }
+
+ public void LoadProducts()
+ {
+ ObservableCollection<ProductData> products;
+ if (File.Exists(ProductSettingFile))
+ {
+ products = XmlHelper.DeserializeFromXml<ObservableCollection<ProductData>>(ProductSettingFile);
+ }
+ else
+ {
+ products = new ObservableCollection<ProductData>();
+ }
+ Products = products;
+ }
+
+ public void LoadParameters()
+ {
+ ObservableCollection<ParameterData> parameters = new ObservableCollection<ParameterData>();
+ if (SelectedProduct != null)
+ {
+ string fileName = $"Parameter_{SelectedProduct.Name}.setting";
+ string parameterSettingFile = Path.Combine(ParameterSettingFolder, fileName);
+ if (File.Exists(parameterSettingFile))
+ {
+ parameters = XmlHelper.DeserializeFromXml<ObservableCollection<ParameterData>>(parameterSettingFile);
+ }
+ }
+ Parameters = parameters;
+ }
+
+ public void SaveOrUpdateData(ProductData data)
+ {
+ int index = Products.IndexOf(data);
+ if (index > -1)
+ {
+ UpdateData(index, data);
+ }
+ else
+ {
+ InsertData(data);
+ }
+ }
+
+ public void SaveOrUpdateParameter(ParameterData data)
+ {
+ int index = Parameters.IndexOf(data);
+ if (index > -1)
+ {
+ UpdateParameter(index, data);
+ }
+ else
+ {
+ InsertParameter(data);
+ }
+ }
+
+ public void InsertData(ProductData data)
+ {
+ var temp = XmlHelper.DeepClone(Products);
+ temp.Add(data);
+ XmlHelper.SerializeToXml(ProductSettingFile, temp);
+ }
+
+ public void UpdateData(int index, ProductData data)
+ {
+ var temp = XmlHelper.DeepClone(Products);
+ temp[index] = data;
+ XmlHelper.SerializeToXml(ProductSettingFile, temp);
+ }
+
+ public void InsertParameter(ParameterData data)
+ {
+ var temp = XmlHelper.DeepClone(Parameters);
+ temp.Add(data);
+ string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting");
+ XmlHelper.SerializeToXml(fileName, temp);
+ }
+
+ public void UpdateParameter(int index, ParameterData data)
+ {
+ var temp = XmlHelper.DeepClone(Parameters);
+ temp[index] = data;
+ string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting");
+ XmlHelper.SerializeToXml(fileName, temp);
+ }
+
+ public void DeleteProduct(ProductData data)
+ {
+ int index = Products.IndexOf(data);
+ if (index > -1)
+ {
+ var temp = Products.Where(p => p != data).ToList();
+ XmlHelper.SerializeToXml(ProductSettingFile, temp);
+ }
+ }
+ public void DeleteProducts()
+ {
+ var temp = Products.Where(p => !p.IsSelected).ToList();
+ XmlHelper.SerializeToXml(ProductSettingFile, temp);
+ }
+
+ public void DeleteParameter(ParameterData data)
+ {
+ int index = Parameters.IndexOf(data);
+ if (index > -1)
+ {
+ var temp = Parameters.Where(p => p != data).ToList();
+ string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting");
+ XmlHelper.SerializeToXml(fileName, temp);
+ }
+ }
+
+ public void DeleteParameters()
+ {
+ var temp = Parameters.Where(p => !p.IsSelected).ToList();
+ string fileName = Path.Combine(ParameterSettingFolder, $"Parameter_{SelectedProduct.Name}.setting");
+ XmlHelper.SerializeToXml(fileName, temp);
+ }
+ }
+}
diff --git a/HMI.ParameterManage/ParameterManage.xaml b/HMI.ParameterManage/ParameterManage.xaml
index bad6c5f..ac5b69b 100644
--- a/HMI.ParameterManage/ParameterManage.xaml
+++ b/HMI.ParameterManage/ParameterManage.xaml
@@ -17,29 +17,38 @@
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
- <ColumnDefinition Width="2*"/>
- <ColumnDefinition Width="8*"/>
+ <ColumnDefinition Width="3*"/>
+ <ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<Border Style="{StaticResource CardBoarder}" Margin="0,0,2,0">
- <StackPanel>
- <DockPanel Margin="0,0,0,10" Cursor="">
- <Button DockPanel.Dock="Right" x:Name="delBatchBtn" pu:ButtonHelper.Icon="" Style="{StaticResource DangerButton}">鍒犻櫎</Button>
- <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}"
- pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="refreshBtn" Click="Button_Click">鍒锋柊</Button>
- <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}"
- pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="addBtn" Click="Button_Click">鏂板</Button>
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource PrimaryButton}"
+ pu:ButtonHelper.Icon="" x:Name="addBtn" Click="Button_Click">鏂板</Button>
+ <Button Style="{StaticResource PrimaryButton}"
+pu:ButtonHelper.Icon="" x:Name="refreshBtn" Click="Button_Click">鍒锋柊</Button>
+ <Button x:Name="delBatchBtn"
+ pu:ButtonHelper.Icon="" Style="{StaticResource DangerButton}"
+ Click="Button_Click">鍒犻櫎</Button>
+ </StackPanel>
<TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}"
- VerticalAlignment="Center" HorizontalAlignment="Left" Text="浜у搧鍒楄〃"/>
+VerticalAlignment="Center" HorizontalAlignment="Left" Text="浜у搧鍒楄〃"/>
</DockPanel>
- <DataGrid Grid.Column="1" x:Name="table" Style="{StaticResource DefaultDataGrid}"
+
+ <DataGrid Grid.Row="1" x:Name="productTable" Style="{StaticResource DefaultDataGrid}"
SelectedItem="{Binding SelectedProduct}" ItemsSource="{Binding Products}">
<DataGrid.Columns>
<DataGridTemplateColumn Width="Auto" CanUserResize="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox VerticalAlignment="Center"
- IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
@@ -67,38 +76,45 @@
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
- </StackPanel>
+ </Grid>
</Border>
<Border Grid.Column="1" Style="{StaticResource CardBoarder}" Margin="2,0,0,0">
- <StackPanel>
- <DockPanel Margin="0,0,0,10" >
- <Button DockPanel.Dock="Right" pu:ButtonHelper.Icon="" Style="{StaticResource DangerButton}">鍒犻櫎</Button>
- <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}"
- pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="refreshParameterBtn" Click="Button_Click">鍒锋柊</Button>
- <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}"
- pu:ButtonHelper.Icon="" Margin="0,0,10,0" x:Name="addParameterBtn" Click="Button_Click">鏂板</Button>
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource PrimaryButton}"
+pu:ButtonHelper.Icon="" x:Name="addParameterBtn" Click="Button_Click">鏂板</Button>
+ <Button Style="{StaticResource PrimaryButton}"
+pu:ButtonHelper.Icon="" x:Name="refreshParameterBtn" Click="Button_Click">鍒锋柊</Button>
+ <Button pu:ButtonHelper.Icon="" x:Name="deleteBatchParameterBtn"
+ Style="{StaticResource DangerButton}" Click="Button_Click">鍒犻櫎</Button>
+ </StackPanel>
<TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}"
- VerticalAlignment="Center" HorizontalAlignment="Left" Text="浜у搧鍒楄〃"/>
- <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}"
- VerticalAlignment="Center" HorizontalAlignment="Left" Text="浜у搧鍙傛暟"/>
+VerticalAlignment="Center" HorizontalAlignment="Left" Text="浜у搧鍙傛暟"/>
</DockPanel>
- <DataGrid x:Name="roleTable" Style="{StaticResource DefaultDataGrid}" SelectionMode="Single"
- ItemsSource="{Binding Parameters}">
+
+ <DataGrid Grid.Row="1" x:Name="parameterTable" Style="{StaticResource DefaultDataGrid}" SelectionMode="Single"
+ SelectedItem="{Binding SelectedParameter}"
+ ItemsSource="{Binding Parameters}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox VerticalAlignment="Center"
- HorizontalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+ HorizontalAlignment="Center" IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="#" Binding="{Binding Converter={StaticResource rowNumber},
- RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"
- CanUserResize="False"/>
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"
+ CanUserResize="False"/>
<DataGridTextColumn Width="*" Binding="{Binding Name}" Header="鍚嶇О" />
<DataGridTextColumn Width="*" Binding="{Binding Value}" Header="鍊�" />
<DataGridTextColumn Width="*" Binding="{Binding Unit}" Header="鍗曚綅" />
@@ -109,18 +125,18 @@
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button x:Name="editParameterBtn" Style="{StaticResource RowLink}" Margin="0,0,10,0"
- DataContext="{Binding }"
- Click="Button_Click">缂栬緫</Button>
+ DataContext="{Binding }"
+ Click="Button_Click">缂栬緫</Button>
<Button x:Name="delParameterBtn" Style="{StaticResource DangerLinkButton}"
- DataContext="{Binding }"
- Click="Button_Click">鍒犻櫎</Button>
+ DataContext="{Binding }"
+ Click="Button_Click">鍒犻櫎</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
- </StackPanel>
+ </Grid>
</Border>
</Grid>
</hb:PluginControl>
\ No newline at end of file
diff --git a/HMI.ParameterManage/ParameterManage.xaml.cs b/HMI.ParameterManage/ParameterManage.xaml.cs
index 9a9bc3a..8da173a 100644
--- a/HMI.ParameterManage/ParameterManage.xaml.cs
+++ b/HMI.ParameterManage/ParameterManage.xaml.cs
@@ -1,9 +1,12 @@
锘縰sing System.IO;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Markup;
using HMI.Base;
using HMI.Core.Util;
using HMI.ParameterManage.Entity;
+using HMI.ParameterManage.Model;
using HMI.UI.Util;
namespace HMI.ParameterManage
@@ -13,8 +16,7 @@
/// </summary>
public partial class ParameterManage : PluginControl
{
- private ControlModel Model;
- private SqliteHelper SqliteHelper;
+ private XmlModel Model;
public ParameterManage()
{
@@ -23,31 +25,7 @@
public override void InitFinish()
{
- string dbpath = Path.Combine(BaseFolder, "ParameterManage.db");
- if (!File.Exists(dbpath))
- {
- SqliteHelper.CreateDatabase(dbpath);
- }
- SqliteHelper = new SqliteHelper(dbpath);
- SqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS product (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- isMaster INTEGER,
- parentId INTEGER,
- UNIQUE(name)
- );
-CREATE TABLE IF NOT EXISTS parameter (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- value TEXT,
- unit TEXT,
- description TEXT,
- pGroup TEXT,
- productName TEXT,
- UNIQUE(productName,name)
- );
-");
- Model = new ControlModel(SqliteHelper);
+ Model = new XmlModel(BaseFolder);
DataContext = Model;
}
@@ -63,7 +41,16 @@
switch (btn.Name)
{
case "addBtn":
- OpenAddDialog();
+ OpenProductDialog(null);
+ break;
+ case "editProductBtn":
+ OpenProductDialog((ProductData)btn.DataContext);
+ break;
+ case "delProductBtn":
+ TryDeleteProduct((ProductData)btn.DataContext);
+ break;
+ case "delBatchBtn":
+ TryDeleteProducts();
break;
case "refrshBtn":
Model.LoadProducts();
@@ -77,20 +64,24 @@
case "editParameterBtn":
OpenAddParameterDialog((ParameterData)btn.DataContext);
break;
+ case "delParameterBtn":
+ TryDeleteParameter((ParameterData)btn.DataContext);
+ break;
+ case "deleteBatchParameterBtn":
+ TryDeleteParameters();
+ break;
default:
break;
}
}
-
- private void OpenAddDialog()
+ private void OpenProductDialog(ProductData data)
{
- var win = new ProductModal
+ var win = new ProductModal(Model)
{
- Title = "鏂板浜у搧",
+ Title = data == null ? "鏂板浜у搧" : "缂栬緫浜у搧",
Owner = Window.GetWindow(this),
- sqliteHelper = SqliteHelper
};
- if (win.Open(new ProductData()) == true)
+ if (win.Open(data ?? new ProductData()) == true)
{
Model.LoadProducts();
}
@@ -103,11 +94,10 @@
ToastHelper.Warning(Window.GetWindow(this), "璇峰厛閫夋嫨涓�椤逛骇鍝�");
return;
}
- var win = new ParameterModal
+ var win = new ParameterModal(Model)
{
Title = data == null ? "鏂板鍙傛暟" : "缂栬緫鍙傛暟",
Owner = Window.GetWindow(this),
- sqliteHelper = SqliteHelper
};
if (win.Open(data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }) == true)
{
@@ -115,5 +105,56 @@
}
}
+ private void TryDeleteProduct(ProductData data)
+ {
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"纭畾瑕佸垹闄や骇鍝乕{data.Name}]鍚楋紵璇ユ搷浣滄棤娉曟挙閿�")
+ == MessageBoxResult.OK)
+ {
+ Model.DeleteProduct(data);
+ Model.LoadProducts();
+ }
+ }
+
+ private void TryDeleteProducts()
+ {
+ var temp = Model.Products.Where(p => p.IsSelected).Count();
+ if (temp <= 0)
+ {
+ this.Warning("璇烽�夋嫨瑕佸垹闄ょ殑浜у搧");
+ return;
+ }
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"纭畾瑕佸垹闄ら�変腑鐨刐{temp}]鏉′骇鍝佸悧锛熻鎿嶄綔鏃犳硶鎾ら攢")
+ == MessageBoxResult.OK)
+ {
+ Model.DeleteProducts();
+ Model.LoadProducts();
+ }
+ }
+
+ private void TryDeleteParameter(ParameterData data)
+ {
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"纭畾瑕佸垹闄ゅ弬鏁癧{data.Name}]鍚楋紵璇ユ搷浣滄棤娉曟挙閿�") == MessageBoxResult.OK)
+ {
+ Model.DeleteParameter(data);
+ Model.LoadParameters();
+ }
+ }
+
+ private void TryDeleteParameters()
+ {
+ var temp = Model.Parameters.Where(p => p.IsSelected).Count();
+ if (temp <= 0)
+ {
+ this.Warning("璇烽�夋嫨瑕佸垹闄ょ殑鍙傛暟");
+ return;
+ }
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"纭畾瑕佸垹闄ら�変腑鐨刐{temp}]鏉″弬鏁板悧锛熻鎿嶄綔鏃犳硶鎾ら攢")
+ == MessageBoxResult.OK)
+ {
+ Model.DeleteParameters();
+ Model.LoadParameters();
+ }
+ }
+
}
}
diff --git a/HMI.ParameterManage/ParameterModal.xaml b/HMI.ParameterManage/ParameterModal.xaml
index 08bc442..29a4921 100644
--- a/HMI.ParameterManage/ParameterModal.xaml
+++ b/HMI.ParameterManage/ParameterModal.xaml
@@ -8,6 +8,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
mc:Ignorable="d"
Title="Form"
SizeToContent="Height"
@@ -26,19 +27,19 @@
pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
<Grid Margin="10">
<StackPanel x:Name="formPanel">
- <pu:FormGroup x:Name="FgProductName" ui:FormGroupHelper.IsRequired="True"
+ <pu:FormGroup x:Name="FgProductName" dp:FormGroupHelper.IsRequired="True"
Header="浜у搧鍚嶇О" GroupName="MyFormGroup">
<TextBox x:Name="TbProductName" IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" />
</pu:FormGroup>
- <pu:FormGroup x:Name="FgName" ui:FormGroupHelper.IsRequired="True"
- ui:FormGroupHelper.ValidateMethod="ValidateName"
+ <pu:FormGroup x:Name="FgName" dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateName"
Header="鍙傛暟鍚嶇О" GroupName="MyFormGroup">
<TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" />
</pu:FormGroup>
<pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}"
- ui:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.IsRequired="True"
Header="鍙傛暟鍊�" GroupName="MyFormGroup">
<TextBox x:Name="TbValue" Style="{StaticResource EditorTextBoxStyle}" />
</pu:FormGroup>
diff --git a/HMI.ParameterManage/ParameterModal.xaml.cs b/HMI.ParameterManage/ParameterModal.xaml.cs
index 6824e14..d30c52d 100644
--- a/HMI.ParameterManage/ParameterModal.xaml.cs
+++ b/HMI.ParameterManage/ParameterModal.xaml.cs
@@ -1,18 +1,11 @@
-锘縰sing System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Linq;
-using System.Reflection;
-using System.Windows;
-using Microsoft.Win32;
-using Panuon.WPF.UI;
-using HMI.Core.Annotation;
-using HMI.Core.Entity;
-using HMI.Core.Exceptions;
-using HMI.Core.Util;
+锘縰sing HMI.Core.Util;
using HMI.ParameterManage.Entity;
-using HMI.UI;
+using HMI.ParameterManage.Model;
+using HMI.UI.DpUtil;
+using Panuon.WPF.UI;
+using System;
+using System.ComponentModel;
+using System.Windows.Interop;
namespace HMI.ParameterManage
{
@@ -21,15 +14,15 @@
/// </summary>
public partial class ParameterModal : WindowX
{
- public ParameterModal()
+ private XmlModel DataModel;
+ public ParameterModal(XmlModel model)
{
+ DataModel = model;
this.DataContext = this;
InitializeComponent();
}
public ParameterData Data { get; set; }
-
- public SqliteHelper sqliteHelper { get; set; }
private bool _isProcessing;
@@ -54,7 +47,7 @@
return;
}
- SaveOrUpdateData();
+ DataModel.SaveOrUpdateParameter(Data);
}
catch (Exception ex)
{
@@ -73,15 +66,7 @@
public bool ValidateName(object value, out string err)
{
- err = null;
- string segment = string.IsNullOrEmpty(Data.Id) ? "" : $" AND id!='{Data.Id}'";
- string sql = $"SELECT 1 FROM parameter WHERE name='{TbName.Text}' AND productName='{Data.ProductName}'{segment};";
- if (sqliteHelper.HasData(sql))
- {
- err = "鍙傛暟鍚嶇О涓嶈兘閲嶅";
- return false;
- }
- return true;
+ return DataModel.ValidateParameterName(value, out err);
}
private bool ValidateForm()
@@ -109,33 +94,6 @@
TbDescription.Text = Data.Description;
TbPGroup.Text = Data.PGroup;
return this.ShowDialog();
- }
-
- private void SaveOrUpdateData()
- {
- if (string.IsNullOrEmpty(Data.Id))
- {
- InsertData(Data);
- }
- else
- {
- UpdateData(Data);
- }
- }
-
- public void InsertData(ParameterData data)
- {
- string sql = $@"INSERT INTO parameter (name,value,unit,description,productName,pGroup)
- VALUES
- ('{data.Name}','{data.Value}','{data.Unit}','{data.Description}','{data.ProductName}','{data.PGroup}');";
- sqliteHelper.ExecuteSql(sql);
- }
-
- public void UpdateData(ParameterData data)
- {
- string sql = $@"UPDATE parameter SET name='{data.Name}',value='{data.Value}',unit='{data.Unit}',
-description='{data.Description}',productName='{data.ProductName}',pGroup='{data.PGroup}' WHERE id='{data.Id}';";
- sqliteHelper.ExecuteSql(sql);
}
}
}
diff --git a/HMI.ParameterManage/ProductModal.xaml b/HMI.ParameterManage/ProductModal.xaml
index dd216e1..1b9c033 100644
--- a/HMI.ParameterManage/ProductModal.xaml
+++ b/HMI.ParameterManage/ProductModal.xaml
@@ -7,6 +7,7 @@
xmlns:pw="https://opensource.panuon.com/wpf"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
mc:Ignorable="d"
Title="Form"
SizeToContent="Height"
@@ -37,9 +38,12 @@
</Window.Resources>
<Grid Margin="10">
- <StackPanel>
+ <StackPanel x:Name="formPanel">
<pu:FormGroup x:Name="FgName" Style="{StaticResource RequiredInputFormGroupStyle}"
- Header="浜у搧鍚嶇О" GroupName="MyFormGroup">
+ Header="浜у搧鍚嶇О" GroupName="MyFormGroup"
+ dp:FormGroupHelper.IsRequired="True"
+ dp:FormGroupHelper.ValidateMethod="ValidateName"
+ >
<TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" />
</pu:FormGroup>
diff --git a/HMI.ParameterManage/ProductModal.xaml.cs b/HMI.ParameterManage/ProductModal.xaml.cs
index d67793d..53eea7b 100644
--- a/HMI.ParameterManage/ProductModal.xaml.cs
+++ b/HMI.ParameterManage/ProductModal.xaml.cs
@@ -13,6 +13,8 @@
using HMI.Core.Util;
using HMI.ParameterManage.Entity;
using HMI.UI;
+using HMI.ParameterManage.Model;
+using HMI.UI.DpUtil;
namespace HMI.ParameterManage
{
@@ -21,15 +23,17 @@
/// </summary>
public partial class ProductModal : WindowX
{
- public ProductModal()
+
+ private XmlModel DataModel;
+
+ public ProductModal(XmlModel dataModel)
{
+ DataModel = dataModel;
this.DataContext = this;
InitializeComponent();
}
public ProductData Data { get; set; }
-
- public SqliteHelper sqliteHelper { get; set; }
private bool _isProcessing;
@@ -54,7 +58,7 @@
return;
}
- SaveOrUpdateData();
+ DataModel.SaveOrUpdateData(Data);
}
catch (Exception ex)
{
@@ -71,50 +75,20 @@
base.OnClosing(e);
}
+ private bool ValidateName(object value, out string msg)
+ {
+ return DataModel.ValidateProductName(value, out msg);
+ }
+
private bool ValidateForm()
{
- try
+ bool flag = FormGroupHelper.ValidateForm(formPanel);
+ if (flag)
{
-
- //
-
- FormValidateException ex = new FormValidateException();
- string segment = string.IsNullOrEmpty(Data.Id) ? "" : $" AND id!='{Data.Id}'";
- string sql = $"SELECT 1 FROM product WHERE name='{TbName.Text}'{segment};";
- if (string.IsNullOrEmpty(TbName.Text))
- {
- ex.Result.Add(new FormGroupValidateResult("璇疯緭鍏ヤ骇鍝佸悕绉�", FgName));
- }
- else if (sqliteHelper.HasData(sql))
- {
- ex.Result.Add(new FormGroupValidateResult("浜у搧鍚嶇О涓嶈兘閲嶅", FgName));
- }
- else
- {
- FgName.ValidateResult = ValidateResult.None;
- FgName.Message = null;
- }
-
- if (!ex.Success)
- {
- throw ex;
- }
+ Data.Name = TbName.Text;
+ Data.IsMaster = TbIsMaster.IsChecked == true;
}
- catch (FormValidateException ex)
- {
- foreach (var data in ex.Result)
- {
- var fg = (FormGroup)data.Sender;
- fg.ValidateResult = ValidateResult.Error;
- fg.Message = data.Message;
- }
- return false;
- }
-
- Data.Name = TbName.Text;
- Data.IsMaster = TbIsMaster.IsChecked == true;
- Data.ParentId = TbParentId.Text;
- return true;
+ return flag;
}
public bool? Open(ProductData data)
@@ -125,35 +99,6 @@
TbParentId.Text = Data.ParentId;
return this.ShowDialog();
- }
-
- private void SaveOrUpdateData()
- {
- if (string.IsNullOrEmpty(Data.Id))
- {
- InsertData(Data);
- }
- else
- {
- UpdateData(Data);
- }
- }
-
- public void InsertData(ProductData data)
- {
- string sql = $@"INSERT INTO product (name,isMaster,parentId)
- VALUES
- ('{data.Name}',{(data.IsMaster ? 1 : 0)} ,{data.ParentId} );";
- sqliteHelper.ExecuteSql(sql);
- }
-
-
-
- public void UpdateData(ProductData data)
- {
- string sql = $@"UPDATE product SET name='{data.Name}',isMaster='{(data.IsMaster ? 1 : 0)}',parentId = {data.ParentId}
-WHERE id='{data.Id}';";
- sqliteHelper.ExecuteSql(sql);
}
}
}
diff --git a/HMI.SettingControl/SettingControl.xaml b/HMI.SettingControl/SettingControl.xaml
index 70b3828..8a2e249 100644
--- a/HMI.SettingControl/SettingControl.xaml
+++ b/HMI.SettingControl/SettingControl.xaml
@@ -9,7 +9,7 @@
xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
xmlns:pw="https://opensource.panuon.com/wpf"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
- xmlns:dp="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
Loaded="UserControl_Loaded"
Background="{StaticResource WorkspaceBackground}"
d:DesignHeight="450" d:DesignWidth="800">
@@ -28,33 +28,35 @@
<Grid>
<Border Style="{StaticResource CardBoarder}">
- <Grid>
+ <Grid dp:GridHelper.Space="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
+ <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
- <TextBlock VerticalAlignment="Center" Text="绯荤粺璁剧疆" Margin="0,0,0,10"
- FontSize="{StaticResource TitleFontSize}" />
- <TabControl Grid.Row="1"
-
+ <TextBlock VerticalAlignment="Center" Text="绯荤粺璁剧疆" FontSize="{StaticResource TitleFontSize}" />
+ <TabControl Grid.Row="1" x:Name="tabControl"
BorderBrush="{StaticResource CommonBoarder}"
ItemsSource="{Binding TabItems}">
- <TabControl.Resources>
- <Style TargetType="TabControl" BasedOn="{StaticResource {x:Static pu:StyleKeys.TabControlStyle}}">
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="TabControl">
- <Border BorderBrush="Black" BorderThickness="1">
+ <TabControl.Resources>
+ <Style TargetType="TabControl" BasedOn="{StaticResource {x:Static pu:StyleKeys.TabControlStyle}}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="TabControl">
+ <Border BorderBrush="Black" BorderThickness="1">
<ContentPresenter/>
</Border>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </TabControl.Resources>
-
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </TabControl.Resources>
</TabControl>
+ <StackPanel Grid.Row="2" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource PrimaryButton}" x:Name="resetBtn" Click="Button_Click">閲嶇疆</Button>
+ <Button Style="{StaticResource PrimaryButton}" x:Name="saveBtn" Click="Button_Click">淇濆瓨</Button>
+ </StackPanel>
</Grid>
</Border>
</Grid>
diff --git a/HMI.SettingControl/SettingControl.xaml.cs b/HMI.SettingControl/SettingControl.xaml.cs
index 9ee7841..fceb973 100644
--- a/HMI.SettingControl/SettingControl.xaml.cs
+++ b/HMI.SettingControl/SettingControl.xaml.cs
@@ -1,10 +1,12 @@
-锘縰sing System.Collections.ObjectModel;
+锘縰sing System;
+using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using HMI.Base;
using HMI.Core.Api;
+using HMI.UI.Util;
using log4net;
namespace HMI.SettingControl
@@ -51,5 +53,73 @@
}
Loaded -= UserControl_Loaded;
}
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ switch (btn.Name)
+ {
+ case "resetBtn":
+ ResetCurrentConfig();
+ break;
+ case "saveBtn":
+ SaveAllConfig();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void SaveAllConfig()
+ {
+ foreach (var d in tabControl.ItemsSource)
+ {
+ if (!(d is TabItem tabItem)) continue;
+ if (tabItem.Content is IConfigManager manager)
+ {
+ try
+ {
+ manager.SaveConfig();
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper.Error(this, $"淇濆瓨{tabItem.Header}閰嶇疆澶辫触锛亄ex.Message}");
+ }
+ }
+ }
+ this.Success("淇濆瓨鎴愬姛");
+ }
+
+ private void SaveCurrentConfig()
+ {
+ var content = tabControl.SelectedItem as TabItem;
+ if (content is IConfigManager manager)
+ {
+ try
+ {
+ manager.SaveConfig();
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper.Error(this, $"淇濆瓨閰嶇疆澶辫触锛亄ex.Message}");
+ }
+ }
+ }
+
+ private void ResetCurrentConfig()
+ {
+ var tabItem = tabControl.SelectedItem as TabItem;
+ if (tabItem.Content is IConfigManager manager)
+ {
+ try
+ {
+ manager.ResetConfig();
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper.Error(this, $"淇濆瓨閰嶇疆澶辫触锛亄ex.Message}");
+ }
+ }
+ }
}
}
diff --git a/HMI.SettingControl/SystemConfig.xaml b/HMI.SettingControl/SystemConfig.xaml
index cc84c83..28cc0e5 100644
--- a/HMI.SettingControl/SystemConfig.xaml
+++ b/HMI.SettingControl/SystemConfig.xaml
@@ -53,9 +53,5 @@
</pu:FormGroup>
</StackPanel>
</GroupBox>
-
- <DockPanel Grid.Row="3" LastChildFill="False">
- <Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" Click="Button_Click">淇濆瓨</Button>
- </DockPanel>
</Grid>
</UserControl>
diff --git a/HMI.SettingControl/SystemConfig.xaml.cs b/HMI.SettingControl/SystemConfig.xaml.cs
index 1e75505..53e5e26 100644
--- a/HMI.SettingControl/SystemConfig.xaml.cs
+++ b/HMI.SettingControl/SystemConfig.xaml.cs
@@ -1,5 +1,6 @@
锘縰sing System;
using System.Windows.Controls;
+using HMI.Core.Api;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI.Util;
@@ -9,7 +10,7 @@
/// <summary>
/// SystemConfig.xaml 鐨勪氦浜掗�昏緫
/// </summary>
- public partial class SystemConfig : UserControl
+ public partial class SystemConfig : UserControl, IConfigManager
{
public SystemConfig()
{
@@ -19,14 +20,29 @@
InitializeComponent();
}
+ public object GetConfig()
+ {
+ return SystemSetting.Instance;
+ }
+
+ public void ResetConfig()
+ {
+ var model = new SystemSettingModel();
+ BeanUtil.Copy(SystemSetting.Instance, model);
+ DataContext = model;
+ }
+
+ public void SaveConfig()
+ {
+ SystemSettingModel settingModel = (SystemSettingModel)DataContext;
+ XmlHelper.SerializeToXml(PathHelper.ConfigFolder + "\\SystemConfig.xml", settingModel);
+ SystemSetting.ReLoad();
+ }
+
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
try
{
- SystemSettingModel settingModel = (SystemSettingModel)DataContext;
- XmlHelper.SerializeToXml(PathHelper.ConfigFolder + "\\SystemConfig.xml", settingModel);
- SystemSetting.ReLoad();
- this.Success("淇濆瓨鎴愬姛");
}
catch (Exception ex)
{
diff --git a/HMI.UI/DpUtil/DataGridHelper.cs b/HMI.UI/DpUtil/DataGridHelper.cs
new file mode 100644
index 0000000..b9fce70
--- /dev/null
+++ b/HMI.UI/DpUtil/DataGridHelper.cs
@@ -0,0 +1,20 @@
+锘縰sing System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.UI.DpUtil
+{
+ public class DataGridHelper
+ {
+ public static DataGridColumn GetSelectedColumn(DataGrid obj)
+ {
+ return (DataGridColumn)obj.GetValue(SelectedColumnProperty);
+ }
+ public static void SetSelectedColumn(DataGrid obj, DataGridColumn value)
+ {
+ obj.SetValue(SelectedColumnProperty, value);
+ }
+ public static readonly DependencyProperty SelectedColumnProperty =
+ DependencyProperty.RegisterAttached("SelectedColumn", typeof(DataGridColumn), typeof(Grid),
+ new PropertyMetadata(null));
+ }
+}
diff --git a/HMI.UI/DpUtil/FormGroupHelper.cs b/HMI.UI/DpUtil/FormGroupHelper.cs
index 3447885..21c314e 100644
--- a/HMI.UI/DpUtil/FormGroupHelper.cs
+++ b/HMI.UI/DpUtil/FormGroupHelper.cs
@@ -1,11 +1,8 @@
-锘縰sing System;
-using System.ComponentModel;
+锘縰sing Panuon.WPF.UI;
using System.Windows;
using System.Windows.Controls;
-using Panuon.WPF.UI;
-using Panuon.WPF.UI.Configurations;
-namespace HMI.UI
+namespace HMI.UI.DpUtil
{
public class FormGroupHelper
{
diff --git a/HMI.UI/HMI.UI.csproj b/HMI.UI/HMI.UI.csproj
index 9c5efce..d2bcfdc 100644
--- a/HMI.UI/HMI.UI.csproj
+++ b/HMI.UI/HMI.UI.csproj
@@ -82,6 +82,7 @@
<ItemGroup>
<Compile Include="Converter\DataGridRowNumberConverter.cs" />
<Compile Include="Converter\PathImageConverter.cs" />
+ <Compile Include="DpUtil\DataGridHelper.cs" />
<Compile Include="DpUtil\FormGroupHelper.cs" />
<Compile Include="DpUtil\GridHelper.cs" />
<Compile Include="DpUtil\StackPanelHelper.cs" />
diff --git a/HMI.UI/Style/FormStyle.xaml b/HMI.UI/Style/FormStyle.xaml
index 42eb600..b77cbf6 100644
--- a/HMI.UI/Style/FormStyle.xaml
+++ b/HMI.UI/Style/FormStyle.xaml
@@ -90,7 +90,7 @@
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
- <Setter Property="Background" Value="LightGray"/>
+ <Setter Property="Background" Value="#e8e8e8"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -172,7 +172,9 @@
<Setter Property="ItemsHoverBackground" Value="{StaticResource SecondPrimaryColor}"/>
<Setter Property="ItemsHoverForeground" Value="{StaticResource SecondPrimaryColorContract}"/>
<Setter Property="TextStringFormat" Value="yyyy-MM-dd HH:mm:ss"/>
+ <Setter Property="Width" Value="180"/>
<Setter Property="Mode" Value="DateTime"/>
+ <Setter Property="SelectedDateTime" Value="{x:Null}"/>
</Style>
</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Style/PanuonResource.xaml b/HMI.UI/Style/PanuonResource.xaml
index 792c26e..f97f70a 100644
--- a/HMI.UI/Style/PanuonResource.xaml
+++ b/HMI.UI/Style/PanuonResource.xaml
@@ -13,6 +13,7 @@
<sys:Double x:Key="TitleFontSize">20</sys:Double>
<sys:Double x:Key="ContentFontSize">16</sys:Double>
+ <sys:Double x:Key="ContentFontSize2">14</sys:Double>
<Style x:Key="PrimaryButton" TargetType="Button" BasedOn="{StaticResource {x:Static pu:StyleKeys.ButtonStyle}}">
<Setter Property="Background" Value="{StaticResource PrimaryColor}"/>
@@ -65,6 +66,22 @@
<Style x:Key="DangerLinkButton" TargetType="Button" BasedOn="{StaticResource LinkButton}">
<Setter Property="Foreground" Value="{StaticResource DangerColor}"/>
+ </Style>
+
+ <Style x:Key="CommonToggle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Static pu:StyleKeys.ToggleButtonStyle}}">
+ <Setter Property="Background" Value="#FFF"/>
+ <Setter Property="Foreground" Value="Black"/>
+ <Setter Property="BorderBrush" Value="LightGray"/>
+ <Setter Property="Cursor" Value="Hand"/>
+ </Style>
+
+ <Style x:Key="CommonMenu" TargetType="Menu" BasedOn="{StaticResource {x:Static pu:StyleKeys.MenuStyle}}">
+ <Setter Property="Background" Value="{StaticResource PrimaryColor}"/>
+ <Setter Property="Foreground" Value="#FFF"/>
+ <Setter Property="pu:IconHelper.FontFamily" Value="{StaticResource iconfont}"/>
+ <Setter Property="pu:IconHelper.Margin" Value="0,0,10,0"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="Cursor" Value="Hand"/>
</Style>
<Style x:Key="CardBoarder" TargetType="Border">
@@ -171,4 +188,10 @@
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="{StaticResource TitleFontSize}"/>
</Style>
+
+ <Style x:Key="FormHeader" TargetType="TextBlock">
+ <Setter Property="VerticalAlignment" Value="Center"/>
+ <Setter Property="HorizontalAlignment" Value="Center"/>
+ <Setter Property="FontSize" Value="{StaticResource ContentFontSize2}"/>
+ </Style>
</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UI/Util/ToastHelper.cs b/HMI.UI/Util/ToastHelper.cs
index 6410963..9f4421f 100644
--- a/HMI.UI/Util/ToastHelper.cs
+++ b/HMI.UI/Util/ToastHelper.cs
@@ -141,7 +141,10 @@
ToastPosition position = ToastPosition.Top, double offset = 0, int durationMs = 3000,
ToastWindow targetWindow = ToastWindow.ActiveWindow)
{
- ToastHelper.Error(Window.GetWindow(control), message, icon, position, offset, durationMs, targetWindow);
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ ToastHelper.Error(Window.GetWindow(control), message, icon, position, offset, durationMs, targetWindow);
+ });
}
public static void Info(this UserControl control,
diff --git a/Plugin.TestResult/Chart.xaml b/Plugin.TestResult/Chart.xaml
new file mode 100644
index 0000000..dc41e62
--- /dev/null
+++ b/Plugin.TestResult/Chart.xaml
@@ -0,0 +1,14 @@
+锘�<UserControl x:Class="Plugin.TestResult_WPF.Chart"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
+ mc:Ignorable="d"
+ Loaded="UserControl_Loaded"
+ Unloaded="UserControl_Unloaded"
+ SizeChanged="UserControl_SizeChanged"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <ScottPlot:WpfPlot x:Name="chart" />
+</UserControl>
diff --git a/Plugin.TestResult/Chart.xaml.cs b/Plugin.TestResult/Chart.xaml.cs
new file mode 100644
index 0000000..16257d5
--- /dev/null
+++ b/Plugin.TestResult/Chart.xaml.cs
@@ -0,0 +1,314 @@
+锘縰sing ScottPlot;
+using ScottPlot.Plottables;
+using ScottPlot.TickGenerators;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Timers;
+using System.Windows.Controls;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// Chart.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class Chart : UserControl
+ {
+ private readonly int maxSize;
+
+ private readonly Queue<long> xData;
+ private readonly Queue<double> yData;
+
+ private readonly Dictionary<string, Queue<long>> xValues;
+ private readonly Dictionary<string, Queue<double>> yValues;
+
+ readonly DataLogger singleLogger;
+
+ private readonly string title;
+ private readonly bool multi;
+ private readonly int refreshInterval;
+
+ private double maxYValue = -1;
+ private double minYValue = double.MaxValue;
+
+ private Timer timer;
+
+ private readonly Dictionary<string, DataLogger> loggers = new Dictionary<string, DataLogger>();
+
+ private DataLogger InitLogger()
+ {
+ DataLogger logger = chart.Plot.Add.DataLogger();
+ //logger.ViewSlide(maxSize * 5);
+ logger.ViewFull();
+ //logger.Add(new Coordinates(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), 0));
+ return logger;
+ }
+
+ public Chart(string title, bool multi, int maxSize, int refreshInterval)
+ {
+ this.title = title;
+ this.maxSize = maxSize;
+ this.multi = multi;
+ this.refreshInterval = refreshInterval;
+
+
+ InitializeComponent();
+ if (this.multi)
+ {
+ xValues = new Dictionary<string, Queue<long>>();
+ yValues = new Dictionary<string, Queue<double>>();
+ //chart.Plot.ShowLegend(Alignment.UpperLeft, Orientation.Vertical);
+ var legend = chart.Plot.ShowLegend(Edge.Top);
+ legend.Alignment = Alignment.UpperLeft;
+ legend.Padding = new PixelPadding(0);
+
+
+ chart.Plot.Axes.Left.TickLabelStyle.FontSize = 12;
+ chart.Plot.Axes.Bottom.TickLabelStyle.FontSize = 12;
+ chart.Plot.Axes.Left.Label.FontSize = 15;
+ }
+ else
+ {
+ singleLogger = InitLogger();
+ singleLogger.Color = Colors.Red;
+ xData = new Queue<long>(maxSize);
+ yData = new Queue<double>(maxSize);
+ chart.Plot.Axes.Left.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(12, ActualHeight, 92);
+ chart.Plot.Axes.Bottom.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(12, ActualHeight, 92);
+ chart.Plot.Axes.Left.Label.FontSize = (float)FontSizeConverter.CountFontSize(15, ActualHeight, 92);
+ }
+
+ /// 绂佺敤榧犳爣
+ chart.UserInputProcessor.Disable();
+ //chart.Plot.Layout.Frameless();
+
+
+ //Streamer1 = chart.Plot.Add.DataStreamer(maxSize);
+ //Streamer1.ViewScrollLeft();
+ //Streamer1.Color = Colors.Green;
+
+ //chart.Plot.Add.Scatter(xData.ToArray(), yData.ToArray());
+
+
+
+
+ //string CustomFormatter(DateTime dt)
+ //{
+ // return dt.ToString("HH:mm:ss.fff");
+ //}
+ //var axis = chart.Plot.Axes.DateTimeTicksBottom();
+ //var tickGen = (DateTimeAutomatic)axis.TickGenerator;
+ //tickGen.LabelFormatter = CustomFormatter;
+
+ //chart.Plot.Axes.Bottom.TickGenerator = new DateTimeAutomatic();
+ //chart.Plot.Axes.DateTimeTicksBottom();
+ //chart.Plot.RenderManager.RenderStarting += (s, e) =>
+ //{
+ // try
+ // {
+ // Tick[] ticks = chart.Plot.Axes.Bottom.TickGenerator.Ticks;
+ // for (int i = 0; i < ticks.Length; i++)
+ // {
+ // long ms = ticks[i].Position < 0 ? 0 : (long)ticks[i].Position;
+ // DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)).AddMilliseconds(ms);
+ // string label = $"{dt:hh:mm:ss.fff}";
+ // ticks[i] = new Tick(ticks[i].Position, label);
+ // }
+ // }
+ // catch (Exception ex)
+ // {
+
+ // }
+ //};
+
+ string CustomFormatter(double position)
+ {
+ if (position > 0)
+ return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)).AddMilliseconds(position).ToString("HH:mm:ss");
+ return "";
+ }
+ EvenlySpacedMinorTickGenerator minorTickGen = new EvenlySpacedMinorTickGenerator(10);
+ NumericAutomatic myTickGenerator = new NumericAutomatic()
+ {
+ LabelFormatter = CustomFormatter,
+ MinorTickGenerator = minorTickGen
+ };
+ chart.Plot.Axes.Bottom.TickGenerator = myTickGenerator;
+ if (!string.IsNullOrEmpty(this.title))
+ {
+ chart.Plot.Axes.Left.Label.Text = this.title;
+ chart.Plot.Axes.Left.Label.Bold = false;
+ chart.Plot.Font.Automatic();
+ //RefreshData();
+ }
+
+ /// 璁剧疆鍒锋柊瀹氭椂鍣�
+ //refreshTimer = new System.Timers.Timer() { Interval = this.refreshInterval, AutoReset = true };
+ //refreshTimer.Elapsed += RefreshTimer_Elapsed;
+
+ //chart.Plot.DataBackground.Color = new Color(0, 0, 0);
+ //chart.Plot.Grid.MajorLineColor = Colors.Green.WithOpacity(.6);
+ //chart.Plot.Grid.MajorLineWidth = 1;
+ //chart.Plot.Grid.MinorLineColor = Colors.Gray.WithOpacity(.3);
+ //chart.Plot.Grid.MinorLineWidth = 1;
+
+ //chart.Plot.Axes.Bottom.TickLabelStyle.IsVisible = false;
+ //chart.Plot.Axes.Bottom.MajorTickStyle.Length = 0;
+ //chart.Plot.Axes.Left.TickLabelStyle.IsVisible = false;
+ //chart.Plot.Axes.Left.MajorTickStyle.Length = 0;
+
+ //chart.Plot.Axes.Bottom.FrameLineStyle.Width = 0;
+ //chart.Plot.Axes.Left.FrameLineStyle.Width = 0;
+ //chart.Plot.Axes.Top.FrameLineStyle.Width = 0;
+ //chart.Plot.Axes.Right.FrameLineStyle.Width = 0;
+
+ timer = new Timer();
+ timer.Interval = this.refreshInterval;
+ timer.Elapsed += Timer_Elapsed;
+ }
+
+ private void Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ if (maxYValue > 0)
+ {
+ RefreshData();
+ }
+ }
+
+ public void RefreshData()
+ {
+ /// 闄愬埗y杞�
+ if (maxYValue > -1)
+ {
+ chart.Plot.Axes.SetLimitsY(minYValue > 5 ? minYValue - 5 : 0, maxYValue + 5);
+ }
+ else
+ {
+ chart.Plot.Axes.SetLimitsY(0, 100);
+ }
+ chart.Refresh();
+ }
+
+ public void Clear()
+ {
+ this.maxYValue = -1;
+ this.minYValue = double.MaxValue;
+ if (this.multi)
+ {
+ foreach (var name in loggers.Keys)
+ {
+ loggers[name].Clear();
+ xValues[name].Clear();
+ yValues[name].Clear();
+ }
+ chart.Refresh();
+ return;
+ }
+ singleLogger.Clear();
+ xData.Clear();
+ yData.Clear();
+ chart.Refresh();
+ }
+
+ public void AddData(double y)
+ {
+ if (this.multi)
+ {
+ return;
+ }
+
+ this.maxYValue = y > maxYValue ? y : maxYValue;
+ this.minYValue = y < minYValue ? y : minYValue;
+
+ var nowTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ InsertData(xData, yData, nowTime, y);
+
+ singleLogger.Add(new Coordinates(nowTime, y));
+ //Streamer1.Add(new Coordinates(DateTimeOffset.Now.ToUnixTimeSeconds(), y));
+
+ chart.Plot.GetPlottables<Marker>()
+ .ToList()
+ .ForEach(m => m.X -= 1);
+ chart.Plot.GetPlottables<Marker>()
+ .Where(m => m.X < 0)
+ .ToList()
+ .ForEach(m => chart.Plot.Remove(m));
+ //RefreshData();
+ }
+
+ private void InsertData(Queue<long> xAxis, Queue<double> yAxis, long x, double y)
+ {
+ if (xAxis.Count >= maxSize)
+ {
+ xAxis.Dequeue();
+ yAxis.Dequeue();
+ }
+ xAxis.Enqueue(x);
+ yAxis.Enqueue(y);
+ }
+
+ public void AddData(string name, double y)
+ {
+ if (!this.multi)
+ {
+ return;
+ }
+
+ this.maxYValue = y > maxYValue ? y : maxYValue;
+ this.minYValue = y < minYValue ? y : minYValue;
+
+ if (loggers.ContainsKey(name))
+ {
+ var logger = loggers[name];
+ var x = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ logger.Add(new Coordinates(x, y));
+ InsertData(xValues[name], yValues[name], x, y);
+ }
+ else
+ {
+ var logger = InitLogger();
+ logger.LegendText = name;
+ loggers.Add(name, logger);
+ var xAxis = new Queue<long>(maxSize);
+ var yAxis = new Queue<double>(maxSize);
+
+ xValues.Add(name, xAxis);
+ yValues.Add(name, yAxis);
+
+ var x = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ logger.Add(new Coordinates(x, y));
+ InsertData(xAxis, yAxis, x, y);
+ }
+
+ //Streamer1.Add(new Coordinates(DateTimeOffset.Now.ToUnixTimeSeconds(), y));
+
+ chart.Plot.GetPlottables<Marker>()
+ .ToList()
+ .ForEach(m => m.X -= 1);
+ chart.Plot.GetPlottables<Marker>()
+ .Where(m => m.X < 0)
+ .ToList()
+ .ForEach(m => chart.Plot.Remove(m));
+ //RefreshData();
+ }
+
+ private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ //refreshTimer.Start();
+ timer?.Start();
+ }
+
+ private void UserControl_Unloaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ timer?.Stop();
+ }
+
+ private void UserControl_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
+ {
+ if (this.multi) return;
+ chart.Plot.Axes.Left.Label.FontSize = (float)FontSizeConverter.CountFontSize(15, ActualHeight, 92);
+ chart.Plot.Axes.Left.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(10, ActualHeight, 92);
+ chart.Plot.Axes.Bottom.TickLabelStyle.FontSize = (float)FontSizeConverter.CountFontSize(10, ActualHeight, 92);
+ }
+ }
+}
diff --git a/Plugin.TestResult/ChartWindow.xaml b/Plugin.TestResult/ChartWindow.xaml
new file mode 100644
index 0000000..e9e70fa
--- /dev/null
+++ b/Plugin.TestResult/ChartWindow.xaml
@@ -0,0 +1,13 @@
+锘�<Window x:Class="Plugin.TestResult_WPF.ChartWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ Unloaded="Window_Unloaded"
+ Title="{Binding title}" Height="450" Width="800">
+ <UniformGrid x:Name="mainGrid" Columns="1">
+
+ </UniformGrid>
+</Window>
diff --git a/Plugin.TestResult/ChartWindow.xaml.cs b/Plugin.TestResult/ChartWindow.xaml.cs
new file mode 100644
index 0000000..a49535f
--- /dev/null
+++ b/Plugin.TestResult/ChartWindow.xaml.cs
@@ -0,0 +1,45 @@
+锘縰sing System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// ChartWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ChartWindow : Window, INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+ private string _title;
+ public string title
+ {
+ get => _title;
+ set => RaiseAndSetIfchanged(ref _title, value);
+ }
+
+ public ChartWindow(string title)
+ {
+ this.title = $"{title}璇︾粏鏇茬嚎";
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ private void Window_Unloaded(object sender, RoutedEventArgs e)
+ {
+ this.mainGrid.Children.Clear();
+ }
+ }
+}
diff --git a/Plugin.TestResult/Constant/CommonConstant.cs b/Plugin.TestResult/Constant/CommonConstant.cs
new file mode 100644
index 0000000..cb338e3
--- /dev/null
+++ b/Plugin.TestResult/Constant/CommonConstant.cs
@@ -0,0 +1,70 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Plugin.TestResult_WPF.Constant
+{
+ public class CommonStatus
+ {
+ public static readonly string OK = "ok";
+ public static readonly string NG = "ng";
+ public static readonly string WAITING = "waiting";
+ public static readonly string CHECKINFAILED = "checkInFailed";
+ public static readonly string CHECK_IN = "checkIn";
+ public static readonly string TESTING = "testing";
+ public static readonly string ALERT = "alert";
+ public static readonly string READY = "ready";
+
+ private static string[] cache = new string[] { "ok", "ng", "waiting", "checkInFailed", "checkIn", "testing", "alert", "ready" };
+
+ public static readonly Dictionary<string, string> STATUS_MAP = new Dictionary<string, string>() {
+ { "ok","姝e父"},
+ { "ng","寮傚父"},
+ { "waiting","绛夊緟涓�"},
+ { "checkInFailed","CheckIn澶辫触"},
+ { "checkIn","CheckIn"},
+ { "testing","娴嬭瘯涓�"},
+ { "alert","鎶ヨ"},
+ { "ready","鍑嗗灏辩华"},
+ };
+
+ public static readonly Dictionary<string, SolidBrush> COLOR_MAP = new Dictionary<string, SolidBrush>() {
+ { "ok",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "ng",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "waiting",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "testing",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "checkInFailed",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "checkIn",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ };
+
+ public static string GetRandomStatus()
+ {
+ return cache[new Random().Next(cache.Length)];
+ }
+
+ public static string GetStatusDescription(string status)
+ {
+ if (STATUS_MAP.ContainsKey(status)) return STATUS_MAP[status];
+ return "";
+ }
+ }
+
+ public class StatusColorConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is string status)
+ {
+
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugin.TestResult/DataTable.xaml b/Plugin.TestResult/DataTable.xaml
new file mode 100644
index 0000000..3c260c0
--- /dev/null
+++ b/Plugin.TestResult/DataTable.xaml
@@ -0,0 +1,84 @@
+锘�<UserControl x:Class="Plugin.TestResult_WPF.DataTable"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ Background="#FFF"
+ BorderBrush="Black"
+ BorderThickness="1"
+ x:Name="control"
+ Loaded="UserControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ </UserControl.Resources>
+ <Grid x:Name="grid">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="8.5*"/>
+ <RowDefinition Height="1.5*"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid x:Name="infoGrid" Grid.Row="0"
+ Background="LightBlue">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="20" FontWeight="Bold"
+ Padding="0,0,20,0"
+ BorderThickness="0,0,0,1"
+ BorderBrush="Black"
+ VerticalContentAlignment="Center" Background="Transparent" Content="{Binding title}"/>
+ <local:InfoTable x:Name="infoTable" Grid.Row="0" Grid.Column="1"
+ FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+ Converter={StaticResource FontSizeConverter}, ConverterParameter='15,940'}"
+ ></local:InfoTable>
+ </Grid>
+
+ <UniformGrid x:Name="mainGrid" Grid.Row="1" Columns="6" local:GridProperties.ShowBorder="True"
+ local:GridProperties.InnerBorderIgnore="All">
+ </UniformGrid>
+
+ <!--<local:Chart Grid.Row="2" x:Name="chart" BorderThickness="0,1,0,1" BorderBrush="Black"
+ MouseDoubleClick="chart_MouseDoubleClick"/>-->
+
+ <StatusBar Grid.Row="3">
+ <StatusBar.ItemsPanel>
+ <ItemsPanelTemplate>
+ <DockPanel/>
+ </ItemsPanelTemplate>
+ </StatusBar.ItemsPanel>
+ <StatusBarItem DockPanel.Dock="Right">
+ <StackPanel Orientation="Horizontal">
+ <Ellipse Width="10" Height="10">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="Gray"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="ERROR">
+ <Setter Property="Fill" Value="Red"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="RUNNING">
+ <Setter Property="Fill" Value="Green"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <TextBlock Text="{Binding TcpServerInfo}"/>
+ <Button Padding="0" Margin="0" BorderThickness="0" Click="Button_Click">馃攧</Button>
+ </StackPanel>
+ </StatusBarItem>
+
+ <StatusBarItem >
+ <TextBox IsReadOnly="True" Background="Transparent" BorderThickness="0" Text="{Binding statusText}"/>
+ </StatusBarItem>
+ </StatusBar>
+
+ <Button Grid.Row="4" Margin="0" Click="SetStationGlobal_Click" BorderThickness="0,1,0,0">鍚姩</Button>
+ </Grid>
+</UserControl>
\ No newline at end of file
diff --git a/Plugin.TestResult/DataTable.xaml.cs b/Plugin.TestResult/DataTable.xaml.cs
new file mode 100644
index 0000000..e43375f
--- /dev/null
+++ b/Plugin.TestResult/DataTable.xaml.cs
@@ -0,0 +1,285 @@
+锘縰sing Plugin.TestResult_WPF.Model;
+using SuperSocket.SocketBase.Protocol;
+using System;
+using System.ComponentModel;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// DataTable.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class DataTable : UserControl, INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private string _title;
+
+ public string title
+ {
+ get { return _title; }
+ set => RaiseAndSetIfchanged(ref _title, value);
+ }
+
+ private string _statusText;
+
+ public string statusText
+ {
+ get { return _statusText; }
+ set => RaiseAndSetIfchanged(ref _statusText, value);
+ }
+
+ private string tcpServerStatus;
+
+ public string TcpServerStatus
+ {
+ get { return tcpServerStatus; }
+ set { RaiseAndSetIfchanged(ref tcpServerStatus, value); }
+ }
+
+ private string tcpServerInfo = "鏈惎鍔�";
+
+ public string TcpServerInfo
+ {
+ get { return tcpServerInfo; }
+ set { RaiseAndSetIfchanged(ref tcpServerInfo, value); }
+ }
+
+
+ private readonly int index;
+ private readonly int cellCount;
+ private readonly string chartTitle;
+ private readonly TestResultView parent;
+
+ private BaseConfig config;
+ private Chart chart;
+ private Chart multiChart;
+ private SingleCell[] cells;
+
+ private TcpServer tcpServer;
+
+ public DataTable(TestResultView parent,int index, string title, BaseConfig config)
+ {
+ this.config = config;
+ this.index = index;
+ this.parent = parent;
+ this.title = title;
+ this.cellCount = config.PositionCount;
+ this.cells = new SingleCell[cellCount];
+ this.chartTitle = config.MainChartTitle;
+ DataContext = this;
+ InitializeComponent();
+ this.chart = new Chart(this.chartTitle, false, config.MaxSize, config.RefreshInterval);
+ this.multiChart = new Chart(config.DetailChartTitle, true, config.MaxSize, config.RefreshInterval);
+ this.grid.Children.Add(this.chart);
+ Grid.SetRow(this.chart, 2);
+ this.chart.MouseDoubleClick += chart_MouseDoubleClick;
+
+ for (int i = 0; i < this.cellCount; i++)
+ {
+ var cell = new SingleCell(title, i, config.CellListMaxSize);
+ mainGrid.Children.Add(cell);
+ cells[i] = cell;
+ }
+ }
+
+ public int GetSize()
+ {
+ return this.cellCount;
+ }
+
+ public SingleCell GetSingleCell(int index)
+ {
+ return cells[index];
+ }
+
+ public void SetStatusText(string statusText)
+ {
+ this.statusText = statusText;
+ }
+
+ public void SetTemperature(double t)
+ {
+ infoTable.temperature = t;
+ chart.AddData(t);
+ }
+
+ public void SetTemperature(string name, double t)
+ {
+ multiChart.AddData(name, t);
+ }
+
+ public void SetStatus(string status)
+ {
+ infoTable.status = status;
+ }
+
+ public void SetOkCount(int count)
+ {
+ infoTable.okCount = count;
+ }
+
+ public void SetNgCount(int count)
+ {
+ infoTable.ngCount = count;
+ }
+
+ public void SetStartTime(string startTime)
+ {
+ infoTable.startTimeStr = startTime;
+ }
+
+ public void SetEndTime(string endTime)
+ {
+ infoTable.endTimeStr = endTime;
+ }
+
+ public void SetConsumeTime(double consumeTime)
+ {
+ infoTable.consumeTime = consumeTime;
+ }
+
+ private ChartWindow window;
+
+ private void chart_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ /// 鎵撳紑澶氫釜娓╁害鏇茬嚎
+ if (window == null)
+ {
+ window = new ChartWindow(title);
+ window.Owner = Window.GetWindow(this);
+ window.Closed += Window_Closed;
+ window.mainGrid.Children.Add(multiChart);
+ window.Show();
+ }
+ else
+ {
+ window.Activate();
+ }
+ }
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ window = null;
+ }
+
+ private void SetStationGlobal_Click(object sender, RoutedEventArgs e)
+ {
+ ClearChartData();
+ parent.SetStartFlag(this.index, true);
+ }
+
+ /// <summary>
+ /// 娓呯┖涓や釜鍥捐〃鏁版嵁
+ /// </summary>
+ public void ClearChartData()
+ {
+ chart.Clear();
+ multiChart.Clear();
+ }
+
+ private void StartTcpServer()
+ {
+ try
+ {
+ if (tcpServer == null)
+ {
+ tcpServer = new TcpServer();
+ tcpServer.NewRequestReceived += TcpServer_NewRequestReceived;
+ if (!tcpServer.Setup(config.PortStart + index))
+ {
+ ChangeTcpServerStatus("ERROR", "鏈嶅姟璁剧疆寮傚父");
+ return;
+ }
+ if (!tcpServer.Start())
+ {
+ ChangeTcpServerStatus("ERROR", "鏈嶅姟鍚姩寮傚父");
+ return;
+ }
+ ChangeTcpServerStatus("RUNNING", "鏈嶅姟杩愯涓�");
+ }
+ }
+ catch (Exception ex)
+ {
+ ChangeTcpServerStatus("ERROR", $"鏈嶅姟寮傚父锛歿ex.Message}");
+ tcpServer?.Stop();
+ tcpServer = null;
+ }
+ }
+
+ private void StopTcpServer()
+ {
+ if (tcpServer == null) return;
+ try
+ {
+ tcpServer.Stop();
+ tcpServer = null;
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ private void ChangeTcpServerStatus(string status, string info)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ TcpServerStatus = status;
+ TcpServerInfo = info;
+ });
+ }
+
+ private void TcpServer_NewRequestReceived(TcpSession session, StringRequestInfo requestInfo)
+ {
+ string msg = requestInfo.Body;
+ string[] datas_10015 = msg.Split(';');
+ int cellIndex = int.Parse(datas_10015[1]);
+
+ string strs = datas_10015[2];
+ string[] values = strs.Split(',');
+
+ //string step = datas_10015[2];
+ //string result = datas_10015[3];
+ GetSingleCell(cellIndex).SetInfos(new Info
+ {
+ step = values[0],
+ value = values[1],
+ result = values[2],
+ range = values[3],
+ condition = values[4],
+ updateTime = values[5]
+ });
+ session.Send("1");
+ }
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ StartTcpServer();
+ Loaded -= UserControl_Loaded;
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ StartTcpServer();
+ }
+ }
+}
diff --git a/Plugin.TestResult/InfoTable.xaml b/Plugin.TestResult/InfoTable.xaml
new file mode 100644
index 0000000..bb03d5f
--- /dev/null
+++ b/Plugin.TestResult/InfoTable.xaml
@@ -0,0 +1,81 @@
+锘�<UserControl x:Class="Plugin.TestResult_WPF.InfoTable"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <Style TargetType="Label">
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="FontWeight" Value="Bold"/>
+ </Style>
+ <Style TargetType="TextBox">
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="FontWeight" Value="Bold"/>
+ <Setter Property="IsReadOnly" Value="True"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ </Style>
+ </UserControl.Resources>
+ <Grid x:Name="infoGrid" Grid.Row="0" local:GridProperties.ShowBorder="True" local:GridProperties.InnerBorderIgnore="Top,Right">
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*"/>
+ <ColumnDefinition Width="2*"/>
+ <ColumnDefinition Width="1.5*"/>
+ <ColumnDefinition Width="2*"/>
+ <ColumnDefinition Width="1.5*"/>
+ <ColumnDefinition Width="2*"/>
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0" Grid.Column="0">娓╁害</Label>
+ <Label Grid.Row="0" Grid.Column="1" Background="Yellow" Content="{Binding temperatureStr}"/>
+ <Label Grid.Row="0" Grid.Column="2">鐘舵��</Label>
+ <Label Grid.Row="0" Grid.Column="3" Content="{Binding statusStr}">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="FontWeight" Value="Bold"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="ok">
+ <Setter Property="Background" Value="#FF0F8853"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ng">
+ <Setter Property="Background" Value="#fd6b6d"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkInFailed">
+ <Setter Property="Background" Value="#ffac00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkIn">
+ <Setter Property="Background" Value="#FF00E2FF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="testing">
+ <Setter Property="Background" Value="#1296db"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="waiting">
+ <Setter Property="Background" Value="#6e6e6e"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="alert">
+ <Setter Property="Background" Value="#e04733"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ready">
+ <Setter Property="Background" Value="#FF08FF00"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ <Label Grid.Row="0" Grid.Column="4">鑰佸寲鏁伴噺</Label>
+ <Label Grid.Row="0" Grid.Column="5" Background="Yellow" Content="{Binding countStr}"/>
+
+ <Label Grid.Row="1" Grid.Column="0">寮�濮嬫椂闂�</Label>
+ <Label Grid.Row="1" Grid.Column="1" Background="Yellow" Content="{Binding startTimeStr}"/>
+ <Label Grid.Row="1" Grid.Column="2">宸茶�佸寲鏃堕棿</Label>
+ <Label Grid.Row="1" Grid.Column="3" Background="Yellow" Content="{Binding consumeTimeStr}"/>
+ <Label Grid.Row="1" Grid.Column="4">棰勮缁撴潫鏃堕棿</Label>
+ <Label Grid.Row="1" Grid.Column="5" Background="Yellow" Content="{Binding endTimeStr}"/>
+ </Grid>
+</UserControl>
diff --git a/Plugin.TestResult/InfoTable.xaml.cs b/Plugin.TestResult/InfoTable.xaml.cs
new file mode 100644
index 0000000..4bff3b1
--- /dev/null
+++ b/Plugin.TestResult/InfoTable.xaml.cs
@@ -0,0 +1,153 @@
+锘縰sing Plugin.TestResult_WPF.Constant;
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Controls;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// InfoTable.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class InfoTable : UserControl, INotifyPropertyChanged
+ {
+
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private double _temperature;
+ public double temperature
+ {
+ get => _temperature;
+ set
+ {
+ RaiseAndSetIfchanged(ref _temperature, value);
+ RaisePropertyChanged("temperatureStr");
+ }
+ }
+
+ public string temperatureStr
+ {
+ get => $"{_temperature.ToString("f2")}鈩�";
+ }
+
+ private string _status;
+ public string status
+ {
+ get => _status;
+ set
+ {
+ RaiseAndSetIfchanged(ref _status, value);
+ RaisePropertyChanged("statusStr");
+ }
+ }
+
+ public string statusStr
+ {
+ get => status != null && CommonStatus.STATUS_MAP.ContainsKey(status) ? CommonStatus.STATUS_MAP[status] : "";
+ }
+
+ private int _okCount;
+ public int okCount
+ {
+ get => _okCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref _okCount, value);
+ RefreshCount();
+ }
+ }
+
+ private int _ngCount;
+
+ public int ngCount
+ {
+ get => _ngCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref _ngCount, value);
+ RefreshCount();
+ }
+ }
+
+ private int _allCount;
+
+ public int allCount
+ {
+ get => _allCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref _allCount, value);
+ }
+ }
+
+ public string countStr
+ {
+ get => $"OK:{okCount},NG:{ngCount},ALL:{allCount}";
+ }
+
+ private string _startTimeStr;
+ public string startTimeStr
+ {
+ get => _startTimeStr;
+ set
+ {
+ RaiseAndSetIfchanged(ref _startTimeStr, value);
+ }
+ }
+
+ private double _consumeTime;
+ public double consumeTime
+ {
+ get => _consumeTime;
+ set
+ {
+ RaiseAndSetIfchanged(ref _consumeTime, value);
+ RaisePropertyChanged("consumeTimeStr");
+ }
+ }
+
+ public string consumeTimeStr
+ {
+ get
+ {
+ if (consumeTime < 60) return $"{consumeTime.ToString("f2")}s";
+ else if (consumeTime < 3600) return $"{Math.Floor(consumeTime / 60)}m{(consumeTime % 60).ToString("f2")}s";
+ return $"{Math.Floor(consumeTime / 3600)}h{Math.Floor((consumeTime % 3600) / 60)}m{(consumeTime % 60).ToString("f2")}s";
+ }
+ }
+
+ private string _endTimeStr;
+
+ public string endTimeStr
+ {
+ get => _endTimeStr;
+ set => RaiseAndSetIfchanged(ref _endTimeStr, value);
+ }
+
+
+ private void RefreshCount()
+ {
+ this.allCount = this.okCount + this.ngCount;
+ RaisePropertyChanged("countStr");
+ }
+
+ public InfoTable()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Plugin.TestResult/InfoWindow.xaml b/Plugin.TestResult/InfoWindow.xaml
new file mode 100644
index 0000000..e80ad29
--- /dev/null
+++ b/Plugin.TestResult/InfoWindow.xaml
@@ -0,0 +1,25 @@
+锘�<Window x:Class="Plugin.TestResult_WPF.InfoWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ Title="{Binding title}" Height="500" Width="800">
+ <DataGrid ItemsSource="{Binding dataSource}" AutoGenerateColumns="False"
+ CanUserAddRows="False"
+ CanUserDeleteRows="False"
+ IsReadOnly="True"
+ ColumnWidth="*"
+ FontSize="16"
+ >
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="娴嬭瘯椤瑰悕绉�" Binding="{Binding step}"/>
+ <DataGridTextColumn Header="娴嬭瘯鍊�" Binding="{Binding value}"/>
+ <DataGridTextColumn Header="娴嬭瘯缁撴灉" Binding="{Binding result}"/>
+ <DataGridTextColumn Header="娴嬭瘯鑼冨洿" Binding="{Binding range}"/>
+ <DataGridTextColumn Header="娴嬭瘯鏉′欢" Binding="{Binding condition}"/>
+ <DataGridTextColumn Header="鏇存柊鏃堕棿" Binding="{Binding updateTime}"/>
+ </DataGrid.Columns>
+ </DataGrid>
+</Window>
diff --git a/Plugin.TestResult/InfoWindow.xaml.cs b/Plugin.TestResult/InfoWindow.xaml.cs
new file mode 100644
index 0000000..bb085f8
--- /dev/null
+++ b/Plugin.TestResult/InfoWindow.xaml.cs
@@ -0,0 +1,58 @@
+锘縰sing Plugin.TestResult_WPF.Model;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// InfoWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class InfoWindow : Window, INotifyPropertyChanged
+ {
+
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private string _title;
+ public string title
+ {
+ get => _title;
+ set => RaiseAndSetIfchanged(ref _title, value);
+ }
+
+ private ObservableCollection<Info> _dataSource;
+
+ public ObservableCollection<Info> dataSource
+ {
+ get => _dataSource == null ? new ObservableCollection<Info>() : _dataSource;
+ set => RaiseAndSetIfchanged(ref _dataSource, value);
+ }
+
+ public InfoWindow(string title, ObservableCollection<Info> infos)
+ {
+ this.title = title;
+ this.dataSource = infos;
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ public void UpdateSource(ObservableCollection<Info> infos)
+ {
+ this.dataSource = infos;
+ }
+ }
+}
diff --git a/Plugin.TestResult/Model/BaseConfig.cs b/Plugin.TestResult/Model/BaseConfig.cs
new file mode 100644
index 0000000..4e0d5e0
--- /dev/null
+++ b/Plugin.TestResult/Model/BaseConfig.cs
@@ -0,0 +1,157 @@
+锘縰sing System.Collections;
+using System.Configuration;
+using System.Runtime.CompilerServices;
+
+namespace Plugin.TestResult_WPF.Model
+{
+ public class BaseConfig
+ {
+ private static Hashtable customConfig = (Hashtable)ConfigurationManager.GetSection("TestResultConfig");
+ /// <summary>
+ /// 棣栭〉甯冨眬琛屾暟
+ /// </summary>
+ private int row = 1;
+ public int Row
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? row : int.Parse(data);
+ }
+ }
+
+ private string GetValue([CallerMemberName] string propertyName = null)
+ {
+ return (customConfig != null && customConfig.ContainsKey(propertyName)) ? customConfig[propertyName].ToString() : null;
+ }
+
+ /// <summary>
+ /// 棣栭〉甯冨眬鍒楁暟
+ /// </summary>
+ private int column = 2;
+ public int Column
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? column : int.Parse(data);
+ }
+ }
+
+ /// <summary>
+ /// 鐐夋暟 -1 灏辨槸row*column
+ /// </summary>
+ private int cellCount = -1;
+ public int CellCount
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? cellCount : int.Parse(data);
+ }
+ }
+
+ /// <summary>
+ /// 姣忎釜鐐夊瓙鐨勭偣浣嶆暟
+ /// </summary>
+ private int positionCount = 54;
+ public int PositionCount
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? positionCount : int.Parse(data);
+ }
+ }
+
+ /// <summary>
+ /// 鏇茬嚎鏈�澶氫繚瀛樺灏戞暟鎹�
+ /// </summary>
+ private int maxSize = 10000;
+ public int MaxSize
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? maxSize : int.Parse(data);
+ }
+ }
+
+ /// <summary>
+ /// 鍥捐〃鍒锋柊棰戠巼 ms
+ /// </summary>
+ private int refreshInterval = 500;
+ public int RefreshInterval
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? refreshInterval : int.Parse(data);
+ }
+ }
+
+ /// <summary>
+ /// 鐐夊瓙鍚嶇О
+ /// </summary>
+ private string nameStr = "A,B,C,D,E,F,G";
+ public string NameStr
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? nameStr : data;
+ }
+ }
+
+ /// <summary>
+ /// 榛樿灞曠ず鐨勫浘琛ㄦ爣棰�
+ /// </summary>
+ private string mainChartTitle = "骞冲潎娓╁害";
+ public string MainChartTitle
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? mainChartTitle : data;
+ }
+ }
+
+ /// <summary>
+ /// 鍙屽嚮鎵撳紑鐨勮缁嗗浘琛ㄦ爣棰�
+ /// </summary>
+ private string detailChartTitle = "璇︾粏娓╁害";
+ public string DetailChartTitle
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? detailChartTitle : data;
+ }
+ }
+
+ /// <summary>
+ /// 绌翠綅Step鍒楄〃鏈�澶у閲�
+ /// </summary>
+ private int cellListMaxSize = 10000;
+ public int CellListMaxSize
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? cellListMaxSize : int.Parse(data);
+ }
+ }
+
+ private int portStart = 6660;
+ public int PortStart
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? portStart : int.Parse(data);
+ }
+ }
+
+ public bool testing = false;
+ }
+}
diff --git a/Plugin.TestResult/Model/BaseModel.cs b/Plugin.TestResult/Model/BaseModel.cs
new file mode 100644
index 0000000..eae935b
--- /dev/null
+++ b/Plugin.TestResult/Model/BaseModel.cs
@@ -0,0 +1,21 @@
+锘縰sing System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace Plugin.TestResult_WPF.Model
+{
+ public class BaseModel : INotifyPropertyChanged
+ {
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ }
+}
diff --git a/Plugin.TestResult/Model/CellInfo.cs b/Plugin.TestResult/Model/CellInfo.cs
new file mode 100644
index 0000000..a463bc9
--- /dev/null
+++ b/Plugin.TestResult/Model/CellInfo.cs
@@ -0,0 +1,9 @@
+锘縩amespace Plugin.TestResult_WPF.Model
+{
+ public class CellInfo
+ {
+ public string MachineName { get; set; }
+ public string OvenName { get; set; }
+ public int Index { get; set; }
+ }
+}
diff --git a/Plugin.TestResult/Model/DataTableModel.cs b/Plugin.TestResult/Model/DataTableModel.cs
new file mode 100644
index 0000000..3e37ba9
--- /dev/null
+++ b/Plugin.TestResult/Model/DataTableModel.cs
@@ -0,0 +1,7 @@
+锘縩amespace Plugin.TestResult_WPF.Model
+{
+ public class DataTableModel : BaseModel
+ {
+
+ }
+}
diff --git a/Plugin.TestResult/Model/Info.cs b/Plugin.TestResult/Model/Info.cs
new file mode 100644
index 0000000..5874718
--- /dev/null
+++ b/Plugin.TestResult/Model/Info.cs
@@ -0,0 +1,60 @@
+锘縩amespace Plugin.TestResult_WPF.Model
+{
+ public class Info : BaseModel
+ {
+ private string _step;
+
+ public string step
+ {
+ get => _step;
+
+ set => RaiseAndSetIfchanged(ref _step, value);
+ }
+
+ private string _value;
+
+ public string value
+ {
+ get => _value;
+
+ set => RaiseAndSetIfchanged(ref _value, value);
+ }
+
+ private string _result;
+
+ public string result
+ {
+ get => _result;
+
+ set => RaiseAndSetIfchanged(ref _result, value);
+ }
+
+ private string _range;
+
+ public string range
+ {
+ get => _range;
+
+ set => RaiseAndSetIfchanged(ref _range, value);
+ }
+
+ private string _condition;
+
+ public string condition
+ {
+ get => _condition;
+
+ set => RaiseAndSetIfchanged(ref _condition, value);
+ }
+
+ private string _updateTime;
+
+ public string updateTime
+ {
+ get => _updateTime;
+
+ set => RaiseAndSetIfchanged(ref _updateTime, value);
+ }
+
+ }
+}
diff --git a/Plugin.TestResult/Model/TcpServer.cs b/Plugin.TestResult/Model/TcpServer.cs
new file mode 100644
index 0000000..c1c0911
--- /dev/null
+++ b/Plugin.TestResult/Model/TcpServer.cs
@@ -0,0 +1,41 @@
+锘縰sing ScottPlot.Colormaps;
+using SuperSocket.SocketBase;
+using SuperSocket.SocketBase.Protocol;
+using System;
+using System.Text;
+
+namespace Plugin.TestResult_WPF.Model
+{
+ public class DTReceiveFilter : ReceiveFilterBase<StringRequestInfo>
+ {
+ public override StringRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
+ {
+ rest = 0;
+ StringBuilder sb = new StringBuilder();
+ int i = offset;
+ while (i < readBuffer.Length)
+ {
+ byte b = readBuffer[i++];
+ if (b == '\n')
+ {
+ break;
+ }
+ sb.Append((char)b);
+ }
+ return new StringRequestInfo(DateTime.Now + "", sb.ToString(), null);
+ }
+ }
+
+ public class TcpServer : AppServer<TcpSession>
+ {
+ public TcpServer() : base(new DefaultReceiveFilterFactory<DTReceiveFilter, StringRequestInfo>())
+ {
+
+ }
+ }
+
+ public class TcpSession : AppSession<TcpSession, StringRequestInfo>
+ {
+
+ }
+}
diff --git a/Plugin.TestResult/OpenTK.dll.config b/Plugin.TestResult/OpenTK.dll.config
new file mode 100644
index 0000000..7098d39
--- /dev/null
+++ b/Plugin.TestResult/OpenTK.dll.config
@@ -0,0 +1,25 @@
+<configuration>
+ <dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
+ <dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
+ <dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
+ <dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
+ <dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
+ <dllmap os="linux" dll="libX11" target="libX11.so.6"/>
+ <dllmap os="linux" dll="libXi" target="libXi.so.6"/>
+ <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
+ <dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
+ <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
+ <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
+ <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
+ <dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
+ <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
+ <dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
+ <dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
+ <!-- XQuartz compatibility (X11 on Mac) -->
+ <dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
+ <dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
+ <dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
+ <dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
+ <dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
+ <dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
+</configuration>
diff --git a/Plugin.TestResult/Plugin.TestResult.csproj b/Plugin.TestResult/Plugin.TestResult.csproj
new file mode 100644
index 0000000..d66425d
--- /dev/null
+++ b/Plugin.TestResult/Plugin.TestResult.csproj
@@ -0,0 +1,313 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{7375B74C-B6BF-4814-9838-E1CAACAD1897}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <RootNamespace>Plugin.TestResult</RootNamespace>
+ <AssemblyName>Plugin.TestResult</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <Deterministic>true</Deterministic>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <LangVersion>7.3</LangVersion>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <LangVersion>7.3</LangVersion>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="CommonLibs">
+ <HintPath>..\Libs\CommonLibs.dll</HintPath>
+ </Reference>
+ <Reference Include="GLWpfControl, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\OpenTK.GLWpfControl.3.3.0\lib\net452\GLWpfControl.dll</HintPath>
+ </Reference>
+ <Reference Include="HarfBuzzSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\HarfBuzzSharp.7.3.0.3\lib\net462\HarfBuzzSharp.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.AdapterAPI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.AdapterAPI.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.API, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.SequenceAnalyzer, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.SequenceAnalyzer.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.Support, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.Support.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Utility">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Utility.dll</HintPath>
+ </Reference>
+ <Reference Include="OpenTK, Version=3.3.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\OpenTK.3.3.1\lib\net20\OpenTK.dll</HintPath>
+ </Reference>
+ <Reference Include="ParameterHelper">
+ <HintPath>..\Libs\ParameterHelper.dll</HintPath>
+ </Reference>
+ <Reference Include="ScottPlot, Version=5.0.47.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\ScottPlot.5.0.47\lib\net462\ScottPlot.dll</HintPath>
+ </Reference>
+ <Reference Include="ScottPlot.WPF, Version=5.0.47.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\ScottPlot.WPF.5.0.47\lib\net462\ScottPlot.WPF.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.2.88.9\lib\net462\SkiaSharp.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp.HarfBuzz, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.HarfBuzz.2.88.9\lib\net462\SkiaSharp.HarfBuzz.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp.Views.Desktop.Common, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.Views.Desktop.Common.2.88.9\lib\net462\SkiaSharp.Views.Desktop.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp.Views.WPF, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.Views.WPF.2.88.9\lib\net462\SkiaSharp.Views.WPF.dll</HintPath>
+ </Reference>
+ <Reference Include="SuperSocket.Facility">
+ <HintPath>..\Libs\SuperSocket.Facility.dll</HintPath>
+ </Reference>
+ <Reference Include="SuperSocket.SocketBase">
+ <HintPath>..\Libs\SuperSocket.SocketBase.dll</HintPath>
+ </Reference>
+ <Reference Include="SuperSocket.SocketEngine">
+ <HintPath>..\Libs\SuperSocket.SocketEngine.dll</HintPath>
+ </Reference>
+ <Reference Include="SupersocketCommon">
+ <HintPath>..\Libs\SupersocketCommon.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Drawing.Common, Version=4.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Drawing.Common.4.7.3\lib\net461\System.Drawing.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+ </Reference>
+ <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ <Reference Include="WindowsFormsIntegration" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ChartWindow.xaml.cs">
+ <DependentUpon>ChartWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Constant\CommonConstant.cs" />
+ <Compile Include="Model\BaseConfig.cs" />
+ <Compile Include="Model\CellInfo.cs" />
+ <Compile Include="Model\Info.cs" />
+ <Compile Include="Model\TcpServer.cs" />
+ <Compile Include="Scanner.xaml.cs">
+ <DependentUpon>Scanner.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Util\CommonCodeParser.cs" />
+ <Compile Include="Util\FontSizeConverter.cs" />
+ <Compile Include="ViewControl.xaml.cs">
+ <DependentUpon>ViewControl.xaml</DependentUpon>
+ </Compile>
+ <Page Include="Chart.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="ChartWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="DataTable.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="InfoTable.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="InfoWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Scanner.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="SingleCell.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="TestResultView.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Compile Include="Chart.xaml.cs">
+ <DependentUpon>Chart.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="DataTable.xaml.cs">
+ <DependentUpon>DataTable.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Util\DpUtil.cs" />
+ <Compile Include="InfoTable.xaml.cs">
+ <DependentUpon>InfoTable.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="InfoWindow.xaml.cs">
+ <DependentUpon>InfoWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Model\BaseModel.cs" />
+ <Compile Include="Model\DataTableModel.cs" />
+ <Compile Include="SingleCell.xaml.cs">
+ <DependentUpon>SingleCell.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="TestResultView.xaml.cs">
+ <DependentUpon>TestResultView.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ <Page Include="ViewControl.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="OpenTK.dll.config" />
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resource\checkInFailed2.png" />
+ <Resource Include="Resource\ng2.png" />
+ <Resource Include="Resource\ok2.png" />
+ <Resource Include="Resource\testing2.png" />
+ <Resource Include="Resource\waiting2.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resource\alert.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resource\checkIn.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resource\ready.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Resource\barcode.png" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>杩欏彴璁$畻鏈轰笂缂哄皯姝ら」鐩紩鐢ㄧ殑 NuGet 绋嬪簭鍖呫�備娇鐢ㄢ�淣uGet 绋嬪簭鍖呰繕鍘熲�濆彲涓嬭浇杩欎簺绋嬪簭鍖呫�傛湁鍏虫洿澶氫俊鎭紝璇峰弬瑙� http://go.microsoft.com/fwlink/?LinkID=322105銆傜己灏戠殑鏂囦欢鏄� {0}銆�</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets'))" />
+ </Target>
+ <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" />
+ <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" />
+ <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" />
+ <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" />
+ <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" />
+ <PropertyGroup>
+ <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
+copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/Plugin.TestResult/Properties/AssemblyInfo.cs b/Plugin.TestResult/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9948624
--- /dev/null
+++ b/Plugin.TestResult/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+锘縰sing System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("Plugin.TestResult_WPF")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Plugin.TestResult_WPF")]
+[assembly: AssemblyCopyright("Copyright 漏 2024")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+//鑻ヨ寮�濮嬬敓鎴愬彲鏈湴鍖栫殑搴旂敤绋嬪簭锛岃璁剧疆
+//.csproj 鏂囦欢涓殑 <UICulture>CultureYouAreCodingWith</UICulture>
+//鍦� <PropertyGroup> 涓�備緥濡傦紝濡傛灉浣犱娇鐢ㄧ殑鏄編鍥借嫳璇��
+//浣跨敤鐨勬槸缇庡浗鑻辫锛岃灏� <UICulture> 璁剧疆涓� en-US銆� 鐒跺悗鍙栨秷
+//瀵逛互涓� NeutralResourceLanguage 鐗规�х殑娉ㄩ噴銆� 鏇存柊
+//浠ヤ笅琛屼腑鐨勨�渆n-US鈥濅互鍖归厤椤圭洰鏂囦欢涓殑 UICulture 璁剧疆銆�
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //涓婚鐗瑰畾璧勬簮璇嶅吀鎵�澶勪綅缃�
+ //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+ //鎴栧簲鐢ㄧ▼搴忚祫婧愬瓧鍏镐腑鎵惧埌鏃朵娇鐢�)
+ ResourceDictionaryLocation.SourceAssembly //甯歌璧勬簮璇嶅吀鎵�澶勪綅缃�
+ //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+ //銆佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚涓撶敤璧勬簮瀛楀吀涓壘鍒版椂浣跨敤)
+)]
+
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�:
+//
+// 涓荤増鏈�
+// 娆$増鏈�
+// 鐢熸垚鍙�
+// 淇鍙�
+//
+//鍙互鎸囧畾鎵�鏈夎繖浜涘�硷紝涔熷彲浠ヤ娇鐢ㄢ�滅敓鎴愬彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊�
+//閫氳繃浣跨敤 "*"锛屽涓嬫墍绀�:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Plugin.TestResult/Properties/Resources.Designer.cs b/Plugin.TestResult/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..e6971ee
--- /dev/null
+++ b/Plugin.TestResult/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+// 姝や唬鐮佺敱宸ュ叿鐢熸垚銆�
+// 杩愯鏃剁増鏈�: 4.0.30319.42000
+//
+// 瀵规鏂囦欢鐨勬洿鏀瑰彲鑳藉鑷翠笉姝g‘鐨勮涓猴紝濡傛灉
+// 閲嶆柊鐢熸垚浠g爜锛屽垯鎵�鍋氭洿鏀瑰皢涓㈠け銆�
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Plugin.TestResult_WPF.Properties {
+
+
+ /// <summary>
+ /// 寮虹被鍨嬭祫婧愮被锛岀敤浜庢煡鎵炬湰鍦板寲瀛楃涓茬瓑銆�
+ /// </summary>
+ // 姝ょ被鏄敱 StronglyTypedResourceBuilder
+ // 绫婚�氳繃绫讳技浜� ResGen 鎴� Visual Studio 鐨勫伐鍏疯嚜鍔ㄧ敓鎴愮殑銆�
+ // 鑻ヨ娣诲姞鎴栫Щ闄ゆ垚鍛橈紝璇风紪杈� .ResX 鏂囦欢锛岀劧鍚庨噸鏂拌繍琛� ResGen
+ // (浠� /str 浣滀负鍛戒护閫夐」)锛屾垨閲嶆柊鐢熸垚 VS 椤圭洰銆�
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// 杩斿洖姝ょ被浣跨敤鐨勭紦瀛� ResourceManager 瀹炰緥銆�
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if ((resourceMan == null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plugin.TestResult_WPF.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// 閲嶅啓褰撳墠绾跨▼鐨� CurrentUICulture 灞炴�э紝瀵�
+ /// 浣跨敤姝ゅ己绫诲瀷璧勬簮绫荤殑鎵�鏈夎祫婧愭煡鎵炬墽琛岄噸鍐欍��
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Plugin.TestResult/Properties/Resources.resx b/Plugin.TestResult/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Plugin.TestResult/Properties/Resources.resx
@@ -0,0 +1,117 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/Plugin.TestResult/Properties/Settings.Designer.cs b/Plugin.TestResult/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..45f5698
--- /dev/null
+++ b/Plugin.TestResult/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Plugin.TestResult_WPF.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Plugin.TestResult/Properties/Settings.settings b/Plugin.TestResult/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/Plugin.TestResult/Properties/Settings.settings
@@ -0,0 +1,7 @@
+锘�<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
\ No newline at end of file
diff --git a/Plugin.TestResult/Resource/alert.png b/Plugin.TestResult/Resource/alert.png
new file mode 100644
index 0000000..6a9e531
--- /dev/null
+++ b/Plugin.TestResult/Resource/alert.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/barcode.png b/Plugin.TestResult/Resource/barcode.png
new file mode 100644
index 0000000..b68a9d6
--- /dev/null
+++ b/Plugin.TestResult/Resource/barcode.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/checkIn.png b/Plugin.TestResult/Resource/checkIn.png
new file mode 100644
index 0000000..eb4f984
--- /dev/null
+++ b/Plugin.TestResult/Resource/checkIn.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/checkInFailed2.png b/Plugin.TestResult/Resource/checkInFailed2.png
new file mode 100644
index 0000000..b4e6cfd
--- /dev/null
+++ b/Plugin.TestResult/Resource/checkInFailed2.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/ng2.png b/Plugin.TestResult/Resource/ng2.png
new file mode 100644
index 0000000..b1da88a
--- /dev/null
+++ b/Plugin.TestResult/Resource/ng2.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/ok2.png b/Plugin.TestResult/Resource/ok2.png
new file mode 100644
index 0000000..637da7a
--- /dev/null
+++ b/Plugin.TestResult/Resource/ok2.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/ready.png b/Plugin.TestResult/Resource/ready.png
new file mode 100644
index 0000000..df8dfd3
--- /dev/null
+++ b/Plugin.TestResult/Resource/ready.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/testing2.png b/Plugin.TestResult/Resource/testing2.png
new file mode 100644
index 0000000..531bff9
--- /dev/null
+++ b/Plugin.TestResult/Resource/testing2.png
Binary files differ
diff --git a/Plugin.TestResult/Resource/waiting2.png b/Plugin.TestResult/Resource/waiting2.png
new file mode 100644
index 0000000..2fd9c21
--- /dev/null
+++ b/Plugin.TestResult/Resource/waiting2.png
Binary files differ
diff --git a/Plugin.TestResult/Scanner.xaml b/Plugin.TestResult/Scanner.xaml
new file mode 100644
index 0000000..3a7c2ad
--- /dev/null
+++ b/Plugin.TestResult/Scanner.xaml
@@ -0,0 +1,54 @@
+锘�<Window x:Class="Plugin.TestResult_WPF.Scanner"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ WindowStartupLocation="CenterScreen"
+ Closing="Window_Closing"
+ mc:Ignorable="d"
+ Title="{Binding title}" Height="450" Width="800">
+ <Window.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalAlignment" Value="Right"/>
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" />
+ </Style>
+ <Style TargetType="TextBox">
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" />
+ </Style>
+ <Style TargetType="Button">
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" />
+ </Style>
+ </Window.Resources>
+
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition />
+ <!--<RowDefinition />-->
+ <RowDefinition />
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalContentAlignment="Center" HorizontalAlignment="Stretch">璇蜂緷娆℃壂涓嬪垪鏉$爜</Label>
+ <Label Grid.Row="1" Grid.Column="0">鍌ㄤ綅鏉$爜</Label>
+ <!--<Label Grid.Row="2" Grid.Column="0">澶瑰叿鏉$爜</Label>-->
+ <Label Grid.Row="2" Grid.Column="0">浜у搧鏉$爜</Label>
+
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="positionText" TextWrapping="NoWrap"/>
+ <!--<TextBox Grid.Row="2" Grid.Column="1"/>-->
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="snrText"/>
+
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2">
+ <Button Margin="20" Padding="15" Click="Con_Click">缁х画鎵弿</Button>
+ <Button Margin="20" Padding="15" Click="Ok_Click">鎵弿瀹屾垚</Button>
+ </StackPanel>
+ </Grid>
+</Window>
diff --git a/Plugin.TestResult/Scanner.xaml.cs b/Plugin.TestResult/Scanner.xaml.cs
new file mode 100644
index 0000000..7e80db7
--- /dev/null
+++ b/Plugin.TestResult/Scanner.xaml.cs
@@ -0,0 +1,216 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO.Ports;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace Plugin.TestResult_WPF
+{
+ public class BarcodeEventArg
+ {
+ public string name { get; private set; }
+ public string positionCode { get; private set; }
+ public string snrCode { get; private set; }
+
+ public BarcodeEventArg(string name, string positionCode, string snrCode)
+ {
+ this.name = name;
+ this.positionCode = positionCode;
+ this.snrCode = snrCode;
+ }
+ }
+
+ /// <summary>
+ /// Scanner.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class Scanner : Window, INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private string _title;
+
+ public string title
+ {
+ get { return _title; }
+ set => RaiseAndSetIfchanged(ref _title, value);
+ }
+
+ public event EventHandler<BarcodeEventArg> FinishBarcode;
+
+ private DataTable dataTable;
+ SerialPort serialPort;
+ public Scanner(string title)
+ {
+ this.title = title;
+ this.DataContext = this;
+ InitializeComponent();
+ InitScanner();
+ }
+
+ /// <summary>
+ /// 璁剧疆鎵爜鏋�
+ /// </summary>
+ private void InitScanner()
+ {
+ string comStr = "";
+ if (serialPort != null) return;
+ if (this.title == "涓�鍖烘壂鐮�")
+ {
+ comStr = "COM1";
+ }
+ else
+ {
+ comStr = "COM2";
+ }
+
+ // 閰嶇疆涓插彛
+ serialPort = new SerialPort
+ {
+ PortName = comStr,
+ BaudRate = 115200,
+ Parity = Parity.None,
+ DataBits = 8,
+ StopBits = StopBits.One,
+ Handshake = Handshake.None,
+ DtrEnable = true,
+ RtsEnable = true
+ //ReadTimeout = 500,
+ //WriteTimeout = 500,
+ //ReciveBufferSize=4096
+ };
+
+ try
+ {
+ // 鎵撳紑涓插彛
+ serialPort.Open();
+ // 娉ㄥ唽鎺ユ敹鏁版嵁浜嬩欢
+ serialPort.DataReceived += SerialPort_DataReceived;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"鍒濆鍖栨壂鐮佹灙澶辫触锛亄ex.StackTrace}");
+ }
+ }
+
+ private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
+ {
+ try
+ {
+ SerialPort sp = (SerialPort)sender;
+ string barcode = ReadDataFrom(sp);
+
+ //string barcode =
+ Dispatcher.Invoke(() =>
+ {
+ if (snrText.IsFocused)
+ {
+ snrText.Text = barcode;
+ Con_Click(null, null);
+ }
+ else
+ {
+ positionText.Text = barcode;
+ //positionText.Focus();
+ //snrText.Text = "";
+ snrText.Focus();
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"鑾峰彇鎵爜鏋暟鎹け璐ワ紒{ex.StackTrace}");
+ }
+ }
+
+ private void Con_Click(object sender, RoutedEventArgs e)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ string position = positionText.Text, snr = snrText.Text;
+ if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
+ {
+ MessageBox.Show("璇疯緭鍏ュ偍浣嶆潯鐮佸拰浜у搧鏉$爜");
+ return;
+ }
+ try
+ {
+ FinishBarcode.Invoke(this, new BarcodeEventArg(title, position, snr));
+ //positionText.Text = "";
+ //snrText.Text = "";
+ positionText.Focus();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ });
+ }
+
+ private void Ok_Click(object sender, RoutedEventArgs e)
+ {
+ string position = positionText.Text, snr = snrText.Text;
+ if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
+ {
+ MessageBox.Show("璇疯緭鍏ュ偍浣嶆潯鐮佸拰浜у搧鏉$爜");
+ return;
+ }
+ try
+ {
+ FinishBarcode.Invoke(this, new BarcodeEventArg(title, position, snr));
+ this.Close();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ private string ReadDataFrom(SerialPort sp)
+ {
+ string barcode = "";
+ while (sp.BytesToRead > 0)
+ {
+ byte[] buffer = new byte[sp.BytesToRead];
+ sp.Read(buffer, 0, buffer.Length);
+ barcode += System.Text.Encoding.UTF8.GetString(buffer);
+ System.Threading.Thread.Sleep(50);
+ }
+ return barcode;
+ }
+
+ private void Window_Closing(object sender, CancelEventArgs e)
+ {
+ try
+ {
+ serialPort.Close();
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+ }
+}
diff --git a/Plugin.TestResult/SingleCell.xaml b/Plugin.TestResult/SingleCell.xaml
new file mode 100644
index 0000000..35448dc
--- /dev/null
+++ b/Plugin.TestResult/SingleCell.xaml
@@ -0,0 +1,101 @@
+锘�<UserControl x:Class="Plugin.TestResult_WPF.SingleCell"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ x:Name="uc"
+ Padding="5"
+ MouseDoubleClick="UserControl_MouseDoubleClick"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ </UserControl.Resources>
+
+ <UserControl.ToolTip>
+ <ToolTip Padding="5" BorderThickness="1" BorderBrush="Black" Background="Yellow" Content="{Binding tooltipContent}"/>
+ </UserControl.ToolTip>
+
+ <UserControl.Style>
+ <Style TargetType="UserControl">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="ok">
+ <Setter Property="Background" Value="#FF0F8853"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ng">
+ <Setter Property="Background" Value="#fd6b6d"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkInFailed">
+ <Setter Property="Background" Value="#ffac00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkIn">
+ <Setter Property="Background" Value="#FF00E2FF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="testing">
+ <Setter Property="Background" Value="#1296db"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="waiting">
+ <Setter Property="Background" Value="#6e6e6e"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="alert">
+ <Setter Property="Background" Value="#e04733"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ready">
+ <Setter Property="Background" Value="#FF08FF00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="hadCode">
+ <Setter Property="Background" Value="#FFF"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </UserControl.Style>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <!--<TextBox Grid.Row="0" IsReadOnly="True" TextAlignment="Center" Margin="0,0,0,3" FontSize="15"
+ Background="Transparent" BorderThickness="0" Text="{Binding title}"/>-->
+ <Label Grid.Row="0" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Padding="0" Margin="0,0,0,3"
+ FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+ Converter={StaticResource FontSizeConverter}, ConverterParameter='15,103'}"
+ FontWeight="Bold"
+ Background="Transparent" BorderThickness="0" Content="{Binding title}"/>
+ <Image Grid.Row="1">
+ <Image.Style>
+ <Style TargetType="Image">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="ok">
+ <Setter Property="Source" Value="Resource/ok2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ng">
+ <Setter Property="Source" Value="Resource/ng2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkInFailed">
+ <Setter Property="Source" Value="Resource/checkInFailed2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkIn">
+ <Setter Property="Source" Value="Resource/checkIn.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="testing">
+ <Setter Property="Source" Value="Resource/testing2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="waiting">
+ <Setter Property="Source" Value="Resource/waiting2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="alert">
+ <Setter Property="Source" Value="Resource/alert.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ready">
+ <Setter Property="Source" Value="Resource/ready.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="hadCode">
+ <Setter Property="Source" Value="Resource/barcode.png"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Image.Style>
+ </Image>
+ </Grid>
+</UserControl>
diff --git a/Plugin.TestResult/SingleCell.xaml.cs b/Plugin.TestResult/SingleCell.xaml.cs
new file mode 100644
index 0000000..b218e98
--- /dev/null
+++ b/Plugin.TestResult/SingleCell.xaml.cs
@@ -0,0 +1,195 @@
+锘縰sing Plugin.TestResult_WPF.Constant;
+using Plugin.TestResult_WPF.Model;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// SingleCell.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class SingleCell : UserControl, INotifyPropertyChanged
+ {
+
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private InfoWindow window;
+ private int maxSize;
+
+ public SingleCell()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ public SingleCell(string parentName, int index,int maxSize)
+ {
+ this.parentName = parentName;
+ this.index = index;
+ this.maxSize = maxSize;
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ private string _parentName;
+ public string parentName
+ {
+ get { return _parentName; }
+ set
+ {
+ RaiseAndSetIfchanged(ref _parentName, value);
+ RaisePropertyChanged("title");
+ }
+ }
+
+ private int _index;
+
+ public int index
+ {
+ get { return _index; }
+ set
+ {
+ RaiseAndSetIfchanged(ref _index, value);
+ RaisePropertyChanged("title");
+ }
+ }
+
+ public string title => $"{parentName}{index + 1}";
+
+ private string _status = CommonStatus.WAITING;
+
+ public string tooltipContent
+ {
+ get
+ {
+ string dataStr = "";
+ if (infos != null && infos.Count > 0)
+ {
+ foreach (var info in infos)
+ {
+ dataStr += $"\r\nStep:{info.step},Result:{info.result}";
+ }
+ }
+ return $"{title}\r\n鐘舵��:{CommonStatus.GetStatusDescription(status)}{dataStr}";
+ }
+ }
+
+ public string status
+ {
+ get { return _status; }
+ set => RaiseAndSetIfchanged(ref _status, value);
+ }
+
+ private ConcurrentQueue<Info> queue = new ConcurrentQueue<Info>();
+
+ private ObservableCollection<Info> _infos;
+
+ public ObservableCollection<Info> infos
+ {
+ get => _infos;
+ set
+ {
+ RaiseAndSetIfchanged(ref _infos, value);
+ RaisePropertyChanged("tooltipContent");
+ }
+ }
+
+ private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ if (window == null)
+ {
+ window = new InfoWindow(title, infos);
+ window.Closed += Window_Closed;
+ window.Owner = Window.GetWindow(this);
+ window.Show();
+ }
+ else
+ {
+ window.Activate();
+ }
+ }
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ this.window = null;
+ }
+
+ public void SetStatus(string status)
+ {
+ this.status = status;
+ }
+
+ public void SetInfos(List<Info> infos)
+ {
+ this.infos = new ObservableCollection<Info>(infos);
+ if (window != null) window.UpdateSource(this.infos);
+ }
+
+ public void SetInfos(string[,] infos)
+ {
+ var data = new ObservableCollection<Info>();
+ for (int i = 0; i < infos.GetLength(0); i++)
+ {
+ data.Add(new Info
+ {
+ step = infos[i, 0],
+ result = infos[i, 1]
+ });
+ }
+ this.infos = data;
+ if (window != null) window.UpdateSource(this.infos);
+ }
+
+ public void SetInfos(Info info)
+ {
+ if (queue.Count >= maxSize)
+ {
+ queue.TryDequeue(out var first);
+ }
+ queue.Enqueue(info);
+ var list = new ObservableCollection<Info>(queue);
+ this.infos = list;
+ if (window != null) window.UpdateSource(this.infos);
+ }
+
+ public void ClearInfo()
+ {
+ queue = new ConcurrentQueue<Info>();
+ var list = new ObservableCollection<Info>(queue);
+ this.infos = list;
+ if (window != null) window.UpdateSource(this.infos);
+ }
+
+ public void SetInfos(string step, string result)
+ {
+ if (queue.Count >= maxSize)
+ {
+ queue.TryDequeue(out var info);
+ }
+ queue.Enqueue(new Info() { step = step, result = result });
+ var list = new ObservableCollection<Info>(queue);
+ this.infos = list;
+ if (window != null) window.UpdateSource(this.infos);
+ }
+ }
+}
diff --git a/Plugin.TestResult/TestResultView.xaml b/Plugin.TestResult/TestResultView.xaml
new file mode 100644
index 0000000..3429e54
--- /dev/null
+++ b/Plugin.TestResult/TestResultView.xaml
@@ -0,0 +1,16 @@
+锘�<UserControl x:Class="Plugin.TestResult_WPF.TestResultView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ FontFamily="Microsoft YaHei"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid x:Name="panel">
+ <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
+ <Grid x:Name="mainGrid" local:GridProperties.BorderSpace="10">
+
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Plugin.TestResult/TestResultView.xaml.cs b/Plugin.TestResult/TestResultView.xaml.cs
new file mode 100644
index 0000000..b5877c6
--- /dev/null
+++ b/Plugin.TestResult/TestResultView.xaml.cs
@@ -0,0 +1,383 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using NationalInstruments.TestStand.Utility;
+using Plugin.TestResult_WPF.Constant;
+using Plugin.TestResult_WPF.Model;
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// TestResultView.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class TestResultView : UserControl
+ {
+ private int rowCount;
+ private int colCount;
+ private int cellCount;
+ private DataTable[] tables;
+ public Dictionary<string, DataTable> nameTables { get; private set; }
+ private readonly BaseConfig config;
+
+ public AxApplicationMgr testApp;
+ public string testSeqFile;
+ /// <summary>
+ /// 娴嬭瘯搴忓垪
+ /// </summary>
+ private SequenceFile testSeq = null;
+ public Engine engine;
+ private Execution execution = null;
+ /// <summary>
+ /// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
+ /// </summary>
+ private SequenceContext SequenceContext = null;
+ /// <summary>
+ /// 娴嬭瘯妯″瀷搴忓垪
+ /// </summary>
+ private SequenceFile modeSeq;
+
+ public TestResultView() : this(new BaseConfig { testing = false })
+ {
+
+ }
+
+ public TestResultView(BaseConfig config)
+ {
+ this.rowCount = config.Row;
+ this.colCount = config.Column;
+ this.config = config;
+ if (config.CellCount < 0)
+ {
+ this.cellCount = rowCount * colCount;
+ }
+ else
+ {
+ this.cellCount = config.CellCount;
+ }
+ tables = new DataTable[this.cellCount];
+
+
+ InitializeComponent();
+ testApp = new AxApplicationMgr();
+ testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
+ testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
+ testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
+
+
+ ((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
+ host.Child = testApp;
+ ((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit();
+ InitMainGrid();
+ //InitTestStandEngine();
+ //StartTestSequence();
+ }
+
+ private void Refresh()
+ {
+ for (int i = 0; i < tables.Length; i++)
+ {
+ var sb = new System.Timers.Timer()
+ {
+ Interval = 1000,
+ AutoReset = true,
+ };
+ var table = tables[i];
+ Random random = new Random(i * 13);
+ sb.Elapsed += (s, e) =>
+ {
+
+ table.SetTemperature(random.Next(100));
+ for (int j = 0; j < 3; j++)
+ {
+ table.SetTemperature(j + "89", random.Next(100));
+ }
+ table.SetOkCount(random.Next(100));
+ table.SetNgCount(random.Next(100));
+ table.SetStatus(CommonStatus.GetRandomStatus());
+ table.SetStartTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+ table.SetEndTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+ table.SetConsumeTime(random.Next(10000));
+
+
+ var cell = table.GetSingleCell(random.Next(table.GetSize()));
+ cell.SetStatus(CommonStatus.GetRandomStatus());
+ cell.SetInfos(random.Next(1000) + "", random.Next(1000) + "");
+ table.SetStatusText(DateTime.Now + "");
+ };
+ sb.Start();
+ }
+ }
+
+ public void InitMainGrid()
+ {
+ nameTables = new Dictionary<string, DataTable>();
+ for (int r = 0; r < rowCount; r++)
+ {
+ RowDefinition row = new RowDefinition();
+ mainGrid.RowDefinitions.Add(row);
+ }
+
+ for (int c = 0; c < colCount; c++)
+ {
+ ColumnDefinition col = new ColumnDefinition();
+ mainGrid.ColumnDefinitions.Add(col);
+ }
+ string[] names = config.NameStr.Split(',');
+ for (int n = 0; n < cellCount; n++)
+ {
+ string name = n < names.Length ? names[n] : "";
+ DataTable child = new DataTable(this, n, name, config);
+ mainGrid.Children.Add(child);
+ tables[n] = child;
+ nameTables[name] = child;
+ int row = n / colCount;
+ int col = n % colCount;
+ Grid.SetRow(child, row);
+ Grid.SetColumn(child, col);
+ }
+ if (config.testing) Refresh();
+ }
+
+ public DataTable GetDataTable(int index)
+ {
+ if (index > 0 && index < tables.Length) return tables[index];
+ return null;
+ }
+
+ /// <summary>
+ /// 鍚姩娴嬭瘯搴忓垪
+ /// </summary>
+ public void InitTestStandEngine()
+ {
+ try
+ {
+ this.engine = this.testApp.GetEngine();
+ this.engine.PersistBreakpoints = false;
+ this.testApp.IsEditor = true;
+ this.testApp.LoginOnStart = false;
+ this.testApp.Start();
+ this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("鍒濆鍖朤S寮曟搸澶辫触:" + ex.Message);
+ }
+ }
+
+ public void StartTestSequence()
+ {
+ try
+ {
+ this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+ this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 0, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+ this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+ this.engine.Globals.SetValBoolean("StationState.StopTest", 0, false);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("鍚姩娴嬭瘯搴忓垪澶辫触:" + ex.Message);
+ }
+ }
+
+ public void StopTest()
+ {
+ try
+ {
+ if (this.SequenceContext == null)
+ return;
+ bool val = this.SequenceContext.StationGlobals.Exists("StationState.StopTest", 0);
+ if (val)
+ {
+ this.SequenceContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true);
+ bool isStop = this.execution.WaitForEndEx(2000, true, null, null);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception(ex.Message);
+ }
+ }
+
+ private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
+ {
+ Environment.ExitCode = testApp.ExitCode;
+ TSHelper.DoSynchronousGCForCOMObjectDestruction();
+ }
+
+ private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
+ {
+ try
+ {
+ //this.ReleaseSequenceFile();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("閲婃斁娴嬭瘯搴忓垪澶辫触:" + ex.Message);
+ }
+ }
+
+ private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+ {
+ try
+ {
+ int EventCase = Convert.ToInt32(e.uiMsg.Event);
+ int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
+ string strData;
+
+ if (EventCase != 10014) return;
+
+ if (MethodCode == 0)
+ {
+ /// 璁剧疆鍙ユ焺
+ this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+ return;
+ }
+
+ if (MethodCode == 1)
+ {
+ /// 鏇存柊鐐夊瓙鐘舵��
+ strData = e.uiMsg.StringData;
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string status = datas_10014[1];
+ tables[ovenIndex].SetStatus(status);
+ return;
+ }
+ if (MethodCode == 2)
+ {
+ /// 鏇存柊鐐夊瓙鏁伴噺淇℃伅
+ strData = e.uiMsg.StringData;
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string okCount = datas_10014[1];
+ string ngCount = datas_10014[2];
+ tables[ovenIndex].SetOkCount(int.Parse(okCount));
+ tables[ovenIndex].SetNgCount(int.Parse(ngCount));
+ return;
+ }
+ if (MethodCode == 3)
+ {
+ /// 鏇存柊鐐夊瓙鏃堕棿淇℃伅
+ strData = e.uiMsg.StringData;
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string startTime = datas_10014[1];
+ string consumeTime = datas_10014[2];
+ string planEndTime = datas_10014[3];
+ tables[ovenIndex].SetStartTime(startTime);
+ tables[ovenIndex].SetConsumeTime(double.Parse(consumeTime));
+ tables[ovenIndex].SetEndTime(planEndTime);
+ return;
+ }
+ if (MethodCode == 4)
+ {
+ /// 鏇存柊鑰佸寲鐐夊簳閮ㄧ姸鎬佹爮
+ strData = e.uiMsg.StringData;
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string statusBar = datas_10014[1];
+ tables[ovenIndex].SetStatusText(statusBar);
+ return;
+ }
+ if (MethodCode == 5)
+ {
+ /// 閲囬泦鐐夋俯搴�
+ strData = e.uiMsg.StringData;
+ string[] datas_10016 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10016[0]);
+
+ string[] names = datas_10016[1].Split(',');
+ string[] values = datas_10016[2].Split(',');
+
+ for (int x = 0; x < values.Length; x++)
+ {
+ if (x == 0) tables[ovenIndex].SetTemperature(double.Parse(values[x]));
+ else tables[ovenIndex].SetTemperature(names[x - 1], double.Parse(values[x]));
+ }
+ return;
+ }
+ if (MethodCode == 6)
+ {
+ /// 鏇存柊绌翠綅鐘舵��
+ strData = e.uiMsg.StringData;
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+ string status_10015 = datas_10015[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).SetStatus(status_10015);
+ return;
+ }
+ if (MethodCode == 7)
+ {
+ /// 鏇存柊绌翠綅鍙傛暟
+ strData = e.uiMsg.StringData;
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+
+ string strs = datas_10015[2];
+ string[] values = strs.Split(',');
+
+ //string step = datas_10015[2];
+ //string result = datas_10015[3];
+ tables[ovenIndex].GetSingleCell(cellIndex).SetInfos(new Info
+ {
+ step = values[0],
+ value = values[1],
+ result = values[2],
+ range = values[3],
+ condition = values[4],
+ updateTime = values[5]
+ });
+ return;
+ }
+ if (MethodCode == 10)
+ {
+ /// 娓呯┖鐐夊瓙鐨勬俯搴﹀浘琛�
+ strData = e.uiMsg.StringData;
+ int ovenIndex = int.Parse(strData);
+ tables[ovenIndex].ClearChartData();
+ return;
+ }
+ if (MethodCode == 11)
+ {
+ /// 娓呴櫎绌翠綅鍙傛暟
+ strData = e.uiMsg.StringData;
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+ tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ public void SetStartFlag(int index, bool data)
+ {
+ if (this.SequenceContext == null) return;
+ char name = (char)(index + 65);
+ string key = $"StationState.Start_{name}";
+ this.engine.Globals.SetValBoolean(key, 0, data);
+ bool val = this.engine.Globals.GetValBoolean(key, 0);
+ //this.SequenceContext.StationGlobals.SetValBoolean(key, 0, data);
+ //bool val = this.SequenceContext.StationGlobals.GetValBoolean(key, 0);
+ }
+
+ public void SetSnrToSeqContext(int index, string snr)
+ {
+
+ }
+ }
+}
diff --git a/Plugin.TestResult/Util/CommonCodeParser.cs b/Plugin.TestResult/Util/CommonCodeParser.cs
new file mode 100644
index 0000000..605ea69
--- /dev/null
+++ b/Plugin.TestResult/Util/CommonCodeParser.cs
@@ -0,0 +1,27 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Plugin.TestResult_WPF.Model;
+
+namespace Plugin.TestResult_WPF.Util
+{
+ public class CommonCodeParser
+ {
+ public CellInfo GetCellInfoByCode(string code)
+ {
+ string[] arr = code.Split('-');
+ if (arr == null || arr.Length != 3)
+ {
+ throw new Exception("鎵爜鏍煎紡寮傚父");
+ }
+ return new CellInfo()
+ {
+ MachineName = arr[0],
+ OvenName = arr[1],
+ Index = int.Parse(arr[2]) - 1,
+ };
+ }
+ }
+}
diff --git a/Plugin.TestResult/Util/DpUtil.cs b/Plugin.TestResult/Util/DpUtil.cs
new file mode 100644
index 0000000..cc3c52c
--- /dev/null
+++ b/Plugin.TestResult/Util/DpUtil.cs
@@ -0,0 +1,232 @@
+锘縰sing System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Media;
+
+namespace Plugin.TestResult_WPF
+{
+ public class GridProperties
+ {
+ public static bool GetShowBorder(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(ShowBorderProperty);
+ }
+ public static void SetShowBorder(DependencyObject obj, bool value)
+ {
+ obj.SetValue(ShowBorderProperty, value);
+ }
+ public static readonly DependencyProperty ShowBorderProperty =
+ DependencyProperty.RegisterAttached("ShowBorder", typeof(bool), typeof(Grid), new PropertyMetadata(false, OnShowBorderChanged));
+
+ public static int GetBorderSpace(DependencyObject obj)
+ {
+ return (int)obj.GetValue(BorderSpaceProperty);
+ }
+ public static void SetBorderSpace(DependencyObject obj, int value)
+ {
+ obj.SetValue(BorderSpaceProperty, value);
+ }
+ public static readonly DependencyProperty BorderSpaceProperty =
+ DependencyProperty.RegisterAttached("BorderSpace", typeof(int), typeof(Grid), new PropertyMetadata(0, OnShowBorderChanged));
+
+ public static string GetInnerBorderIgnore(DependencyObject obj)
+ {
+ return (string)obj.GetValue(InnerBorderIgnoreProperty);
+ }
+ public static void SetInnerBorderIgnore(DependencyObject obj, string value)
+ {
+ obj.SetValue(InnerBorderIgnoreProperty, value);
+ }
+ public static readonly DependencyProperty InnerBorderIgnoreProperty =
+ DependencyProperty.RegisterAttached("InnerBorderIgnore", typeof(string),
+ typeof(Grid), new PropertyMetadata("None", OnShowBorderChanged));
+
+
+ private static void OnShowBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is Grid grid)
+ {
+ if (e.Property == ShowBorderProperty)
+ {
+ grid.Loaded += GridInnerBorderLoaded;
+ return;
+ }
+ else if (e.Property == BorderSpaceProperty)
+ {
+ grid.Loaded += GridSpaceOnLoaded;
+ return;
+ }
+ }
+ else if (d is UniformGrid uniformGrid)
+ {
+ uniformGrid.Loaded += UniformGridOnLoad;
+ return;
+ }
+ }
+
+ private static void GridInnerBorderLoaded(object sender, RoutedEventArgs e)
+ {
+ if (!(sender is Grid grid)) return;
+ var rowCount = grid.RowDefinitions.Count;
+ var columnCount = grid.ColumnDefinitions.Count;
+ int totalCount = rowCount * columnCount;
+
+ int width = 1;
+
+ string baseData = GetInnerBorderIgnore(grid);
+ HashSet<string> data = new HashSet<string>(baseData.Split(','));
+ bool ignoreTop = data.Contains("All") || data.Contains("Top"),
+ ignoreBottom = data.Contains("All") || data.Contains("Bottom"),
+ ignoreLeft = data.Contains("All") || data.Contains("Left"),
+ ignoreRight = data.Contains("All") || data.Contains("Right");
+
+ foreach (var child in grid.Children)
+ {
+ int row = Grid.GetRow((UIElement)child);
+ int col = Grid.GetColumn((UIElement)child);
+
+ var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0,
+ row == 0 ? (ignoreTop ? 0 : width) : 0,
+ (col == columnCount - 1 && ignoreRight) ? 0 : width,
+ width);
+
+ if (child is UserControl control)
+ {
+ control.BorderBrush = Brushes.Black;
+ control.BorderThickness = bt;
+ }
+
+ if (child is Label label)
+ {
+ label.BorderBrush = Brushes.Black;
+ label.BorderThickness = bt;
+ }
+
+ if (child is TextBox box)
+ {
+ box.BorderBrush = Brushes.Black;
+ box.BorderThickness = bt;
+ }
+ }
+
+ /// 寮冪敤
+ //for (int i = 0; i < totalCount; i++)
+ //{
+ // int row = i / columnCount;
+ // int col = i % columnCount;
+
+ // if (i > grid.Children.Count - 1) {
+ // continue;
+ // }
+ // var cell = grid.Children[i];
+ // var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0,
+ // row == 0 ? (ignoreTop ? 0 : width) : 0,
+ // (col == columnCount - 1 && ignoreRight) ? 0 : width,
+ // width);
+
+ // if (cell is UserControl child)
+ // {
+ // child.BorderBrush = Brushes.Black;
+ // child.BorderThickness = bt;
+ // }
+
+ // if (cell is Label label)
+ // {
+ // label.BorderBrush = Brushes.Black;
+ // label.BorderThickness = bt;
+ // }
+
+ // if (cell is TextBox box)
+ // {
+ // box.BorderBrush = Brushes.Black;
+ // box.BorderThickness = bt;
+ // }
+ //}
+ grid.Loaded -= GridInnerBorderLoaded;
+ }
+
+ private static void GridSpaceOnLoaded(object sender, RoutedEventArgs e)
+ {
+ if (!(sender is Grid grid)) return;
+ int space = GetBorderSpace(grid);
+ if (space <= 0)
+ {
+ return;
+ }
+
+ var rowCount = grid.RowDefinitions.Count;
+ var columnCount = grid.ColumnDefinitions.Count;
+ int totalCount = rowCount * columnCount;
+
+ for (int i = 0; i < totalCount; i++)
+ {
+ int row = i / columnCount;
+ int col = i % columnCount;
+
+ if (i > grid.Children.Count - 1)
+ {
+ continue;
+ }
+ var cell = grid.Children[i];
+
+ var bt = new Thickness(col == 0 ? space : 0, row == 0 ? space : 0, space, space);
+
+ if (cell is UserControl child)
+ {
+ child.Margin = bt;
+ }
+ }
+ grid.Loaded -= GridSpaceOnLoaded;
+ }
+
+ private static void UniformGridOnLoad(object sender, RoutedEventArgs e)
+ {
+ if (!(sender is UniformGrid grid)) return;
+ //var rowCount = grid.Rows;
+ int columnCount = grid.Columns;
+ int totalCount = grid.Children.Count;
+ int rowCount = totalCount / columnCount;
+ int width = 1;
+
+ for (int i = 0; i < grid.Children.Count; i++)
+ {
+ int row = i / columnCount;
+ int col = i % columnCount;
+ var child = grid.Children[i];
+
+ string baseData = GetInnerBorderIgnore(grid);
+ HashSet<string> data = new HashSet<string>(baseData.Split(','));
+ bool ignoreTop = data.Contains("All") || data.Contains("Top"),
+ ignoreBottom = data.Contains("All") || data.Contains("Bottom"),
+ ignoreLeft = data.Contains("All") || data.Contains("Left"),
+ ignoreRight = data.Contains("All") || data.Contains("Right");
+
+ var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0,
+ row == 0 ? (ignoreTop ? 0 : width) : 0,
+ (col == columnCount - 1 && ignoreRight) ? 0 : width,
+ (row == rowCount && ignoreBottom) ? 0 : width);
+
+ if (child is UserControl control)
+ {
+ control.BorderBrush = Brushes.Black;
+ control.BorderThickness = bt;
+ }
+
+ if (child is Label label)
+ {
+ label.BorderBrush = Brushes.Black;
+ label.BorderThickness = bt;
+ }
+
+ if (child is TextBox box)
+ {
+ box.BorderBrush = Brushes.Black;
+ box.BorderThickness = bt;
+ }
+ }
+ grid.Loaded -= UniformGridOnLoad;
+ }
+ }
+
+}
diff --git a/Plugin.TestResult/Util/FontSizeConverter.cs b/Plugin.TestResult/Util/FontSizeConverter.cs
new file mode 100644
index 0000000..7d1d61e
--- /dev/null
+++ b/Plugin.TestResult/Util/FontSizeConverter.cs
@@ -0,0 +1,33 @@
+锘縰sing System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Plugin.TestResult_WPF
+{
+ public class FontSizeConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (parameter == null) return 15;
+
+ string[] ps = parameter.ToString().Split(',');
+ int size = int.Parse(ps[0]);
+ int baseSize = int.Parse(ps[1]);
+ if (value is double width)
+ {
+ return CountFontSize(size, width, baseSize);
+ }
+ return 15;
+ }
+
+ public static double CountFontSize(double size, double limit, double baseSize)
+ {
+ return size * limit / baseSize;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugin.TestResult/ViewControl.xaml b/Plugin.TestResult/ViewControl.xaml
new file mode 100644
index 0000000..1d320b9
--- /dev/null
+++ b/Plugin.TestResult/ViewControl.xaml
@@ -0,0 +1,161 @@
+锘�<UserControl x:Class="Plugin.TestResult_WPF.ViewControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.TestResult_WPF"
+ mc:Ignorable="d"
+ Loaded="UserControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ <Style TargetType="GroupBox">
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='30,1920'}" />
+ </Style>
+
+ <Style TargetType="Button">
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ </Style>
+
+ <Style TargetType="Label">
+ <Setter Property="BorderThickness" Value="1"/>
+ <Setter Property="BorderBrush" Value="LightGray"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ </Style>
+ </UserControl.Resources>
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="7.5*"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+ <local:TestResultView x:Name="testResultView" Grid.Column="0" Loaded="testResultView_Loaded" />
+ <StackPanel Grid.Column="1" Background="#FFF">
+ <GroupBox Header="浜у搧淇℃伅">
+ <ComboBox x:Name="modelSelect" SelectionChanged="modelSelect_SelectionChanged"></ComboBox>
+ </GroupBox>
+ <GroupBox Header="鐢熶骇缁熻">
+ <StackPanel>
+ <Label HorizontalContentAlignment="Center" HorizontalAlignment="Stretch">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="HorizontalAlignment" Value="Stretch"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding mesStatus}" Value="true">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Content" Value="MES寮�"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding mesStatus}" Value="false">
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="Content" Value="MES鍏�"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ <Label>
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="HorizontalAlignment" Value="Stretch"/>
+ <Setter Property="Content" Value="{Binding produceStatus}"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding produceStatus}" Value="INIT">
+ <Setter Property="Background" Value="Gray"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding produceStatus}" Value="STOP">
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding produceStatus}" Value="RUNNING">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ </StackPanel>
+ </GroupBox>
+ <GroupBox Header="鎿嶄綔">
+ <StackPanel>
+ <Button x:Name="btnStart" Click="Start_Click">
+ <Button.Content>鍚姩</Button.Content>
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Foreground" Value="White"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button x:Name="btnStop" Click="Stop_Click">
+ <Button.Content>鍋滄</Button.Content>
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="Foreground" Value="White"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button x:Name="btnScan1" Click="Scan_Click_1">
+ <Button.Content>涓�鍖烘壂鐮�</Button.Content>
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button x:Name="btnScan2" Click="Scan_Click_2">
+ <Button.Content>浜屽尯鎵爜</Button.Content>
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <!-- <Button Content="璁℃暟娓呴浂"/>
+ <Button Content="鎵爜"/>
+ <Button Content="涓�鍖烘墜鍔�"/>
+ <Button Content="浜屽尯鎵嬪姩"/>-->
+ </StackPanel>
+ </GroupBox>
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Plugin.TestResult/ViewControl.xaml.cs b/Plugin.TestResult/ViewControl.xaml.cs
new file mode 100644
index 0000000..fc91920
--- /dev/null
+++ b/Plugin.TestResult/ViewControl.xaml.cs
@@ -0,0 +1,288 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using NationalInstruments.TestStand.Utility;
+using ParameterHelper;
+using Plugin.TestResult_WPF.Model;
+using Plugin.TestResult_WPF.Util;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Plugin.TestResult_WPF
+{
+ /// <summary>
+ /// ViewControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ViewControl : UserControl, INotifyPropertyChanged
+ {
+ public event PropertyChangedEventHandler PropertyChanged;
+ public void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+ public void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null)
+ {
+ RaisePropertyChanged(propertyName);
+ }
+ }
+
+ private ParameterManager parameterManager;
+ private CommonCodeParser codeParser = new CommonCodeParser();
+ private double TestTemperature = 60;
+ private int TestTime = 3600;
+ private double SaftyTemperature = 40;
+ private double TestVoltage = 12;
+ private double Time_Heating_Low = 300;
+ private double Time_Heating_High = 2400;
+ private string testSeqFile;
+ private Scanner scannerWindow1;
+ private Scanner scannerWindow2;
+ /// <summary>
+ /// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
+ /// </summary>
+ private SequenceContext SequenceContext = null;
+
+
+ private bool _mesStatus;
+
+ public bool mesStatus
+ {
+ get => _mesStatus;
+ set => RaiseAndSetIfChanged(ref _mesStatus, value);
+ }
+
+ private string _produceStatus = "INIT";
+
+ public string produceStatus
+ {
+ get => _produceStatus;
+ set => RaiseAndSetIfChanged(ref _produceStatus, value);
+ }
+
+
+
+ public ViewControl()
+ {
+ DataContext = this;
+ InitializeComponent();
+ testResultView.testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
+ testResultView.testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
+ testResultView.testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
+ }
+
+ private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
+ {
+ }
+
+ private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
+ {
+
+ }
+
+ private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+ {
+ try
+ {
+ int EventCase = Convert.ToInt32(e.uiMsg.Event);
+ int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
+ string strData;
+
+ if (EventCase != 10014) return;
+
+ if (MethodCode == 0)
+ {
+ /// 璁剧疆鍙ユ焺
+ this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+ return;
+ }
+
+
+ if (MethodCode == 8)
+ {
+ /// 鏇存柊MES鐘舵��
+ strData = e.uiMsg.StringData;
+ mesStatus = strData == "1";
+ return;
+ }
+
+ if (MethodCode == 9)
+ {
+ /// 鏇存柊鐢熶骇鐘舵��
+ strData = e.uiMsg.StringData;
+ produceStatus = strData;
+ return;
+ }
+ }
+ catch
+ { }
+ }
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadProduct();
+ testResultView.InitTestStandEngine();
+ Start_Click(null, null);
+ }
+
+ public void LoadProduct()
+ {
+ ProductManager prdManager = new ProductManager();
+ prdManager.LoadProducts();
+ this.modelSelect.Items.Clear();
+ foreach (Product prd in prdManager.Products)
+ {
+ this.modelSelect.Items.Add(prd.Name);
+ }
+ if (prdManager.Products.Count > 0)
+ {
+ this.modelSelect.SelectedIndex = 0;
+ }
+ }
+
+ private void modelSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ try
+ {
+ string ParaFile = @".\Config\ProductionSetting\Parameter\Parameter_" + this.modelSelect.SelectedItem + ".setting";
+
+ this.parameterManager = new ParameterManager(ParaFile);
+ this.parameterManager.LoadParameters();
+ //MessageBox.Show("ParaFile:" + ParaFile + "ParaCount:" + this.parameterManager.Parameters.Count.ToString());
+ //this.TestTemperature = Convert.ToDouble(this.parameterManager.Find("TestTemperature").ParmValue);
+ //this.TestTime = Convert.ToInt32(this.parameterManager.Find("TestTime").ParmValue);
+ //this.TestVoltage = Convert.ToDouble(this.parameterManager.Find("TestVoltage").ParmValue);
+ //this.SaftyTemperature = Convert.ToDouble(this.parameterManager.Find("SaftyTemperature").ParmValue);
+ //this.Time_Heating_Low = Convert.ToDouble(this.parameterManager.Find("Time_Heat_Low").ParmValue);
+ //this.Time_Heating_High = Convert.ToDouble(this.parameterManager.Find("Time_Heat_High").ParmValue);
+ testResultView.testSeqFile = this.parameterManager.Find("TestSequence").ParmValue.ToString(); // @"D:\BurnIn\TestDemo.seq"
+
+
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("鍒囨崲浜у搧鍨嬪彿澶辫触!" + ex.Message + ex.StackTrace);
+ }
+ }
+
+ private void Start_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ testResultView.StartTestSequence();
+
+ this.modelSelect.IsEnabled = false;
+ this.btnStart.IsEnabled = false;
+ this.btnStop.IsEnabled = true;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("鍚姩娴嬭瘯澶辫触锛�" + ex.Message);
+ }
+ }
+
+ private void Stop_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ testResultView.StopTest();
+ this.modelSelect.IsEnabled = true;
+ this.btnStart.IsEnabled = true;
+ this.btnStop.IsEnabled = false;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("鍋滄娴嬭瘯澶辫触!" + ex.Message);
+ }
+ }
+
+ private void Scan_Click_1(object sender, RoutedEventArgs e)
+ {
+ if (scannerWindow1 == null)
+ {
+ scannerWindow1 = new Scanner("涓�鍖烘壂鐮�");
+ scannerWindow1.FinishBarcode += ScannerWindow_FinishBarcode;
+ scannerWindow1.Owner = Window.GetWindow(this);
+ scannerWindow1.Closed += ScannerWindow1_Closed;
+ scannerWindow1.Show();
+ }
+ else
+ {
+ scannerWindow1.Activate();
+ }
+ }
+
+ private void Scan_Click_2(object sender, RoutedEventArgs e)
+ {
+ if (scannerWindow2 == null)
+ {
+ scannerWindow2 = new Scanner("浜屽尯鎵爜");
+ scannerWindow2.FinishBarcode += ScannerWindow_FinishBarcode;
+ scannerWindow2.Owner = Window.GetWindow(this);
+ scannerWindow2.Closed += ScannerWindow2_Closed;
+ scannerWindow2.Show();
+ }
+ else
+ {
+ scannerWindow2.Activate();
+ }
+ }
+
+ /// <summary>
+ /// 鎵爜瀹屾垚閫昏緫
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void ScannerWindow_FinishBarcode(object sender, BarcodeEventArg e)
+ {
+ if (this.SequenceContext == null) return;
+ CellInfo cellInfo = codeParser.GetCellInfoByCode(e.positionCode);
+
+ string paramName = e.name == "涓�鍖烘壂鐮�" ? "StationState.StartScanner_A" : "StationState.StartScanner_B";
+ testResultView.engine.Globals.SetValBoolean(paramName, 0, true);
+ string positionCode = e.positionCode, snrCode = e.snrCode;
+ //闇�瑕佸鍔犳潯鐮佹牎楠屽姛鑳�
+
+ //灏嗚鍒扮殑鏉$爜鍐欏叆鍒癝N涓�
+ int dutNo = Convert.ToInt16(positionCode.Split('-')[2]) - 1;
+ string LookupStr = e.name == "涓�鍖烘壂鐮�" ? $"StationState.SN[{dutNo}]" : $"StationState.SN[{(dutNo + 54)}]";
+ //this.SequenceContext.StationGlobals.SetValString(LookupStr, 0, snrCode);
+ //string code = this.SequenceContext.StationGlobals.GetValString(LookupStr, 0);
+
+ testResultView.engine.Globals.SetValString(LookupStr, 0, snrCode);
+ string code = testResultView.engine.Globals.GetValString(LookupStr, 0);
+ testResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).SetStatus("hadCode");
+ }
+
+ private void ScannerWindow1_Closed(object sender, EventArgs e)
+ {
+ scannerWindow1 = null;
+ }
+
+ private void ScannerWindow2_Closed(object sender, EventArgs e)
+ {
+ scannerWindow2 = null;
+ }
+
+ private void testResultView_Loaded(object sender, RoutedEventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/Plugin.TestResult/packages.config b/Plugin.TestResult/packages.config
new file mode 100644
index 0000000..6693fcf
--- /dev/null
+++ b/Plugin.TestResult/packages.config
@@ -0,0 +1,25 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="HarfBuzzSharp" version="7.3.0.3" targetFramework="net472" />
+ <package id="HarfBuzzSharp.NativeAssets.Linux" version="7.3.0.3" targetFramework="net472" />
+ <package id="HarfBuzzSharp.NativeAssets.macOS" version="7.3.0.3" targetFramework="net472" />
+ <package id="HarfBuzzSharp.NativeAssets.Win32" version="7.3.0.3" targetFramework="net472" />
+ <package id="OpenTK" version="3.3.1" targetFramework="net472" />
+ <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net472" />
+ <package id="ScottPlot" version="5.0.47" targetFramework="net472" />
+ <package id="ScottPlot.WPF" version="5.0.47" targetFramework="net472" />
+ <package id="SkiaSharp" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.HarfBuzz" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.NativeAssets.Linux.NoDependencies" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.NativeAssets.macOS" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.NativeAssets.Win32" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.Views.Desktop.Common" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.Views.WPF" version="2.88.9" targetFramework="net472" />
+ <package id="System.Buffers" version="4.5.1" targetFramework="net472" />
+ <package id="System.Drawing.Common" version="4.7.3" targetFramework="net472" />
+ <package id="System.Memory" version="4.5.5" targetFramework="net472" />
+ <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
+ <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" />
+ <package id="System.Runtime.Loader" version="4.3.0" targetFramework="net472" />
+ <package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
+</packages>
\ No newline at end of file
diff --git a/WPFProject/LoadingWindow.xaml.cs b/WPFProject/LoadingWindow.xaml.cs
index 6a857bb..49b44ce 100644
--- a/WPFProject/LoadingWindow.xaml.cs
+++ b/WPFProject/LoadingWindow.xaml.cs
@@ -1,4 +1,5 @@
-锘縰sing System.Threading.Tasks;
+锘縰sing System;
+using System.Threading.Tasks;
using System.Windows;
using HMI.Base;
@@ -24,9 +25,9 @@
private void Loader_LoadMessageAppend(object sender, string e)
{
- Dispatcher.BeginInvoke(() =>
+ this.Dispatcher.BeginInvoke((Action)delegate ()
{
- Console.Text = Console.Text+$"{e}\r\n";
+ Console.Text = Console.Text + $"{e}\r\n";
});
}
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index b5336b6..564f32e 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -369,6 +369,10 @@
<Project>{f7663c79-7047-42f3-b129-73a2575ee7c6}</Project>
<Name>HMI.IOMonitor</Name>
</ProjectReference>
+ <ProjectReference Include="..\HMI.LogViewer\HMI.LogViewer.csproj">
+ <Project>{20c23602-b029-4e21-8c11-b9e5f2223237}</Project>
+ <Name>HMI.LogViewer</Name>
+ </ProjectReference>
<ProjectReference Include="..\HMI.ParameterManage\HMI.ParameterManage.csproj">
<Project>{736cd77d-b81e-4866-bb00-84b0b57110f0}</Project>
<Name>HMI.ParameterManage</Name>
@@ -389,6 +393,10 @@
<Project>{de4205c6-5923-46fd-a4b9-65169bf61c75}</Project>
<Name>HMI.MenuManage</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.TestResult\Plugin.TestResult.csproj">
+ <Project>{7375b74c-b6bf-4814-9838-e1caacad1897}</Project>
+ <Name>Plugin.TestResult</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Icon\xinzeng_1.png">
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index 92be340..80ca826 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -33,6 +33,10 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonLibs", "..\..\HMI.Old\Framework\CommonLibs\CommonLibs\CommonLibs.csproj", "{0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMI.LogViewer", "..\HMI.LogViewer\HMI.LogViewer.csproj", "{20C23602-B029-4E21-8C11-B9E5F2223237}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.TestResult", "..\Plugin.TestResult\Plugin.TestResult.csproj", "{7375B74C-B6BF-4814-9838-E1CAACAD1897}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -161,6 +165,22 @@
{0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}.Release|Any CPU.Build.0 = Release|Any CPU
{0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}.Release|x64.ActiveCfg = Release|x64
{0212E104-4E85-4F9F-AA70-FC4FAC25C3E5}.Release|x64.Build.0 = Release|x64
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x64.ActiveCfg = Debug|x64
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Debug|x64.Build.0 = Debug|x64
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|Any CPU.Build.0 = Release|Any CPU
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x64.ActiveCfg = Release|Any CPU
+ {20C23602-B029-4E21-8C11-B9E5F2223237}.Release|x64.Build.0 = Release|Any CPU
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x64.ActiveCfg = Debug|x64
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Debug|x64.Build.0 = Debug|x64
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x64.ActiveCfg = Release|x64
+ {7375B74C-B6BF-4814-9838-E1CAACAD1897}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
--
Gitblit v1.9.1