From 1afe548ac40cc7f975917ef9bf2e156595cf81f3 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期四, 16 四月 2026 08:58:04 +0800
Subject: [PATCH] 优化;
---
HMI.UI/Converter/DateStrConverter.cs | 29
Plugin.TestResult/SingleCell.xaml | 66
WPFProject/Controls/MainTabControl.xaml | 2
HMI.LogViewer/LogViewer.xaml | 25
Plugin.TestResult/DataTable.xaml | 27
Plugin.TsSupport/TsExecutionWrapper.cs | 214 +
Plugin.UICollection/TcpDebugger.xaml.cs | 393 +++
Plugin.TestResult/TestResultView.xaml.cs | 170
Plugin.TsExecution/Plugin.TsExecution.csproj | 21
Plugin.DataViewer/Plugin.DataViewer.csproj | 26
Plugin.TestResult/Model/TcpServer.cs | 27
SimpleUtil/HMI.Simple.Util/ProductUtil.cs | 89
Plugin.TsExecution/ScreenTouchWin.xaml.cs | 67
WPFProject/Settings.ini | 6
HMI.ParameterManage/ParameterModal.xaml | 4
WPFProject/PanuonWindow.xaml.cs | 73
Util.ManualDebug/StatusBtn.xaml | 75
Plugin.TestResult/Lixun/SNValidator.cs | 91
Plugin.TestResult/ViewControl.xaml.cs | 171 +
OPCClient/OPCClient.csproj | 1
Plugin.TsExecution/ScreenGrid.xaml | 15
Util.ManualDebug/ManualDebug.xaml | 133 +
WPFProject/App.config | 2
Plugin.TsExecution/TsExecution.xaml.cs | 171 +
Util.ManualDebug/StatusBtn.xaml.cs | 40
HMI.Core/Util/Sqlite3Helper.cs | 40
HMI.Core/Setting/ParamSetting.cs | 30
Plugin.TsExecution/ScreenTouch.xaml.cs | 156 +
Util.ManualDebug/AssemblyInfo.cs | 10
HMI.ParameterManage/SettingModal.xaml | 17
Plugin.UICollection/AssemblyInfo.cs | 10
Plugin.TsSupport/ITestExecutionWrapper.cs | 47
HMI.UI/Style/PanuonResource.xaml | 19
WPFProject/PanuonWindow.xaml | 45
Plugin.TsExecution/SingleControl.xaml | 143
WPFProject/WPFProject.sln | 70
HMI.UnitTest/App.xaml | 2
Plugin.DataViewer/DataViewerControl.xaml.cs | 800 ++++++
HMI.Util/packages.config | 1
Plugin.DataViewer/DataViewerControl.xaml | 480 +++
HMI.Core/Properties/AssemblyInfo.cs | 4
HMI.Util/ExcelHelper.cs | 49
Plugin.TestResult/ManualDebugWindow.xaml.cs | 95
HMI.LogViewer/LogViewer.xaml.cs | 142
HMI.StdControl/HMI.StdControl.csproj | 7
HMI.Core/Util/HexUtil.cs | 22
HMI.UI/Converter/ResultConverter.cs | 31
HMI.Util/Alarm/AlarmUtil.cs | 8
HMI.UI/Converter/RadioEnumConverter.cs | 19
Plugin.TestResult/packages.config | 1
CellStepSender/Properties/AssemblyInfo.cs | 4
HMI.UI/MaskControl.xaml | 4
Plugin.TsExecution/Properties/AssemblyInfo.cs | 4
WPFProject/App.xaml.cs | 2
WPFProject/UI/ResourceUI.xaml | 63
Plugin.TestResult/SingleCell.xaml.cs | 230 +
Plugin.TestResult/ViewControl.xaml | 26
Plugin.TestResult/DataTable.xaml.cs | 118
WPFProject/ResourceListener.cs | 135 +
HMI.Core/FontSizeConverter.cs | 1
HMI.UI/HMI.UI.csproj | 10
HMI.ParameterManage/ParameterManage.xaml.cs | 32
Plugin.TestResult/Util/PNUtil.cs | 56
SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs | 5
WPFProject/Lang/zh-CN/app.json | 8
HMI.Core/Manager/ProductManager.cs | 24
WPFProject/Lang/zh-CN/TestResult.json | 2
Plugin.TestResult/ManualDebugWindow.xaml | 21
CellStepSender/TcpClientTool3.cs | 81
HMI.UnitTest/MainWindow.xaml | 12
CellStepSender/StepSender.cs | 4
HMI.DataViewer/DataViewer.xaml.cs | 22
CellStepSender/CellStepSender.csproj | 1
Plugin.TsSupport/Plugin.TsSupport.csproj | 3
HMI.UnitTest/MainWindow.xaml.cs | 105
HMI.ParameterManage/Model/XmlModel.cs | 6
HMI.UI/Style/MsgBoxStyle.xaml | 55
Plugin.TestResult/Scanner.xaml.cs | 52
Plugin.TsExecution/ScreenGrid.xaml.cs | 45
Plugin.TsExecution/ScreenTouch.xaml | 14
WPFProject/Lang/en-US/TestResult.json | 2
HMI.UI/RequirePasswordWindow.xaml | 1
HMI.Core/Entity/ParameterData.cs | 7
HMI.Core/Util/PathHelper.cs | 20
Plugin.UICollection/TcpDebugger.xaml | 176 +
HMI.ParameterManage/SettingModal.xaml.cs | 199 +
WPFProject/WPFProject.csproj | 19
Util.ManualDebug/ManualDebug.xaml.cs | 467 +++
HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj | 1
Plugin.UICollection/Plugin.UICollection.csproj | 25
Plugin.DOControl/Plugin.DOControl.csproj | 1
SimpleUtil/HMI.Simple.Util/ParameterUtil.cs | 73
Plugin.TsExecution/ScreenTouchWin.xaml | 20
HMI.AlermInfoManage/AlarmInfoManage.xaml.cs | 16
Util.ManualDebug/ManualDebugStyle.xaml | 130 +
Plugin.TestResult/Plugin.TestResult.csproj | 20
Plugin.TsExecution/SingleControl.xaml.cs | 130 +
HMI.ParameterManage/ParameterModal.xaml.cs | 2
HMI.StdControl/StdSettingCheckBox.xaml.cs | 155 +
Plugin.CurrentSensorControl/BurnInSettingModal.xaml.cs | 12
Plugin.TestResult/InfoWindow.xaml | 4
Plugin.TsSupport/TeststandWrapper.cs | 228 +
Util.ManualDebug/Util.ManualDebug.csproj | 33
Plugin.DataViewer/CustomSortColumn.cs | 108
HMI.Util/HMI.Util.csproj | 5
WPFProject/Controls/MainTabControl.xaml.cs | 24
Plugin.DataViewer/AssemblyInfo.cs | 12
/dev/null | 15
Plugin.CurrentSensorControl/BurnInOven.xaml.cs | 2
WPFProject/Properties/AssemblyInfo.cs | 2
SimpleUtil/HMI.Simple.Util/Parameter.cs | 1
HMI.StdControl/StdSettingCheckBox.xaml | 14
HMI.UnitTest/HMI.UnitTest.csproj | 12
HMI.UI/RequirePasswordByUser.xaml | 33
HMI.UI/RequirePasswordByUser.xaml.cs | 62
WPFProject/Lang/en-US/app.json | 10
HMI.Util/IniFileHelper.cs | 32
WPFProject/UI/ResourceUI.xaml.cs | 91
118 files changed, 6,804 insertions(+), 691 deletions(-)
diff --git a/CellStepSender/CellStepSender.csproj b/CellStepSender/CellStepSender.csproj
index 7bb8947..351972d 100644
--- a/CellStepSender/CellStepSender.csproj
+++ b/CellStepSender/CellStepSender.csproj
@@ -43,6 +43,7 @@
<ItemGroup>
<Compile Include="StepSender.cs" />
<Compile Include="TcpClientTool.cs" />
+ <Compile Include="TcpClientTool3.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/CellStepSender/Properties/AssemblyInfo.cs b/CellStepSender/Properties/AssemblyInfo.cs
index 136a4b8..00223c1 100644
--- a/CellStepSender/Properties/AssemblyInfo.cs
+++ b/CellStepSender/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@
// 鐢熸垚鍙�
// 淇鍙�
//
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
diff --git a/CellStepSender/StepSender.cs b/CellStepSender/StepSender.cs
index 6ca40d1..1914c0b 100644
--- a/CellStepSender/StepSender.cs
+++ b/CellStepSender/StepSender.cs
@@ -28,10 +28,10 @@
{
errorMsg = null;
- TcpClientTool client = null;
+ TcpClientTool3 client = null;
try
{
- client = new TcpClientTool(ip, port);
+ client = new TcpClientTool3(ip, port);
string res = null;
client.ExecuteMessageChanged += (sender, data) =>
{
diff --git a/CellStepSender/TcpClientTool3.cs b/CellStepSender/TcpClientTool3.cs
new file mode 100644
index 0000000..993c28b
--- /dev/null
+++ b/CellStepSender/TcpClientTool3.cs
@@ -0,0 +1,81 @@
+锘縰sing System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+
+namespace CellStepSender
+{
+ public class TcpClientTool3
+ {
+ private string _ip;
+ private int _port;
+ private bool _isConnected = false; // 鏄惁杩炴帴
+ private Socket _clientSocket; // 濂楁帴瀛�
+
+ public event EventHandler<string> ExecuteMessageChanged;
+
+ public TcpClientTool3(string ip, int port)
+ {
+ this._ip = ip;
+ this._port = port;
+ }
+
+ public void Connect()
+ {
+ try
+ {
+ _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ IPAddress ipaddress = IPAddress.Parse(this._ip);
+ IPEndPoint endpoint = new IPEndPoint(ipaddress, _port);
+ _clientSocket.Connect(endpoint);
+ _isConnected = true;
+ }
+ catch (Exception ex)
+ {
+ _clientSocket.Dispose();
+ _isConnected = false;
+ throw ex;
+ }
+ }
+
+ public void Disconnect()
+ {
+ _clientSocket.Dispose();
+ }
+
+ public void Send(string data)
+ {
+ byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(data);
+ lock (this)
+ {
+ _clientSocket.Send(arrClientSendMsg);
+ }
+ }
+
+ public bool SendStep(
+ string ip, int port,
+ int ovenIndex, int cellIndex, string step, string value, string limitUp,
+ string limitDown, string unit, string result, string updateTime, out string errorMsg)
+ {
+
+ errorMsg = null;
+ try
+ {
+ if (!_isConnected)
+ {
+ errorMsg = "Not Connected";
+ return false;
+ }
+
+ string msg = $"{ovenIndex};{cellIndex};{step},{value},{limitUp},{limitDown},{unit},{result},{updateTime}\n";
+ Send(msg);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ errorMsg = ex.Message;
+ return false;
+ }
+ }
+ }
+}
diff --git a/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs b/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
index 19006db..02cb527 100644
--- a/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
+++ b/HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
@@ -315,7 +315,14 @@
{
try
{
- AlarmTexts = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmText>>(alarmTextPath);
+ if (string.IsNullOrEmpty(alarmTextPath) || !File.Exists(alarmTextPath))
+ {
+ AlarmTexts = new ObservableCollection<AlarmText>();
+ }
+ else
+ {
+ AlarmTexts = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmText>>(alarmTextPath);
+ }
}
catch (Exception ex)
{
@@ -323,8 +330,6 @@
AlarmTexts = new ObservableCollection<AlarmText>();
}
}
-
-
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
@@ -339,6 +344,11 @@
Loaded -= UserControl_Loaded;
}
+ public override void DoClose(object sender, EventArgs e)
+ {
+ // AlarmUtil.OnAlarm -= AlarmUtil_OnAlarm;
+ }
+
//private void MonitorTimer_Elapsed_bak(object sender, ElapsedEventArgs e)
//{
// try
diff --git a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
index 767066e..360439f 100644
--- a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
+++ b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
@@ -150,7 +150,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
diff --git a/HMI.AlermInfoManage/app.config b/HMI.AlermInfoManage/app.config
deleted file mode 100644
index a0cefc2..0000000
--- a/HMI.AlermInfoManage/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/HMI.Core/Entity/ParameterData.cs b/HMI.Core/Entity/ParameterData.cs
index 7c67c8d..a86f6c4 100644
--- a/HMI.Core/Entity/ParameterData.cs
+++ b/HMI.Core/Entity/ParameterData.cs
@@ -9,6 +9,13 @@
public string Name { get; set; }
[ExcelColumn("璁剧疆椤圭被鍨�")]
public string Type { get; set; }
+
+ [ExcelColumn("鏄惁涓烘暟缁�")]
+ public bool IsArray { get; set; } = false;
+
+ [ExcelColumn("鏁扮粍闀垮害")]
+ public int Length { get; set; } = 1;
+
[ExcelColumn("鍊�")]
public string Value { get; set; }
[ExcelColumn("鍗曚綅")]
diff --git a/HMI.Core/FontSizeConverter.cs b/HMI.Core/FontSizeConverter.cs
index ecadb25..2498c4c 100644
--- a/HMI.Core/FontSizeConverter.cs
+++ b/HMI.Core/FontSizeConverter.cs
@@ -8,6 +8,7 @@
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
+ /// "{size},{鍩哄噯鍊紏,{鏈�灏忓�紏,{鏈�澶у�紏"
if (parameter == null) return 15;
string[] ps = parameter.ToString().Split(',');
diff --git a/HMI.Core/Manager/ProductManager.cs b/HMI.Core/Manager/ProductManager.cs
index 94f7edf..96e10d6 100644
--- a/HMI.Core/Manager/ProductManager.cs
+++ b/HMI.Core/Manager/ProductManager.cs
@@ -1,4 +1,5 @@
锘縰sing HMI.Core.Entity;
+using HMI.Core.Setting;
using HMI.Core.Util;
using System.Collections.Generic;
using System.IO;
@@ -11,13 +12,32 @@
/// </summary>
public class ProductManager
{
+ public static string GetFolder()
+ {
+ if (ParamSetting.ShareConfig != null)
+ {
+ return Path.Combine(ParamSetting.ShareConfig, "Product");
+ }
+ return Path.Combine(PathHelper.ConfigFolder, "Product");
+ }
+
+ public static string GetDataFilePath()
+ {
+ return Path.Combine(GetFolder(), "Product.data");
+ }
+
+ public static string GetParamFolderByProductName(string productName)
+ {
+ return Path.Combine(GetFolder(), "Parameter", $"Parameter_{productName}.data");
+ }
+
/// <summary>
/// 鑾峰彇淇濆瓨鐨勪骇鍝�
/// </summary>
/// <returns></returns>
public static T GetProducts<T>() where T : IList<ProductData>
{
- string path = PathHelper.ProductDataFile;
+ string path = GetDataFilePath();
if (!File.Exists(path)) return default(T);
T datas = XmlHelper.DeserializeFromXml<T>(path);
return datas;
@@ -29,7 +49,7 @@
/// <returns></returns>
public static T GetParametersByProductName<T>(string productName) where T : IList<ParameterData>
{
- string path = Path.Combine(PathHelper.ProductParameterFolder, $"Parameter_{productName}.data");
+ string path = GetParamFolderByProductName(productName);
if (!File.Exists(path)) return default(T);
T datas = XmlHelper.DeserializeFromXml<T>(path);
return datas;
diff --git a/HMI.Core/Properties/AssemblyInfo.cs b/HMI.Core/Properties/AssemblyInfo.cs
index fa4d953..9b1611c 100644
--- a/HMI.Core/Properties/AssemblyInfo.cs
+++ b/HMI.Core/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
//鍙互鎸囧畾鎵�鏈夎繖浜涘�硷紝涔熷彲浠ヤ娇鐢ㄢ�滅敓鎴愬彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊�
//閫氳繃浣跨敤 "*"锛屽涓嬫墍绀�:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
diff --git a/HMI.Core/Setting/ParamSetting.cs b/HMI.Core/Setting/ParamSetting.cs
index 974bc46..e01cc33 100644
--- a/HMI.Core/Setting/ParamSetting.cs
+++ b/HMI.Core/Setting/ParamSetting.cs
@@ -34,6 +34,9 @@
/// 鍚敤鎵爜鎹㈠瀷
/// </summary>
public static bool EnableAutoModel { get; private set; } = false;
+ public static string ShareConfig { get; private set; } = null;
+ public static bool ShowBurnInAbort { get; private set; } = true;
+ public static string SocketNames { get; private set; } = string.Empty;
static ParamSetting()
{
@@ -148,6 +151,33 @@
{
}
+
+ try
+ {
+ ShareConfig = ParameterManager.GetCommonParameterByName<string>("ShareConfig", null);
+ }
+ catch
+ {
+
+ }
+
+ try
+ {
+ ShowBurnInAbort = ParameterManager.GetCommonParameterByName<bool>("ShowBurnInAbort", true);
+ }
+ catch
+ {
+
+ }
+
+ try
+ {
+ SocketNames = ParameterManager.GetCommonParameterByName<string>("SocketNames", string.Empty);
+ }
+ catch
+ {
+
+ }
}
}
}
diff --git a/HMI.Core/Util/HexUtil.cs b/HMI.Core/Util/HexUtil.cs
index 546bd63..19a79b7 100644
--- a/HMI.Core/Util/HexUtil.cs
+++ b/HMI.Core/Util/HexUtil.cs
@@ -2,15 +2,15 @@
namespace HMI.Core.Util
{
- public class HexUtil
- {
- public static byte[] ToBytesFromHexString(string hexString)
- {
- //浠� ' ' 鍒嗗壊瀛楃涓诧紝骞跺幓鎺夌┖瀛楃
- string[] chars = hexString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
- byte[] returnBytes;
- returnBytes = BitConverter.GetBytes(Convert.ToInt32(chars[0]));
- return returnBytes;
- }
- }
+ //public class HexUtil
+ //{
+ // public static byte[] ToBytesFromHexString(string hexString)
+ // {
+ // //浠� ' ' 鍒嗗壊瀛楃涓诧紝骞跺幓鎺夌┖瀛楃
+ // string[] chars = hexString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ // byte[] returnBytes;
+ // returnBytes = BitConverter.GetBytes(Convert.ToInt32(chars[0]));
+ // return returnBytes;
+ // }
+ //}
}
diff --git a/HMI.Core/Util/PathHelper.cs b/HMI.Core/Util/PathHelper.cs
index 956c8bc..092287d 100644
--- a/HMI.Core/Util/PathHelper.cs
+++ b/HMI.Core/Util/PathHelper.cs
@@ -50,16 +50,8 @@
/// </summary>
public static string ParameterDataPath { get; private set; }
- /// <summary>
- /// 浜у搧鏁版嵁鐩綍
- /// </summary>
- public static string ProductDataFolder { get; private set; }
- public static string ProductParameterFolder { get; private set; }
-
- /// <summary>
- /// 浜у搧鏁版嵁婧愭枃浠�
- /// </summary>
- public static string ProductDataFile { get; private set; }
+
+
/// <summary>
/// 娴嬭瘯椤规暟鎹洰褰�
@@ -94,11 +86,11 @@
ParameterFolder = InitFolder(ConfigFolder + "\\Parameter");
ParameterDataPath = ParameterFolder + "\\CommonParameter.data";
- ProductDataFolder = InitFolder(ConfigFolder + "\\Product");
- ProductParameterFolder = InitFolder(ProductDataFolder + "\\Parameter");
- ProductDataFile = ProductDataFolder + "\\Product.data";
+ //ProductDataFolder = InitFolder(ConfigFolder + "\\Product");
+ //ProductParameterFolder = InitFolder(ProductDataFolder + "\\Parameter");
+ //ProductDataFile = ProductDataFolder + "\\Product.data";
- TestItemDataFolder = InitFolder(ProductDataFolder + "\\TestItem");
+ // TestItemDataFolder = InitFolder(ProductDataFolder + "\\TestItem");
TestItemDataFile = TestItemDataFolder + "\\TestItem.data";
LogViewerDir = InitFolder(ConfigFolder + "\\LogViewer");
diff --git a/HMI.Core/Util/Sqlite3Helper.cs b/HMI.Core/Util/Sqlite3Helper.cs
index bc979d4..57fe091 100644
--- a/HMI.Core/Util/Sqlite3Helper.cs
+++ b/HMI.Core/Util/Sqlite3Helper.cs
@@ -52,6 +52,46 @@
}
}
+ public long InsertWithId(string Sql)
+ {
+ try
+ {
+ if (Sql.EndsWith(";"))
+ {
+ Sql += "SELECT last_insert_rowid();";
+ }
+ else
+ {
+ Sql += ";SELECT last_insert_rowid();";
+ }
+ using (var cmd = new SQLiteCommand(Sql, conn))
+ {
+ return (long)cmd.ExecuteScalar();
+ }
+ }
+ catch (Exception ex)
+ {
+ string message = "ExecuteSql Error:" + ex.Message;
+ throw new Exception(message);
+ }
+ }
+
+ public object SelectOne(string Sql)
+ {
+ try
+ {
+ using (var cmd = new SQLiteCommand(Sql, conn))
+ {
+ return cmd.ExecuteScalar();
+ }
+ }
+ catch (Exception ex)
+ {
+ string message = "ExecuteSql Error:" + ex.Message;
+ throw new Exception(message);
+ }
+ }
+
public int ExecuteBatch(IEnumerable<string> sqls)
{
SQLiteTransaction tr = null;
diff --git a/HMI.DataViewer/DataViewer.xaml.cs b/HMI.DataViewer/DataViewer.xaml.cs
index 283734b..d704535 100644
--- a/HMI.DataViewer/DataViewer.xaml.cs
+++ b/HMI.DataViewer/DataViewer.xaml.cs
@@ -1,6 +1,7 @@
锘縰sing HMI.Base;
using HMI.Core.Util;
using HMI.DataViewer.Entity;
+using HMI.UI.Converter;
using HMI.UI.Util;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
@@ -19,22 +20,7 @@
namespace HMI.DataViewer
{
- public class DefaultValueConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value is DateTime date)
- {
- return date.ToString("yyyy-MM-dd HH:mm:ss");
- }
- return value.ToString();
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- return value;
- }
- }
+
/// <summary>
/// UserControl1.xaml 鐨勪氦浜掗�昏緫
@@ -65,8 +51,6 @@
}
private Dictionary<string, DataBase_Setting> Map = new Dictionary<string, DataBase_Setting>();
-
- private IValueConverter defaultConverter = new DefaultValueConverter();
private void Button_Click(object sender, RoutedEventArgs e)
{
@@ -285,7 +269,7 @@
Header = header,
Binding = new System.Windows.Data.Binding(bindingPath)
{
- Converter = defaultConverter
+ Converter = DateStrConverter.Instance
},
Width = new DataGridLength(1, DataGridLengthUnitType.Star)
};
diff --git a/HMI.LogViewer/LogViewer.xaml b/HMI.LogViewer/LogViewer.xaml
index 684a64e..004f847 100644
--- a/HMI.LogViewer/LogViewer.xaml
+++ b/HMI.LogViewer/LogViewer.xaml
@@ -71,7 +71,7 @@
<StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
<Button Style="{StaticResource QueryBtn}"
x:Name="queryBtn" Click="Button_Click"/>
- <Button Style="{StaticResource RfhBtn}"
+ <Button Style="{StaticResource ResetBtn}"
x:Name="resetBtn" Click="Button_Click"/>
<!--<Button x:Name="exportBtn"
Style="{StaticResource ExportBtn}" Click="Button_Click"/>-->
@@ -88,14 +88,16 @@
<ComboBoxItem Content="Error"/>
</ComboBox>
- <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource App.StartTime}"/>
- <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="startTimeInput"/>
-
- <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource App.EndTime}"/>
- <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="endTimeInput"/>
-
<TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource log.source}"/>
<TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="sourceInput" Width="180"/>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource App.StartTime}"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" IsEnabled="{Binding AutoRfh,Converter={StaticResource reverseBool}}"
+ x:Name="startTimeInput"/>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource App.EndTime}"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" IsEnabled="{Binding AutoRfh,Converter={StaticResource reverseBool}}"
+ x:Name="endTimeInput"/>
<TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource log.autoRefresh}"/>
<CheckBox x:Name="autoRfhInput" HorizontalAlignment="Center" VerticalAlignment="Center"
@@ -159,7 +161,7 @@
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Style="{StaticResource CellBorder}">
- <TextBlock VerticalAlignment="Center" Text="{Binding time}"/>
+ <TextBlock VerticalAlignment="Center" Text="{Binding time,Converter={x:Static uic:DateStrConverter.Instance},ConverterParameter='yyyy-MM-dd HH:mm:ss.fff'}"/>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
@@ -177,6 +179,7 @@
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
+
<GridViewColumn Width="1420">
<GridViewColumn.Header>
<TextBlock Text="{DynamicResource log.text}"/>
@@ -194,6 +197,12 @@
</ListView.View>
</ListView>
+ <StackPanel Grid.Row="3" HorizontalAlignment="Right">
+ <pu:Pagination Style="{StaticResource DefaultPage}"
+ CurrentPage="{Binding CurrentPage}"
+ MaxPage="{Binding MaxPage}"/>
+ </StackPanel>
+
<!--<DataGrid Grid.Row="2" x:Name="table"
CellStyle="{StaticResource sbCell}"
RowHeight="{StaticResource nanD}" Style="{StaticResource DefaultDataGrid}">
diff --git a/HMI.LogViewer/LogViewer.xaml.cs b/HMI.LogViewer/LogViewer.xaml.cs
index 3920fbb..a2fc8f4 100644
--- a/HMI.LogViewer/LogViewer.xaml.cs
+++ b/HMI.LogViewer/LogViewer.xaml.cs
@@ -33,23 +33,26 @@
private Timer autoRfhTimer;
- private int currentPage = 1;
- public int CurrentPage
+ private long pageSize = 50;
+
+ private long currentPage = 1;
+ public long CurrentPage
{
get => currentPage;
set
{
Set(ref currentPage, value);
+ Filtrate(value, pageSize);
}
}
- private int maxPage = 0;
- public int MaxPage
+ private long maxPage = 1;
+ public long MaxPage
{
get => maxPage;
set
{
- Set(ref currentPage, value);
+ Set(ref maxPage, value);
}
}
@@ -65,6 +68,7 @@
};
autoRfhTimer.Elapsed += AutoRfhTimer_Elapsed;
InitializeComponent();
+ QueryReset();
}
public override void InitFinish()
@@ -93,7 +97,6 @@
//}
}
-
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= UserControl_Loaded;
@@ -103,6 +106,10 @@
{
Refresh100items();
}
+
+ //private void RefreshTable() {
+ // if(CurrentPage == )
+ //}
private void Button_Click(object sender, RoutedEventArgs e)
{
@@ -114,6 +121,7 @@
break;
case "resetBtn":
QueryReset();
+ CurrentPage = 1;
break;
case "exportBtn":
DoExport();
@@ -144,9 +152,10 @@
return;
}
- queryBtn.IsEnabled = false;
- autoRfhInput.IsEnabled = false;
- Filtrate();
+ AutoRfh = false;
+ //queryBtn.IsEnabled = false;
+ //autoRfhInput.IsEnabled = false;
+ CurrentPage = 1;
}
catch (Exception ex)
{
@@ -162,31 +171,60 @@
private void QueryReset()
{
+ var today = DateTime.Now;
+ var start = DateTime.Parse(today.ToString("yyyy-MM-dd 00:00:00")).AddDays(-7);
+ var end = DateTime.Parse(today.ToString("yyyy-MM-dd 00:00:00")).AddDays(1);
+
levelInput.Text = null;
- startTimeInput.SelectedDateTime = null;
- endTimeInput.SelectedDateTime = null;
- startTimeInput.Text = null;
- table.ItemsSource = null;
+ startTimeInput.SelectedDateTime = start;
+ endTimeInput.SelectedDateTime = end;
}
- private void Filtrate()
+ private void Filtrate(long page, long size)
{
- string str = LoadSql();
- DataTable dt = new DataTable();
- var files = GetOldDbFiles(PathHelper.LogViewerDir, new DateTime?[] { startTimeInput.SelectedDateTime,
+ try
+ {
+ var files = GetOldDbFiles(PathHelper.LogViewerDir, new DateTime?[] { startTimeInput.SelectedDateTime,
endTimeInput.SelectedDateTime });
- foreach (string file in files)
- {
- using (SqliteHelper sql = new SqliteHelper(file))
+ if (files.Length <= 0)
{
- dt.Merge(sql.GetDataTable(str));
+ table.ItemsSource = new DataTable().DefaultView;
+ return;
}
+
+ using (Sqlite3Helper helper = new Sqlite3Helper(files[0]))
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ }
+
+ string sql = string.Join(" UNION ALL ", GetSqls(files));
+
+ string sortName = "time", sortDirection = "DESC";
+
+ string baseSql = $"SELECT level,time,source,text FROM ({sql}) as _temp";
+
+ string countSql = $"SELECT COUNT(1) FROM ({sql}) as __temp";
+
+ long total = (long)helper.SelectOne(countSql);
+ long pages = (total/pageSize)+ ((total % pageSize) > 0 ? 1 : 0);
+
+ sql = $"{baseSql} ORDER BY {sortName} {sortDirection} LIMIT {size} OFFSET {(page - 1) * size} ";
+
+ DataTable dt = helper.GetDataTable(sql);
+ table.ItemsSource = dt.DefaultView;
+
+ MaxPage = pages;
+ }
+
}
- if (dt.Rows.Count > 0)
+ catch (Exception ex)
{
- dt.DefaultView.Sort = "time Desc";
+ log.Error("Select Log Error.", ex);
+ MsgBoxHelper2.Error($"鏌ヨ澶辫触: {ex.Message}");
}
- table.ItemsSource = dt.DefaultView;
}
public static string[] GetOldDbFiles(string folderPath, DateTime?[] range)
@@ -217,35 +255,40 @@
}
/// <summary>
- /// 鍔犺浇鐣岄潰鍒ゆ柇鏁版嵁搴撹鍙�
+ ///
/// </summary>
- /// <returns> str鏁版嵁搴撶殑璇彞 </returns>
- private string LoadSql()
+ /// <param name="files"></param>
+ /// <returns></returns>
+ private string[] GetSqls(string[] files)
{
- string sql = " select level,time,source,text from log";
- List<string> datas = new List<string>();
- if (!string.IsNullOrEmpty(levelInput.Text))
+ string[] sqls = new string[files.Length];
+ for (int i = 0; i < files.Length; i++)
{
- datas.Add($"level='{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 sql = $"SELECT level,time,source,text FROM db{i}.log";
+ List<string> datas = new List<string>();
+ if (!string.IsNullOrEmpty(levelInput.Text))
+ {
+ datas.Add($"level='{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;
+ string condition = string.Join(" AND ", datas);
+ condition = string.IsNullOrEmpty(condition) ? string.Empty : $" WHERE {condition}";
+ sql = $"{sql}{condition}";
+ sqls[i] = sql;
+ }
+ return sqls;
}
/// <summary>
@@ -267,6 +310,7 @@
this.Dispatcher.BeginInvoke((Action)delegate ()
{
table.ItemsSource = dt.DefaultView;
+ MaxPage = 1;
});
}
}
diff --git a/HMI.ParameterManage/Model/XmlModel.cs b/HMI.ParameterManage/Model/XmlModel.cs
index da86c39..92210e2 100644
--- a/HMI.ParameterManage/Model/XmlModel.cs
+++ b/HMI.ParameterManage/Model/XmlModel.cs
@@ -191,7 +191,7 @@
/// <param name="datas"></param>
private void SaveProduct(IList<ProductData> datas)
{
- XmlHelper.SerializeToXml(PathHelper.ProductDataFile, datas);
+ XmlHelper.SerializeToXml(ProductManager.GetDataFilePath(), datas);
}
#endregion
@@ -257,13 +257,13 @@
/// <param name="datas"></param>
private void SaveParameter(IList<ParameterData> datas)
{
- string fileName = Path.Combine(PathHelper.ProductDataFolder, "Parameter", $"Parameter_{SelectedProduct.Name}.data");
+ string fileName = ProductManager.GetParamFolderByProductName(SelectedProduct.Name);
XmlHelper.SerializeToXml(fileName, datas);
}
private void SaveParameter(string product, IList<ParameterData> datas)
{
- string fileName = Path.Combine(PathHelper.ProductDataFolder, "Parameter", $"Parameter_{product}.data");
+ string fileName = ProductManager.GetParamFolderByProductName(product);
XmlHelper.SerializeToXml(fileName, datas);
}
#endregion
diff --git a/HMI.ParameterManage/ParameterManage.xaml.cs b/HMI.ParameterManage/ParameterManage.xaml.cs
index 73685f9..23e543f 100644
--- a/HMI.ParameterManage/ParameterManage.xaml.cs
+++ b/HMI.ParameterManage/ParameterManage.xaml.cs
@@ -1,11 +1,16 @@
锘縰sing HMI.Base;
using HMI.Core.Entity;
+using HMI.Core.Manager;
using HMI.Core.Util;
using HMI.ParameterManage.Model;
using HMI.UI.Util;
+using NPOI.POIFS.NIO;
+using NPOI.SS.Formula.Functions;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Markup;
namespace HMI.ParameterManage
{
@@ -97,13 +102,34 @@
ToastHelper.Warning(Window.GetWindow(this), this.lang("Pm.PleaseSelectProduct"));
return;
}
- var win = new ParameterModal(Model)
+ //var win = new ParameterModal(Model)
+ //{
+ // Title = data == null ? this.lang("Pm.Parameter.Add") : this.lang("Pm.Parameter.Edit"),
+ // Owner = Window.GetWindow(this),
+ //};
+ //if (win.Open(Model.SelectedProduct.Name, data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }, Model.groups) == true)
+ //{
+ // Model.LoadParameters();
+ //}
+
+ SettingModal modal = new SettingModal()
{
Title = data == null ? this.lang("Pm.Parameter.Add") : this.lang("Pm.Parameter.Edit"),
- Owner = Window.GetWindow(this),
+ Owner = Window.GetWindow(this)
};
- if (win.Open(Model.SelectedProduct.Name, data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }, Model.groups) == true)
+ var target = data ?? new ParameterData();
+ if (modal.Open(target, Model.Parameters, Model.groups, Model.SelectedProduct.Name) == true)
{
+ //if (index == -1)
+ //{
+ // Datasource.Add(modal.Data);
+ // ParameterManager.SaveCommonParameter(Datasource);
+ //}
+ //else
+ //{
+ // ParameterManager.SaveCommonParameter(Datasource);
+ //}
+ Model.SaveOrUpdateParameter(target);
Model.LoadParameters();
}
}
diff --git a/HMI.ParameterManage/ParameterModal.xaml b/HMI.ParameterManage/ParameterModal.xaml
index c93342f..2fb7f11 100644
--- a/HMI.ParameterManage/ParameterModal.xaml
+++ b/HMI.ParameterManage/ParameterModal.xaml
@@ -46,6 +46,10 @@
</ComboBox>
</pu:FormGroup>
+ <pu:FormGroup x:Name="FgIsArray" Header="IsArray" dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+ <CheckBox x:Name="CbIsArray" />
+ </pu:FormGroup>
+
<pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}"
Header="{DynamicResource Pm.Parameter.Value}"
dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
diff --git a/HMI.ParameterManage/ParameterModal.xaml.cs b/HMI.ParameterManage/ParameterModal.xaml.cs
index d7553d4..c89f0ea 100644
--- a/HMI.ParameterManage/ParameterModal.xaml.cs
+++ b/HMI.ParameterManage/ParameterModal.xaml.cs
@@ -81,6 +81,7 @@
{
Data.Name = TbName.Text;
Data.Type = CbType.Text;
+ Data.IsArray = CbIsArray.IsChecked == true;
Data.Value = GetTargetValue();
Data.Unit = TbUnit.Text;
Data.Description = TbDescription.Text;
@@ -95,6 +96,7 @@
Data = data;
TbName.Text = Data.Name;
CbType.SelectedValue = Data.Type;
+ CbIsArray.IsChecked = Data.IsArray;
CbGroup.ItemsSource = groups;
UpdateWindow(Data.Type);
UpdateForm(Data);
diff --git a/HMI.ParameterManage/SettingModal.xaml b/HMI.ParameterManage/SettingModal.xaml
index 37370f6..1078321 100644
--- a/HMI.ParameterManage/SettingModal.xaml
+++ b/HMI.ParameterManage/SettingModal.xaml
@@ -19,6 +19,13 @@
<Grid Margin="10">
<StackPanel x:Name="formPanel">
+ <pu:FormGroup x:Name="FgProductName" Visibility="Collapsed"
+ Header="{DynamicResource Pm.Product.Name}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <TextBox x:Name="TbProductName" IsReadOnly="True" Style="{StaticResource EditorTextBoxStyle}" />
+ </pu:FormGroup>
+
<pu:FormGroup x:Name="FgName"
dp:FormGroupHelper.ValidateMethod="ValidateName"
Header="{DynamicResource Pm.Parameter.Name}"
@@ -37,6 +44,14 @@
<ComboBoxItem>Bool</ComboBoxItem>
<ComboBoxItem>String</ComboBoxItem>
</ComboBox>
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgIsArray" Header="IsArray" dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+ <CheckBox x:Name="CbIsArray" Checked="CbIsArray_Checked" Unchecked="CbIsArray_Checked"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgLength" Visibility="Collapsed" Header="Length" dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+ <ui:NumberInput x:Name="NiLength" TextChanged="NiLength_TextChanged" Style="{StaticResource EditorTextBoxStyle}"/>
</pu:FormGroup>
<pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}"
@@ -58,6 +73,8 @@
<TextBox x:Name="TbStringValue" Style="{StaticResource EditorTextBoxStyle}"/>
<Button Grid.Column="1" Click="Button_Click" Style="{StaticResource SearchButton}"/>
</Grid>
+ <DataGrid Visibility="Collapsed"
+ x:Name="arrayInput" MinHeight="100" MaxHeight="200" CanUserAddRows="False" CanUserDeleteRows="False"></DataGrid>
</Grid>
</pu:FormGroup>
diff --git a/HMI.ParameterManage/SettingModal.xaml.cs b/HMI.ParameterManage/SettingModal.xaml.cs
index 308485e..22569d6 100644
--- a/HMI.ParameterManage/SettingModal.xaml.cs
+++ b/HMI.ParameterManage/SettingModal.xaml.cs
@@ -3,17 +3,62 @@
using HMI.UI.DpUtil;
using HMI.UI.Util;
using Microsoft.Win32;
+using NPOI.SS.Formula.Functions;
+using NPOI.SS.Formula.PTG;
using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
-using System.Text.RegularExpressions;
using System.Windows.Controls;
namespace HMI.ParameterManage
{
+ public class BoolData
+ {
+ public int Index { get; }
+ public bool Value { get; set; }
+
+ public BoolData(int index)
+ {
+ this.Index = index;
+ }
+ }
+
+ public class IntData
+ {
+ public int Index { get; }
+ public int Value { get; set; }
+
+ public IntData(int index)
+ {
+ this.Index = index;
+ }
+ }
+
+ public class DoubleData
+ {
+ public int Index { get; }
+ public double Value { get; set; }
+
+ public DoubleData(int index)
+ {
+ this.Index = index;
+ }
+ }
+
+ public class StringData
+ {
+ public int Index { get; }
+ public string Value { get; set; } = string.Empty;
+
+ public StringData(int index)
+ {
+ this.Index = index;
+ }
+ }
+
/// <summary>
/// ModalWindow.xaml 鐨勪氦浜掗�昏緫
/// </summary>
@@ -93,6 +138,9 @@
{
Data.Name = TbName.Text;
Data.Type = CbType.Text;
+ Data.IsArray = CbIsArray.IsChecked == true;
+ Data.Length = int.Parse(NiLength.Text);
+
Data.Value = GetTargetValue();
Data.Unit = TbUnit.Text;
Data.Description = TbDescription.Text;
@@ -102,14 +150,23 @@
return flag;
}
- public bool? Open(ParameterData data, ObservableCollection<ParameterData> datasource, List<string> groups)
+ public bool? Open(ParameterData data, ObservableCollection<ParameterData> datasource, List<string> groups,string productName = null)
{
+ if (!string.IsNullOrEmpty(productName))
+ {
+ FgProductName.Visibility = System.Windows.Visibility.Visible;
+ TbProductName.Text = productName;
+ }
+
Datasource = datasource;
Data = data;
TbGroup.ItemsSource = groups;
TbName.Text = Data.Name;
CbType.SelectedValue = Data.Type;
+ CbIsArray.IsChecked = Data.IsArray;
+ NiLength.Text = Data.Length.ToString();
+
UpdateWindow(Data.Type);
UpdateForm(Data);
@@ -123,6 +180,12 @@
private string GetTargetValue()
{
var type = CbType.Text;
+ if (CbIsArray.IsChecked == true)
+ {
+ var arr = (object[])arrayInput.ItemsSource;
+ return string.Join(",", arr.Select(e => e.GetType().GetProperty("Value").GetValue(e).ToString()).ToArray());
+ }
+
if (type == "Int" || type == "Double")
{
return NiNumberValue.Text;
@@ -139,17 +202,25 @@
private void UpdateForm(ParameterData data)
{
- if (Data.Type == "Int" || Data.Type == "Int")
+ if (data.IsArray)
{
- NiNumberValue.Text = Data.Value;
- }
- else if (Data.Type == "Bool")
- {
- CbBoolValue.SelectedValue = Data.Value;
+ string[] arr = data.Value.Split(',');
+ arrayInput.ItemsSource = RefreshArray(arr, Data.Type);
}
else
{
- TbStringValue.Text = Data.Value;
+ if (Data.Type == "Int" || Data.Type == "Int")
+ {
+ NiNumberValue.Text = Data.Value;
+ }
+ else if (Data.Type == "Bool")
+ {
+ CbBoolValue.SelectedValue = Data.Value;
+ }
+ else
+ {
+ TbStringValue.Text = Data.Value;
+ }
}
}
@@ -183,6 +254,10 @@
val = ((ComboBoxItem)e.AddedItems[0]).Content.ToString();
}
UpdateWindow(val);
+ if (CbIsArray.IsChecked == true)
+ {
+ arrayInput.ItemsSource = RefreshArray(GetLength(), val);
+ }
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
@@ -193,5 +268,111 @@
TbStringValue.Text = ofd.FileName;
}
}
+
+ private void CbIsArray_Checked(object sender, System.Windows.RoutedEventArgs e)
+ {
+ bool isChecked = ((CheckBox)sender).IsChecked == true;
+ if (isChecked)
+ {
+ FgLength.Visibility = System.Windows.Visibility.Visible;
+ arrayInput.Visibility = System.Windows.Visibility.Visible;
+ arrayInput.ItemsSource = RefreshArray(GetLength(), CbType.Text);
+ }
+ else
+ {
+ FgLength.Visibility = System.Windows.Visibility.Collapsed;
+ arrayInput.Visibility = System.Windows.Visibility.Collapsed;
+ }
+ }
+
+ private object[] RefreshArray(int length, string type)
+ {
+ var arr = new object[length];
+ for (int i = 0; i < length; i++)
+ {
+ if (type == "Int")
+ {
+ arr[i] = new IntData(i);
+ }
+ else if (type == "Double")
+ {
+ arr[i] = new DoubleData(i);
+ }
+ else if (type == "Bool")
+ {
+ arr[i] = new BoolData(i);
+ }
+ else
+ {
+ arr[i] = new StringData(i);
+ }
+ }
+ return arr;
+ }
+
+ private object[] RefreshArray(string[] source, string type)
+ {
+ var arr = new object[source.Length];
+ type = string.IsNullOrEmpty(type) ? "String" : type;
+ for (int i = 0; i < arr.Length; i++)
+ {
+ if (type == "Int")
+ {
+ arr[i] = new IntData(i)
+ {
+ Value = int.Parse(source[i])
+ };
+ }
+ else if (type == "Double")
+ {
+ arr[i] = new DoubleData(i)
+ {
+ Value = double.Parse(source[i])
+ };
+ }
+ else if (type == "Bool")
+ {
+ arr[i] = new BoolData(i)
+ {
+ Value = bool.Parse(source[i])
+ };
+ }
+ else
+ {
+ arr[i] = new StringData(i)
+ {
+ Value = source[i]
+ };
+ }
+ }
+ return arr;
+ }
+
+ private int GetLength()
+ {
+ try
+ {
+ string text = NiLength.Text;
+ if (text.Contains("."))
+ {
+ text = text.Split('.')[0];
+ }
+ int length = int.Parse(text);
+ return length > 0 ? length : 1;
+ }
+ catch
+ {
+ return 1;
+ }
+ }
+
+ private void NiLength_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (CbIsArray.IsChecked != true)
+ {
+ return;
+ }
+ arrayInput.ItemsSource = RefreshArray(GetLength(), CbType.Text);
+ }
}
}
diff --git a/HMI.StdControl/HMI.StdControl.csproj b/HMI.StdControl/HMI.StdControl.csproj
index a9e7344..d30adf5 100644
--- a/HMI.StdControl/HMI.StdControl.csproj
+++ b/HMI.StdControl/HMI.StdControl.csproj
@@ -46,12 +46,19 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="StdSettingCheckBox.xaml.cs">
+ <DependentUpon>StdSettingCheckBox.xaml</DependentUpon>
+ </Compile>
<Compile Include="StdEnableMes.xaml.cs">
<DependentUpon>StdEnableMes.xaml</DependentUpon>
</Compile>
<Compile Include="StdUIEventArg.cs" />
</ItemGroup>
<ItemGroup>
+ <Page Include="StdSettingCheckBox.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="StdEnableMes.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/HMI.StdControl/StdSettingCheckBox.xaml b/HMI.StdControl/StdSettingCheckBox.xaml
new file mode 100644
index 0000000..ddda536
--- /dev/null
+++ b/HMI.StdControl/StdSettingCheckBox.xaml
@@ -0,0 +1,14 @@
+锘�<UserControl x:Class="HMI.StdControl.StdSettingCheckBox"
+ 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:HMI.StdControl"
+ mc:Ignorable="d"
+ x:Name="self"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <CheckBox x:Name="CbEnableMes" IsChecked="{Binding IsChecked,ElementName=self,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ VerticalContentAlignment="Center"
+ IsEnabled="{Binding CbEnabled,ElementName=self}"
+ Content="{Binding Text,ElementName=self}" />
+</UserControl>
diff --git a/HMI.StdControl/StdSettingCheckBox.xaml.cs b/HMI.StdControl/StdSettingCheckBox.xaml.cs
new file mode 100644
index 0000000..9450c9c
--- /dev/null
+++ b/HMI.StdControl/StdSettingCheckBox.xaml.cs
@@ -0,0 +1,155 @@
+锘縰sing HMI.Core.Manager;
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.StdControl
+{
+ /// <summary>
+ /// StdEnableMes.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class StdSettingCheckBox : UserControl, INotifyPropertyChanged
+ {
+
+ #region ...
+ public virtual event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void Set([CallerMemberName] string name = null)
+ {
+
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ protected void Set<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null)
+ {
+ Set(propertyName);
+ }
+ }
+ #endregion
+
+ private event EventHandler<StdUIEventArg> valueChanged;
+ public event EventHandler<StdUIEventArg> ValueChanged
+ {
+ add
+ {
+ valueChanged += value;
+ }
+ remove
+ {
+ valueChanged -= value;
+ }
+ }
+
+ public static DependencyProperty IsCheckedProperty = DependencyProperty.Register(
+ "IsChecked",
+ typeof(bool),
+ typeof(StdSettingCheckBox),
+ new FrameworkPropertyMetadata(false));
+
+ public static DependencyProperty ValueProperty = DependencyProperty.Register(
+ "Value",
+ typeof(string),
+ typeof(StdSettingCheckBox),
+ new FrameworkPropertyMetadata(null));
+
+ public static DependencyProperty CbEnabledProperty = DependencyProperty.Register(
+ "CbEnabled",
+ typeof(bool),
+ typeof(StdSettingCheckBox),
+ new FrameworkPropertyMetadata(true));
+
+ public static DependencyProperty TextProperty = DependencyProperty.Register(
+ "Text",
+ typeof(string),
+ typeof(StdSettingCheckBox),
+ new FrameworkPropertyMetadata(null));
+
+
+ public bool CbEnabled
+ {
+ get => (bool)GetValue(CbEnabledProperty);
+ set
+ {
+ SetValue(CbEnabledProperty, value);
+ }
+ }
+
+ public string Value
+ {
+ get => (string)GetValue(ValueProperty);
+ set
+ {
+ SetValue(ValueProperty, value);
+ }
+ }
+
+ public string Text
+ {
+ get => (string)GetValue(TextProperty);
+ set
+ {
+ SetValue(TextProperty, value);
+ }
+ }
+
+ public bool IsChecked
+ {
+ get => (bool)GetValue(IsCheckedProperty);
+ set
+ {
+ if (WriteConfig(Value, value))
+ {
+ SetValue(IsCheckedProperty, value);
+ }
+ }
+ }
+
+ public StdSettingCheckBox()
+ {
+ InitializeComponent();
+ this.Loaded += StdSettingCheckBox_Loaded;
+ }
+
+ private void StdSettingCheckBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ var value = ParameterManager.GetCommonParameterByName(Value);
+ if (value == null)
+ {
+ this.Visibility = System.Windows.Visibility.Collapsed;
+ }
+ else
+ {
+ IsChecked = bool.Parse(value.Value);
+ }
+ }
+ catch
+ {
+ IsChecked = false;
+ }
+ }
+
+ private bool WriteConfig(string name, bool value)
+ {
+ try
+ {
+ valueChanged?.Invoke(this, new StdUIEventArg()
+ {
+ StringValue = name,
+ BoolValue = value
+ });
+ return ParameterManager.UpdateCommonParameter(name, value, out string errMsg);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/HMI.UI/Converter/DateStrConverter.cs b/HMI.UI/Converter/DateStrConverter.cs
new file mode 100644
index 0000000..3be6f7d
--- /dev/null
+++ b/HMI.UI/Converter/DateStrConverter.cs
@@ -0,0 +1,29 @@
+锘縰sing System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace HMI.UI.Converter
+{
+
+ public class DateStrConverter : IValueConverter
+ {
+ public static DateStrConverter Instance { get; } = new DateStrConverter();
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is DateTime date)
+ {
+ if (parameter != null)
+ {
+ return date.ToString(parameter.ToString());
+ }
+ return date.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ return value.ToString();
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return DateTime.Parse(value.ToString());
+ }
+ }
+}
diff --git a/HMI.UI/Converter/RadioEnumConverter.cs b/HMI.UI/Converter/RadioEnumConverter.cs
new file mode 100644
index 0000000..d003850
--- /dev/null
+++ b/HMI.UI/Converter/RadioEnumConverter.cs
@@ -0,0 +1,19 @@
+锘縰sing System;
+using System.Windows.Data;
+
+namespace HMI.UI.Converter
+{
+ public class RadioEnumConverter : IValueConverter
+ {
+ public static RadioEnumConverter Instance { get; } = new RadioEnumConverter();
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return value?.Equals(parameter);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return value?.Equals(true) == true ? parameter : Binding.DoNothing;
+ }
+ }
+}
diff --git a/HMI.UI/Converter/ResultConverter.cs b/HMI.UI/Converter/ResultConverter.cs
new file mode 100644
index 0000000..901b410
--- /dev/null
+++ b/HMI.UI/Converter/ResultConverter.cs
@@ -0,0 +1,31 @@
+锘縰sing System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace HMI.UI.Converter
+{
+ public class ResultConverter : IValueConverter
+ {
+ public static ResultConverter Instance = new ResultConverter();
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value == null) return value;
+ var str = value.ToString();
+ if (str.Equals("ok", StringComparison.OrdinalIgnoreCase) || str.Equals("pass", StringComparison.OrdinalIgnoreCase))
+ {
+ return "PASS";
+ }
+ if (str.Equals("ng", StringComparison.OrdinalIgnoreCase) || str.Equals("fail", StringComparison.OrdinalIgnoreCase))
+ {
+ return "FAIL";
+ }
+ return value;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+}
diff --git a/HMI.UI/HMI.UI.csproj b/HMI.UI/HMI.UI.csproj
index bef777c..0530193 100644
--- a/HMI.UI/HMI.UI.csproj
+++ b/HMI.UI/HMI.UI.csproj
@@ -98,6 +98,9 @@
<Compile Include="Controls\treegrid\TreeItemConverter.cs" />
<Compile Include="Controls\treegrid\TreeNodeExtend.cs" />
<Compile Include="Controls\VisualHost.cs" />
+ <Compile Include="Converter\DateStrConverter.cs" />
+ <Compile Include="Converter\RadioEnumConverter.cs" />
+ <Compile Include="Converter\ResultConverter.cs" />
<Compile Include="Converter\ReverseBoolConverter.cs" />
<Compile Include="Converter\IndentConverter.cs" />
<Compile Include="Converter\CollectionHasItem.cs" />
@@ -135,6 +138,9 @@
<Compile Include="MDI\Workspace.xaml.cs">
<DependentUpon>Workspace.xaml</DependentUpon>
</Compile>
+ <Compile Include="RequirePasswordByUser.xaml.cs">
+ <DependentUpon>RequirePasswordByUser.xaml</DependentUpon>
+ </Compile>
<Compile Include="RequirePasswordWindow.xaml.cs">
<DependentUpon>RequirePasswordWindow.xaml</DependentUpon>
</Compile>
@@ -152,6 +158,10 @@
<Compile Include="Util\MsgBoxHelper.cs" />
<Compile Include="Util\MsgBoxHelper2.cs" />
<Compile Include="Util\ToastHelper.cs" />
+ <Page Include="RequirePasswordByUser.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="RequirePasswordWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
diff --git a/HMI.UI/MaskControl.xaml b/HMI.UI/MaskControl.xaml
index b44ebf4..4f603ef 100644
--- a/HMI.UI/MaskControl.xaml
+++ b/HMI.UI/MaskControl.xaml
@@ -21,7 +21,7 @@
</Grid.ColumnDefinitions>
<Border Padding="10,5,0,5" Background="{DynamicResource PrimaryColor}"
CornerRadius="5,5,0,0">
- <Label Padding="2" BorderThickness="0" Margin="0" Foreground="#FFF" x:Name="titleLabel" Content="璇风◢鍚�"/>
+ <Label Padding="2" Background="Transparent" BorderThickness="0" Margin="0" Foreground="#FFF" x:Name="titleLabel" Content="璇风◢鍚�"/>
</Border>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center"
VerticalAlignment="Center"
@@ -48,7 +48,7 @@
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
- <TextBlock Grid.Row="1" Margin="20,0,0,0" Grid.Column="1" x:Name="contentLabel"
+ <TextBlock Grid.Row="1" Margin="20,0,0,0" Grid.Column="1" Background="Transparent" x:Name="contentLabel"
VerticalAlignment="Center" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
diff --git a/HMI.UI/RequirePasswordByUser.xaml b/HMI.UI/RequirePasswordByUser.xaml
new file mode 100644
index 0000000..8f0a0e4
--- /dev/null
+++ b/HMI.UI/RequirePasswordByUser.xaml
@@ -0,0 +1,33 @@
+锘�<pu:WindowX x:Class="HMI.Base.RequirePasswordByUser"
+ 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:HMI.Base"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil"
+ Loaded="WindowX_Loaded"
+ FontSize="14"
+ WindowStartupLocation="CenterOwner"
+ Height="200"
+ pu:WindowXModalDialog.OKButtonContent="纭畾"
+ Title="璇疯緭鍏ュ瘑鐮�" Width="500">
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <pu:FormGroup Header="褰撳墠鐢ㄦ埛" Orientation="Horizontal" Style="{StaticResource InputFormGroupStyle}">
+ <TextBlock Text="{Binding Username}"/>
+ </pu:FormGroup>
+ <pu:FormGroup Grid.Row="1" Header="瀵嗙爜" Orientation="Horizontal"
+ Style="{StaticResource RequiredInputFormGroupStyle}">
+ <PasswordBox x:Name="PwdPassword" VerticalContentAlignment="Center"
+ Style="{StaticResource SignInPasswordBoxStyle}"
+ pu:PasswordBoxHelper.Watermark="{DynamicResource App.Password}"/>
+ </pu:FormGroup>
+ </Grid>
+</pu:WindowX>
diff --git a/HMI.UI/RequirePasswordByUser.xaml.cs b/HMI.UI/RequirePasswordByUser.xaml.cs
new file mode 100644
index 0000000..598cad0
--- /dev/null
+++ b/HMI.UI/RequirePasswordByUser.xaml.cs
@@ -0,0 +1,62 @@
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using System.ComponentModel;
+
+namespace HMI.Base
+{
+ /// <summary>
+ /// RequirePasswordWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class RequirePasswordByUser : WindowX
+ {
+ public RequirePasswordByUser(string username)
+ {
+ this.Username = username;
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ private string username;
+ public string Username
+ {
+ get => username;
+ set
+ {
+ Set(ref username, value);
+ }
+ }
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ //Press Continue Button
+ if (DialogResult == true)
+ {
+ try
+ {
+ using (var helper = new Sqlite3Helper(PathHelper.DatabasePath))
+ {
+ if (!helper.HasData($"SELECT 1 FROM user WHERE username = '{Username}' AND password = '{PwdPassword.Password}';"))
+ {
+ ToastHelper.Error(this, "瀵嗙爜閿欒");
+ e.Cancel = true;
+ }
+ }
+ }
+ catch (System.Exception ex)
+ {
+ ToastHelper.Error(this, $"楠岃瘉鐢ㄦ埛淇℃伅澶辫触: {ex.Message}");
+ e.Cancel = true;
+ }
+ }
+ base.OnClosing(e);
+ }
+
+ private void WindowX_Loaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ Username = UserInfo.User.Username;
+ PwdPassword.Password = string.Empty;
+ }
+ }
+}
diff --git a/HMI.UI/RequirePasswordWindow.xaml b/HMI.UI/RequirePasswordWindow.xaml
index 89656c1..4cd14fa 100644
--- a/HMI.UI/RequirePasswordWindow.xaml
+++ b/HMI.UI/RequirePasswordWindow.xaml
@@ -11,6 +11,7 @@
Loaded="WindowX_Loaded"
FontSize="14"
Height="200"
+ WindowStartupLocation="CenterOwner"
pu:WindowXModalDialog.OKButtonContent="纭畾"
Title="璇疯緭鍏ュ瘑鐮�" Width="500">
<Grid dp:GridHelper.Space="10">
diff --git a/HMI.UI/Style/MsgBoxStyle.xaml b/HMI.UI/Style/MsgBoxStyle.xaml
index 1f577a1..39c0a68 100644
--- a/HMI.UI/Style/MsgBoxStyle.xaml
+++ b/HMI.UI/Style/MsgBoxStyle.xaml
@@ -3,11 +3,10 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:puconfig="clr-namespace:Panuon.WPF.UI.Configurations;assembly=Panuon.WPF.UI">
-
- <pu:MessageBoxXSettings x:Key="MsgBoxWarn"
- InteropOwnersMask="False"
- InverseButtonsSequence="False">
- <pu:MessageBoxXSettings.WindowXStyle>
+ <pu:MessageBoxXSetting x:Key="MsgBoxWarn"
+ InteropOwnersMask="False"
+ InverseButtonsSequence="False">
+ <pu:MessageBoxXSetting.WindowXStyle>
<Style TargetType="pu:WindowX" BasedOn="{StaticResource {x:Static pu:MessageBoxX.WindowXStyleKey}}">
<Setter Property="pu:WindowXCaption.Background" Value="{DynamicResource WarningColor}" />
<Setter Property="pu:WindowXCaption.Foreground" Value="{DynamicResource WarningColorContract}" />
@@ -15,9 +14,9 @@
<Setter Property="Height" Value="200" />
<Setter Property="SizeToContent" Value="Manual" />
</Style>
- </pu:MessageBoxXSettings.WindowXStyle>
+ </pu:MessageBoxXSetting.WindowXStyle>
- <pu:MessageBoxXSettings.ButtonStyle>
+ <pu:MessageBoxXSetting.ButtonStyle>
<Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:MessageBoxX.ButtonStyleKey}}">
<Style.Triggers>
@@ -33,20 +32,20 @@
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
- <TextBlock Text="{Binding}" TextDecorations="Underline" />
+ <TextBlock Text="{DynamicResource App.Cancel}" TextDecorations="Underline" />
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
- </pu:MessageBoxXSettings.ButtonStyle>
- </pu:MessageBoxXSettings>
+ </pu:MessageBoxXSetting.ButtonStyle>
+ </pu:MessageBoxXSetting>
- <pu:MessageBoxXSettings x:Key="MsgBoxError"
- InteropOwnersMask="False"
- InverseButtonsSequence="False">
- <pu:MessageBoxXSettings.WindowXStyle>
+ <pu:MessageBoxXSetting x:Key="MsgBoxError"
+ InteropOwnersMask="False"
+ InverseButtonsSequence="False">
+ <pu:MessageBoxXSetting.WindowXStyle>
<Style TargetType="pu:WindowX" BasedOn="{StaticResource {x:Static pu:MessageBoxX.WindowXStyleKey}}">
<Setter Property="pu:WindowXCaption.Background" Value="{DynamicResource DangerColor}" />
<Setter Property="pu:WindowXCaption.Foreground" Value="{DynamicResource DangerColorContrast}" />
@@ -54,9 +53,9 @@
<Setter Property="Height" Value="200" />
<Setter Property="SizeToContent" Value="Manual" />
</Style>
- </pu:MessageBoxXSettings.WindowXStyle>
+ </pu:MessageBoxXSetting.WindowXStyle>
- <pu:MessageBoxXSettings.ButtonStyle>
+ <pu:MessageBoxXSetting.ButtonStyle>
<Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:MessageBoxX.ButtonStyleKey}}">
<Style.Triggers>
@@ -72,20 +71,20 @@
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
- <TextBlock Text="{Binding}" TextDecorations="Underline" />
+ <TextBlock Text="{DynamicResource App.Cancel}" TextDecorations="Underline" />
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
- </pu:MessageBoxXSettings.ButtonStyle>
- </pu:MessageBoxXSettings>
+ </pu:MessageBoxXSetting.ButtonStyle>
+ </pu:MessageBoxXSetting>
- <pu:MessageBoxXSettings x:Key="MsgBoxInfo"
- InteropOwnersMask="False"
- InverseButtonsSequence="False">
- <pu:MessageBoxXSettings.WindowXStyle>
+ <pu:MessageBoxXSetting x:Key="MsgBoxInfo"
+ InteropOwnersMask="False"
+ InverseButtonsSequence="False">
+ <pu:MessageBoxXSetting.WindowXStyle>
<Style TargetType="pu:WindowX" BasedOn="{StaticResource {x:Static pu:MessageBoxX.WindowXStyleKey}}">
<Setter Property="pu:WindowXCaption.Background" Value="{DynamicResource PrimaryColor}" />
<Setter Property="pu:WindowXCaption.Foreground" Value="{DynamicResource PrimaryColorContract}" />
@@ -93,9 +92,9 @@
<Setter Property="Height" Value="200" />
<Setter Property="SizeToContent" Value="Manual" />
</Style>
- </pu:MessageBoxXSettings.WindowXStyle>
+ </pu:MessageBoxXSetting.WindowXStyle>
- <pu:MessageBoxXSettings.ButtonStyle>
+ <pu:MessageBoxXSetting.ButtonStyle>
<Style TargetType="Button" BasedOn="{StaticResource {x:Static pu:MessageBoxX.ButtonStyleKey}}">
<Style.Triggers>
@@ -111,15 +110,15 @@
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
- <TextBlock Text="{Binding}" TextDecorations="Underline" />
+ <TextBlock Text="{DynamicResource App.Cancel}" TextDecorations="Underline" />
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
- </pu:MessageBoxXSettings.ButtonStyle>
- </pu:MessageBoxXSettings>
+ </pu:MessageBoxXSetting.ButtonStyle>
+ </pu:MessageBoxXSetting>
<pu:ToastSetting x:Key="toastSuccess" Spacing="25">
<pu:ToastSetting.LabelStyle>
diff --git a/HMI.UI/Style/PanuonResource.xaml b/HMI.UI/Style/PanuonResource.xaml
index 9c5b052..bccebeb 100644
--- a/HMI.UI/Style/PanuonResource.xaml
+++ b/HMI.UI/Style/PanuonResource.xaml
@@ -225,6 +225,7 @@
<Setter Property="pu:WindowXModalDialog.OKButtonContent"
Value="{DynamicResource App.Save}"/>
<Setter Property="pu:WindowXModalDialog.ButtonPanelMargin" Value="0,30,10,10"/>
+ <Setter Property="InteropOwnersMask" Value="False"/>
</Style>
<Style x:Key="DefaultListBox" TargetType="ListBox" BasedOn="{StaticResource {x:Static pu:StyleKeys.ListBoxStyle}}">
@@ -319,4 +320,22 @@
</Setter.Value>
</Setter>
</Style>
+
+ <Style x:Key="DefaultPageItem" TargetType="pu:PaginationItem">
+ <Setter Property="Cursor" Value="Hand" />
+ <Setter Property="MinWidth" Value="30" />
+ <Setter Property="Width" Value="Auto" />
+ <Setter Property="Width" Value="Auto" />
+ </Style>
+
+ <Style x:Key="DefaultPage" TargetType="pu:Pagination">
+ <Setter Property="Height" Value="30"/>
+ <Setter Property="HorizontalAlignment" Value="Right"/>
+ <Setter Property="Foreground" Value="Black" />
+ <Setter Property="ItemsBackground" Value="Transparent"/>
+ <Setter Property="ItemsCornerRadius" Value="12"/>
+ <Setter Property="ItemsSelectedBackground" Value="{DynamicResource SecondPrimaryColor}"/>
+ <Setter Property="ItemContainerStyle" Value="{StaticResource DefaultPageItem}"/>
+ </Style>
+
</ResourceDictionary>
\ No newline at end of file
diff --git a/HMI.UnitTest/App.xaml b/HMI.UnitTest/App.xaml
index a3b7d0f..ad0c1c0 100644
--- a/HMI.UnitTest/App.xaml
+++ b/HMI.UnitTest/App.xaml
@@ -16,7 +16,7 @@
<ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
<ResourceDictionary Source="/HMI.UI;component/Style/MsgBoxStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
- <Style TargetType="{x:Type pu:FormGroup}" BasedOn="{StaticResource InputFormGroupStyle}"></Style>
+ <!--<Style TargetType="{x:Type pu:FormGroup}" BasedOn="{StaticResource InputFormGroupStyle}"></Style>-->
<uic:PathImageConverter x:Key="path2Image"/>
<uic:DataGridRowNumberConverter x:Key="rowNumber"/>
<uic:VisibilityBoolConverter x:Key="vbConverter"/>
diff --git a/HMI.UnitTest/HMI.UnitTest.csproj b/HMI.UnitTest/HMI.UnitTest.csproj
index 01946e0..148a599 100644
--- a/HMI.UnitTest/HMI.UnitTest.csproj
+++ b/HMI.UnitTest/HMI.UnitTest.csproj
@@ -131,6 +131,10 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\UILib\UILib.csproj">
+ <Project>{27325fe0-3ce2-4cd5-8eb5-7e45cc441479}</Project>
+ <Name>UILib</Name>
+ </ProjectReference>
<ProjectReference Include="..\ConnectionUtil\ConnectionUtil.csproj">
<Project>{d0806fa6-3f6d-4304-81b8-ead9da7cb5b2}</Project>
<Name>ConnectionUtil</Name>
@@ -167,10 +171,18 @@
<Project>{202d9a7b-96b3-4ad4-9977-fc4263207a02}</Project>
<Name>Plugin.TsExecution</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.UICollection\Plugin.UICollection.csproj">
+ <Project>{22dc8d91-50b2-47ca-86a8-29a6da48f388}</Project>
+ <Name>Plugin.UICollection</Name>
+ </ProjectReference>
<ProjectReference Include="..\SimpleUtil\HMI.Simple.Util\HMI.Simple.Util.csproj">
<Project>{cf5bebe9-2803-49c3-b773-73d082e0984a}</Project>
<Name>HMI.Simple.Util</Name>
</ProjectReference>
+ <ProjectReference Include="..\Util.ManualDebug\Util.ManualDebug.csproj">
+ <Project>{d0944e62-ee52-4abe-832a-a09d98814db1}</Project>
+ <Name>Util.ManualDebug</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Entity\" />
diff --git a/HMI.UnitTest/MainWindow.xaml b/HMI.UnitTest/MainWindow.xaml
index 801296c..adb3447 100644
--- a/HMI.UnitTest/MainWindow.xaml
+++ b/HMI.UnitTest/MainWindow.xaml
@@ -13,19 +13,15 @@
<Grid x:Name="page">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition/>
+ <RowDefinition />
</Grid.RowDefinitions>
<Button Click="Button_Click">娴嬭瘯</Button>
<!--<Button Click="Button_Click2" Grid.Row="1">鍙戦��</Button>
<Button Click="Button_Click3" Grid.Row="2">鍙戦�乀CP</Button>
<Button Click="Button_Click4" Grid.Row="4">鍙戦�丏ata</Button>-->
- <TextBox x:Name="input" Height="0" Grid.Row="3"></TextBox>
+ <!--<TextBox x:Name="input" Height="0" Grid.Row="3"></TextBox>
<TextBlock Grid.Row="5" Height="0" x:Name="console"></TextBlock>
- <Border Grid.Row="6" x:Name="border"></Border>
+ <Border Grid.Row="6" x:Name="border"></Border>-->
+ <Border Grid.Row="1" x:Name="border2"></Border>
</Grid>
</pu:WindowX>
diff --git a/HMI.UnitTest/MainWindow.xaml.cs b/HMI.UnitTest/MainWindow.xaml.cs
index 2c18c54..4dc0549 100644
--- a/HMI.UnitTest/MainWindow.xaml.cs
+++ b/HMI.UnitTest/MainWindow.xaml.cs
@@ -3,16 +3,15 @@
using HMI.Core.Util;
using HMI.Simple.Util;
using log4net;
-using ModBusTcp;
using Panuon.WPF.UI;
using Plugin.DataBoard;
using Plugin.TestResult_WPF;
using Plugin.TsExecution;
+using Plugin.UICollection;
using System;
using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
using System.Windows;
+using Util.ManualDebug;
namespace UnitTest
{
/// <summary>
@@ -27,22 +26,9 @@
LangUtil.Load();
InitializeComponent();
//RebuildDb();
+ border2.Child = new TcpDebugger();
- ModBusTcpController controller = new ModBusTcpController("127.0.0.1", 502);
- if (controller.Start(out msg)) {
- bool res;
- int? target;
-
- controller.WriteBool("1", true, out msg);
- controller.ReadDOBool("1", out res, out msg);
- Console.WriteLine(res);
- controller.ReadDOInt("1", out target, out msg);
- Console.WriteLine(target);
- controller.WriteInt("1", 1, out msg);
- controller.ReadDOInt("1", out target, out msg);
- Console.WriteLine(target);
- Console.WriteLine(target);
- }
+
//page.Children.Add(new UserControl1());
@@ -142,6 +128,12 @@
private void Button_Click(object sender, RoutedEventArgs e)
{
+ var win = new ManualDebug()
+ {
+ seqPath = "C:\\Users\\chrry\\Desktop\\鎵嬪姩璋冭瘯绀轰緥.seq"
+ };
+
+ win.Show();
//Task.Run(() =>
//{
// for (int j = 0; j < 1000; j++)
@@ -198,7 +190,7 @@
//});
//tsExecution.UpdatePositionStatus(0, "Passed");
- tsExecution.UpdatePositionStatus(0, "Failed");
+ //tsExecution.UpdatePositionStatus(0, "Failed");
//tsExecution.UpdatePositionProcessValue(0, 12);
//tsExecution.PausePosition(0);
//tsExecution.SetPositionBarcode(0, "123456789");
@@ -231,73 +223,6 @@
Console.WriteLine($"{e.Data}");
}
- private void Client_OnData(object sender, PipeDataEventArgs e)
- {
- Dispatcher.Invoke(() =>
- {
- console.Text += e.Data;
- });
- }
-
- private void Button_Click2(object sender, RoutedEventArgs e)
- {
- var allStart = DateTime.Now;
- for (int i = 0; i < 100; i++)
- {
- var start = DateTime.Now;
- if (client.SendMessage("ping", out string res))
- {
- var interval = (DateTime.Now - start).TotalMilliseconds;
- Console.WriteLine($"{interval}: {res}");
- }
- }
- Console.WriteLine($"Total: {(DateTime.Now - allStart).TotalMilliseconds}");
- }
-
- private void Button_Click3(object sender, RoutedEventArgs e)
- {
- try
- {
- var allStart = DateTime.Now;
- for (int i = 0; i < 500; i++)
- {
- var start = DateTime.Now;
- string data = input.Text;
- string str = $"{{\"command\":5,\"value\":{data},\"id\":\"DITag0\"}}\r\n";
- string res = tcpClient.SendMessage(str);
- var interval = (DateTime.Now - start).TotalMilliseconds;
- Console.WriteLine($"{interval}: {res}");
- }
- Console.WriteLine($"Total: {(DateTime.Now - allStart).TotalMilliseconds}");
- }
- catch (Exception ex)
- {
-
- }
- }
-
- private void Button_Click4(object sender, RoutedEventArgs e)
- {
- try
- {
- var allStart = DateTime.Now;
- for (int i = 0; i < 500; i++)
- {
- var start = DateTime.Now;
- string data = input.Text;
- string str = $"{{\"command\":5,\"value\":{data},\"id\":\"DITag0\"}}";
- client.SendMessage(str, out string res);
- var interval = (DateTime.Now - start).TotalMilliseconds;
- Console.WriteLine($"{interval}: {res}");
- }
- Console.WriteLine($"Total: {(DateTime.Now - allStart).TotalMilliseconds}");
-
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.StackTrace);
- }
- }
private void HandlePlugin(object obj)
{
@@ -318,10 +243,10 @@
private void Window_Loaded(object sender, RoutedEventArgs e)
{
- var plugin = new TsExecution();
- HandlePlugin(plugin);
- border.Child = plugin;
- tsExecution = plugin;
+ //var plugin = new TsExecution();
+ //HandlePlugin(plugin);
+ //border.Child = plugin;
+ //tsExecution = plugin;
this.Loaded -= Window_Loaded;
}
}
diff --git a/HMI.Util/Alarm/AlarmUtil.cs b/HMI.Util/Alarm/AlarmUtil.cs
index f846bd6..1044e1e 100644
--- a/HMI.Util/Alarm/AlarmUtil.cs
+++ b/HMI.Util/Alarm/AlarmUtil.cs
@@ -2,6 +2,7 @@
using HMI.Core.Entity;
using HMI.Core.Setting;
using HMI.Core.Util;
+using log4net;
using S7Driver;
using System;
using System.Collections.Generic;
@@ -18,8 +19,11 @@
public event EventHandler<LoadMsg> LoadMessageAppend;
+ private static ILog log = LogManager.GetLogger("AlarmHelper");
+
internal AlarmHelper()
{
+
}
public ObservableCollection<AlarmSetting> BlockSettings { get; private set; }
@@ -178,7 +182,7 @@
}
catch (Exception ex)
{
- //log.Error("Read OPCServer Data Error.", ex);
+ log.Error("Read PLC Alarm Data Error.", ex);
}
finally
{
@@ -279,7 +283,7 @@
}
catch (Exception ex)
{
- //log.Error("PcTimer Execute Failed", ex);
+ log.Error("Read MSMQ Alarm Data Failed", ex);
}
finally
{
diff --git a/HMI.Util/ExcelHelper.cs b/HMI.Util/ExcelHelper.cs
index 9e795dc..0708a5c 100644
--- a/HMI.Util/ExcelHelper.cs
+++ b/HMI.Util/ExcelHelper.cs
@@ -1,10 +1,12 @@
锘縰sing HMI.Core;
using HMI.Core.Util;
using NPOI.HSSF.UserModel;
+using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
+using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -55,6 +57,53 @@
}
}
+ public static void ExportExcel<T>(string targetPath, DataTable table)
+ {
+ Type type = typeof(T);
+ var properties = PropertyHelper.GetAtterProperty<T, ExcelColumnAttribute>(out var attrs);
+ if (properties == null || properties.Count <= 0)
+ {
+ throw new Exception("No Attribute");
+ }
+ IWorkbook workbook = null;
+ if (targetPath.EndsWith(".xlsx"))
+ {
+ workbook = new XSSFWorkbook();
+ }
+ else if (targetPath.EndsWith(".xls"))
+ {
+ workbook = new HSSFWorkbook();
+ }
+ workbook.CreateSheet("sheet1");////鏂板缓涓�涓伐浣滆〃
+ ISheet SheetOne = workbook.GetSheet("Sheet1");
+ IRow row1 = SheetOne.CreateRow(0);
+ for (int i = 0; i < properties.Count; i++)
+ {
+ row1.CreateCell(i).SetCellValue(LangUtil.Get((attrs[i]).Name));
+ }
+
+ for (int i = 0; i < table.Rows.Count; i++)
+ {
+ IRow rowTemp = SheetOne.CreateRow(i + 1);
+ for (int j = 0; j < properties.Count; j++)
+ {
+ var attr = attrs[j];
+ object obj = attr.IgnoreExport ? "" : table.Rows[i][properties[j].Name];
+ string value = obj?.ToString();
+ if (obj is DateTime time)
+ {
+ value = time.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ rowTemp.CreateCell(j).SetCellValue(value);
+ }
+ }
+
+ using (FileStream fs = new FileStream(targetPath, FileMode.OpenOrCreate))
+ {
+ workbook.Write(fs);
+ }
+ }
+
public static List<T> ReadFromExcel<T>(string sourcePath)
{
diff --git a/HMI.Util/HMI.Util.csproj b/HMI.Util/HMI.Util.csproj
index 7488068..fc1f1c8 100644
--- a/HMI.Util/HMI.Util.csproj
+++ b/HMI.Util/HMI.Util.csproj
@@ -52,6 +52,9 @@
<Reference Include="ICSharpCode.SharpZipLib, Version=1.0.0.999, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\WPFProject\packages\SharpZipLib.1.0.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
+ <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
+ </Reference>
<Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.dll</HintPath>
</Reference>
@@ -65,7 +68,9 @@
<HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.OpenXmlFormats.dll</HintPath>
</Reference>
<Reference Include="System" />
+ <Reference Include="System.Configuration" />
<Reference Include="System.Core" />
+ <Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
diff --git a/HMI.Util/IniFileHelper.cs b/HMI.Util/IniFileHelper.cs
index f6e7d4e..1c2959b 100644
--- a/HMI.Util/IniFileHelper.cs
+++ b/HMI.Util/IniFileHelper.cs
@@ -26,6 +26,9 @@
private static extern uint GetPrivateProfileStringA(string section, string key,
string def, Byte[] retVal, int size, string filePath);
+ [DllImport("kernel32")]
+ private static extern int GetPrivateProfileSection(string section, byte[] retVal, int size, string filePath);
+
#endregion
public static List<string> ReadSections()
{
@@ -108,5 +111,34 @@
return true;
}
#endregion
+
+ public static Dictionary<string, string> GetKeyValuesBySection(string iniFile, string section)
+ {
+ int size = 65536;
+ byte[] buffer = new byte[size];
+
+ Dictionary<string, string> result = new Dictionary<string, string>();
+ int bytesRead = GetPrivateProfileSection(section, buffer, size, iniFile);
+ if (bytesRead > 0)
+ {
+ string sectionData = Encoding.Default.GetString(buffer, 0, bytesRead - 1);
+ string[] keyValuePairs = sectionData.Split('\0');
+
+ foreach (string pair in keyValuePairs)
+ {
+ if (!string.IsNullOrEmpty(pair))
+ {
+ int equalSignIndex = pair.IndexOf('=');
+ if (equalSignIndex > 0)
+ {
+ string key = pair.Substring(0, equalSignIndex).Trim();
+ string value = pair.Substring(equalSignIndex + 1).Trim();
+ result[key] = value;
+ }
+ }
+ }
+ }
+ return result;
+ }
}
}
diff --git a/HMI.Util/packages.config b/HMI.Util/packages.config
index 5ed5cff..72b7273 100644
--- a/HMI.Util/packages.config
+++ b/HMI.Util/packages.config
@@ -1,5 +1,6 @@
锘�<?xml version="1.0" encoding="utf-8"?>
<packages>
+ <package id="log4net" version="3.0.4" targetFramework="net472" />
<package id="NPOI" version="2.4.1" targetFramework="net472" />
<package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
</packages>
\ No newline at end of file
diff --git a/OPCClient/OPCClient.csproj b/OPCClient/OPCClient.csproj
index 13f20fc..d7aa75b 100644
--- a/OPCClient/OPCClient.csproj
+++ b/OPCClient/OPCClient.csproj
@@ -73,7 +73,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
- <None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
diff --git a/OPCClient/app.config b/OPCClient/app.config
deleted file mode 100644
index a0cefc2..0000000
--- a/OPCClient/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/Plugin.CurrentSensorControl/BurnInOven.xaml.cs b/Plugin.CurrentSensorControl/BurnInOven.xaml.cs
index 72d9c5a..10b2b6c 100644
--- a/Plugin.CurrentSensorControl/BurnInOven.xaml.cs
+++ b/Plugin.CurrentSensorControl/BurnInOven.xaml.cs
@@ -14,7 +14,7 @@
{
private BaseConfig config;
- private static readonly string[] datas = new string[] { "_CoolerStatus", "_LEDLight", "_Req", "_SetTemp", "_SaveTemp", "_TempDown", "_TempUp", "_AvgTemp" };
+ private static readonly string[] datas = new string[] { "_LEDLight", "_Req", "_SetTemp", "_SaveTemp", "_TempDown", "_TempUp", "_AvgTemp" };
[ObservableProperty]
private string header;
diff --git a/Plugin.CurrentSensorControl/BurnInSettingModal.xaml.cs b/Plugin.CurrentSensorControl/BurnInSettingModal.xaml.cs
index 16abaa4..576146b 100644
--- a/Plugin.CurrentSensorControl/BurnInSettingModal.xaml.cs
+++ b/Plugin.CurrentSensorControl/BurnInSettingModal.xaml.cs
@@ -125,6 +125,14 @@
}
}
+ private void TryDeleteData(PLCTagData data)
+ {
+ if (MsgBoxHelper2.WarnChoose($"纭畾鍒犻櫎鏁版嵁: {data.Name} 鍚楋紵") == System.Windows.MessageBoxResult.OK)
+ {
+ Datasource.Remove(data);
+ }
+ }
+
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
var btn = sender as Button;
@@ -135,10 +143,12 @@
case "importBtn":
DoImport();
break;
+ case "delBtn":
+ TryDeleteData((PLCTagData)btn.DataContext);
+ break;
default:
break;
}
-
}
}
}
diff --git a/Plugin.DOControl/Plugin.DOControl.csproj b/Plugin.DOControl/Plugin.DOControl.csproj
index bbf2eb1..1637a2c 100644
--- a/Plugin.DOControl/Plugin.DOControl.csproj
+++ b/Plugin.DOControl/Plugin.DOControl.csproj
@@ -118,7 +118,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
diff --git a/Plugin.DOControl/app.config b/Plugin.DOControl/app.config
deleted file mode 100644
index a0cefc2..0000000
--- a/Plugin.DOControl/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/Plugin.DataViewer/AssemblyInfo.cs b/Plugin.DataViewer/AssemblyInfo.cs
new file mode 100644
index 0000000..8a284a8
--- /dev/null
+++ b/Plugin.DataViewer/AssemblyInfo.cs
@@ -0,0 +1,12 @@
+using HMI.Core.Annotation;
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+[assembly: PluginClassName("Plugin.DataViewer.DataViewerControl")]
diff --git a/Plugin.DataViewer/CustomSortColumn.cs b/Plugin.DataViewer/CustomSortColumn.cs
new file mode 100644
index 0000000..793d2f1
--- /dev/null
+++ b/Plugin.DataViewer/CustomSortColumn.cs
@@ -0,0 +1,108 @@
+锘縰sing System.ComponentModel;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace Plugin.DataViewer
+{
+ public class CustomSortColumnConverter : IValueConverter
+ {
+ public static CustomSortColumnConverter Instance = new CustomSortColumnConverter();
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value as ListSortDirection? == ListSortDirection.Ascending)
+ {
+ return true;
+ }
+
+ if (value as ListSortDirection? == ListSortDirection.Descending)
+ {
+ return false;
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+
+ public interface ICustomSortColumn
+ {
+ public bool? IsAsc { get; set; }
+
+ void UpdateOther(bool? value);
+ DataGrid GetOwner();
+ }
+
+ public class CustomSortTemplateColumn : DataGridTemplateColumn, ICustomSortColumn
+ {
+ public static DependencyProperty IsAscProperty = DependencyProperty.Register(
+ "IsAsc",
+ typeof(bool?),
+ typeof(DataGridTemplateColumn),
+ new FrameworkPropertyMetadata(null));
+
+ public bool? IsAsc
+ {
+ get => (bool?)GetValue(IsAscProperty);
+ set
+ {
+ SetValue(IsAscProperty, value);
+ }
+ }
+
+ public void UpdateOther(bool? value)
+ {
+ foreach (var col in DataGridOwner.Columns)
+ {
+ if (col == this) continue;
+ if (col is ICustomSortColumn csc)
+ {
+ csc.IsAsc = value;
+ }
+ }
+ }
+
+ public DataGrid GetOwner()
+ {
+ return this.DataGridOwner;
+ }
+ }
+
+ public class CustomSortTextColumn : DataGridTextColumn, ICustomSortColumn
+ {
+ public static DependencyProperty IsAscProperty = DependencyProperty.Register(
+ "IsAsc",
+ typeof(bool?),
+ typeof(DataGridTextColumn),
+ new FrameworkPropertyMetadata(null));
+
+ public bool? IsAsc
+ {
+ get => (bool?)GetValue(IsAscProperty);
+ set
+ {
+ SetValue(IsAscProperty, value);
+ }
+ }
+ public void UpdateOther(bool? value)
+ {
+ foreach (var col in DataGridOwner.Columns)
+ {
+ if (col == this) continue;
+ if (col is ICustomSortColumn csc)
+ {
+ csc.IsAsc = value;
+ }
+ }
+ }
+
+ public DataGrid GetOwner()
+ {
+ return this.DataGridOwner;
+ }
+ }
+}
diff --git a/Plugin.DataViewer/DataViewerControl.xaml b/Plugin.DataViewer/DataViewerControl.xaml
new file mode 100644
index 0000000..f25c54e
--- /dev/null
+++ b/Plugin.DataViewer/DataViewerControl.xaml
@@ -0,0 +1,480 @@
+锘�<hb:SimpleMaskControl x:Class="Plugin.DataViewer.DataViewerControl"
+ 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.DataViewer"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:sc="clr-namespace:System.ComponentModel;assembly=System"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <pu:StyleDictionary Includes="Label" />
+ </ResourceDictionary.MergedDictionaries>
+
+ <Style x:Key="SB" TargetType="DataGridColumnHeader">
+ <Setter Property="Foreground" Value="{DynamicResource PrimaryColorContract}"/>
+ <!--<Setter Property="Background" Value="{DynamicResource PrimaryColor}"/>
+ <Setter Property="Foreground" Value="{DynamicResource PrimaryColorContract}"/>
+ <Setter Property="BorderBrush" Value="{DynamicResource PrimaryColorContract}"/>
+ <Setter Property="BorderThickness" Value="0,0,1,1"/>-->
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="DataGridColumnHeader">
+ <Border BorderBrush="#FFF" Background="{DynamicResource PrimaryColor}"
+ MouseLeftButtonDown="Grid_MouseLeftButtonUp"
+ Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGridColumnHeader}}"
+ BorderThickness="0,0,1,1">
+ <Grid Margin="{TemplateBinding Padding}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Thumb x:Name="PART_LeftHeaderGripper" Grid.Column="0" HorizontalAlignment="Left"
+Width="1" BorderThickness="0" BorderBrush="Transparent"
+Cursor="SizeWE"/>
+ <ContentPresenter Grid.Column="0"
+ VerticalAlignment="Center"
+ Content="{Binding Column.Header,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGridColumnHeader}}"/>
+ <TextBlock VerticalAlignment="Center" Grid.Column="2" Text="" x:Name="sorter"> <!---->
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="FontFamily" Value="{StaticResource iconfont}"/>
+ <Setter Property="Visibility" Value="Collapsed"/>
+ <Style.Triggers>
+
+ <!--<DataTrigger Binding="{Binding Column.CustomSort,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGridColumnHeader}}" Value="{x:Null}">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ </DataTrigger>-->
+
+ <DataTrigger Binding="{Binding Column.IsAsc,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGridColumnHeader}}" Value="false">
+ <Setter Property="Visibility" Value="Visible"/>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding Column.IsAsc,
+ RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGridColumnHeader}}" Value="True">
+ <Setter Property="Visibility" Value="Visible"/>
+ <Setter Property="LayoutTransform">
+ <Setter.Value>
+ <RotateTransform Angle="180"/>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="3" HorizontalAlignment="Right" Width="1" BorderThickness="0"
+ BorderBrush="Transparent" Cursor="SizeWE"/>
+ </Grid>
+ </Border>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="ThisDataGridRow" TargetType="DataGridRow">
+ <Setter Property="Background" Value="White"/>
+ <Style.Triggers>
+ <Trigger Property="AlternationIndex" Value="1">
+ <Setter Property="Background" Value="#eeeeee"/>
+ </Trigger>
+ <DataTrigger Binding="{Binding result,Converter={x:Static uic:ResultConverter.Instance}}" Value="FAIL">
+ <Setter Property="Background" Value="{DynamicResource DangerColor}"/>
+ <Setter Property="Foreground" Value="{DynamicResource SecondPrimaryColorContract}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status,Converter={x:Static uic:ResultConverter.Instance}}" Value="FAIL">
+ <Setter Property="Background" Value="{DynamicResource DangerColor}"/>
+ <Setter Property="Foreground" Value="{DynamicResource SecondPrimaryColorContract}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="OutLabel" TargetType="Label">
+ <Setter Property="Height" Value="25"/>
+ <Setter Property="Padding" Value="0"/>
+ <Setter Property="VerticalAlignment" Value="Center"/>
+ <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
+ <Setter Property="VerticalContentAlignment" Value="Stretch"/>
+ <Setter Property="Background" Value="#ffffff"/>
+ <Setter Property="BorderThickness" Value="2"/>
+ <Setter Property="FontSize" Value="10"/>
+ <Setter Property="Foreground" Value="#000000"/>
+ </Style>
+
+ <Style x:Key="InLabel" TargetType="Label">
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="pu:LabelHelper.CornerRadius" Value="2,0,0,2"/>
+ </Style>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <Border Style="{StaticResource CardBoarder}">
+ <Grid>
+ <Grid dp:GridHelper.Space="10" dp:GridHelper.SpaceIgnore="ALL">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="4*"/>
+ <ColumnDefinition Width="6*"/>
+ </Grid.ColumnDefinitions>
+
+ <DockPanel Grid.ColumnSpan="2">
+ <!--<StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+ <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource EditBtn}" x:Name="editBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource RfhBtn}" x:Name="rfhBtn" Click="Button_Click"/>
+ <Button Style="{StaticResource DelBtn}" x:Name="delBtn" Click="Button_Click"/>
+ </StackPanel>-->
+ <TextBlock Style="{StaticResource TitleBox}" Text="{DynamicResource Dv.Title}"/>
+ </DockPanel>
+
+ <!--<Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+ </Grid>-->
+ <StackPanel Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Left" Style="{StaticResource ButtonGroup}">
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}"
+ Text="SN"/>
+ <pu:SearchBox x:Name="snInput" Tag="sn" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}"
+ Text="绌翠綅鍙�"/>
+ <pu:SearchBox x:Name="positionInput" Tag="position" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="鍨嬪彿"/>
+ <pu:SearchBox x:Name="modelInput" Tag="model" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="缁撴灉"/>
+ <pu:SearchBox x:Name="resultInput" Tag="result" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}"
+ Text="{DynamicResource App.StartTime}"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}"
+ SelectedDateTime="{x:Null}" x:Name="startTimeInput"/>
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}"
+ Text="{DynamicResource App.EndTime}"/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}"
+ SelectedDateTime="{x:Null}" x:Name="endTimeInput"/>
+
+ <Button Style="{StaticResource QueryBtn}"
+ x:Name="srhBtn" Click="Button_Click"/>
+
+ <Button Style="{StaticResource ResetBtn}"
+ x:Name="resetBtn" Click="Button_Click"/>
+ </StackPanel>
+
+ <Grid Grid.Row="2" Grid.Column="0" dp:GridHelper.Space="5" dp:GridHelper.SpaceIgnore="ALL">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+
+ <DockPanel>
+ <Button DockPanel.Dock="Right" Style="{StaticResource ExportBtn}"
+x:Name="exportBtn" Click="Button_Click"/>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+
+ <Label
+Height="25"
+Padding="0"
+HorizontalContentAlignment="Stretch"
+VerticalContentAlignment="Stretch"
+pu:LabelHelper.CornerRadius="2"
+Background="#ffffff"
+BorderBrush="{DynamicResource PrimaryColor}"
+BorderThickness="2"
+FontSize="10"
+FontWeight="Bold"
+Foreground="#000000">
+ <DockPanel Margin="-1" MinWidth="80">
+ <Label VerticalContentAlignment="Center" BorderThickness="0" Content="ALL" Foreground="{DynamicResource PrimaryColorContract}"
+ pu:LabelHelper.CornerRadius="2,0,0,2" DockPanel.Dock="Left" Background="{DynamicResource PrimaryColor}" />
+ <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="Black">
+ <Run Text="{Binding TotalCount}"/>
+ </TextBlock>
+ </DockPanel>
+ </Label>
+
+ <Label
+Height="25"
+Padding="0"
+HorizontalContentAlignment="Stretch"
+VerticalContentAlignment="Stretch"
+pu:LabelHelper.CornerRadius="2"
+Background="#ffffff"
+BorderBrush="{DynamicResource SuccessColor}"
+BorderThickness="2"
+FontSize="10"
+FontWeight="Bold"
+Foreground="#000000">
+ <DockPanel Margin="-1" MinWidth="80">
+ <Label VerticalContentAlignment="Center" BorderThickness="0" Content="PASS" Foreground="{DynamicResource SuccessColorContrast}"
+ pu:LabelHelper.CornerRadius="2,0,0,2" DockPanel.Dock="Left" Background="{DynamicResource SuccessColor}"/>
+ <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="Black">
+<Run Text="{Binding PassCount}"/>
+ </TextBlock>
+ </DockPanel>
+ </Label>
+
+ <Label
+Height="25"
+Padding="0"
+HorizontalContentAlignment="Stretch"
+VerticalContentAlignment="Stretch"
+pu:LabelHelper.CornerRadius="2"
+Background="#ffffff"
+BorderBrush="{DynamicResource DangerColor}"
+BorderThickness="2"
+FontSize="10"
+ FontWeight="Bold"
+Foreground="#000000">
+ <DockPanel Margin="-1" MinWidth="80">
+ <Label VerticalContentAlignment="Center" BorderThickness="0" Content="FAIL" Foreground="{DynamicResource DangerColorContrast}"
+ pu:LabelHelper.CornerRadius="2,0,0,2" DockPanel.Dock="Left" Background="{DynamicResource DangerColor}" />
+ <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="Black">
+<Run Text="{Binding FailCount}"/>
+ </TextBlock>
+ </DockPanel>
+ </Label>
+
+ </StackPanel>
+
+ </DockPanel>
+
+
+
+ <DataGrid Grid.Row="1" CanUserSortColumns="False"
+ AutoGenerateColumns="False" x:Name="resultTable"
+ RowStyle="{StaticResource ThisDataGridRow}"
+ Style="{StaticResource DefaultDataGrid}"
+ ColumnHeaderStyle="{StaticResource SB}"
+ VirtualizingStackPanel.CacheLength="10"
+ SelectedItem="{Binding SelectedResult}"
+ MouseDoubleClick="resultTable_MouseDoubleClick"
+ ColumnHeaderHeight="30">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" IsReadOnly="True" Width="Auto">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="*" Binding="{Binding sn}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="SN"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding position}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="绌翠綅鍙�"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding model}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="鍨嬪彿"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding result}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="娴嬭瘯缁撴灉"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="160" Binding="{Binding time,Converter={x:Static uic:DateStrConverter.Instance}}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="娴嬭瘯鏃堕棿"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ </DataGrid.Columns>
+ </DataGrid>
+
+ <pu:Pagination Grid.Row="2" Height="30" Margin="10" HorizontalAlignment="Right" Foreground="Black"
+ItemsBackground="Transparent"
+ItemsCornerRadius="12"
+ItemsSelectedBackground="{DynamicResource SecondPrimaryColor}"
+ x:Name="page" CurrentPageChanged="page_CurrentPageChanged"
+ CurrentPage="{Binding CurrentPage}"
+ MaxPage="{Binding TotalPage}">
+ <pu:Pagination.ItemContainerStyle>
+ <Style TargetType="pu:PaginationItem">
+ <Setter Property="MinWidth" Value="30" />
+ <Setter Property="Width" Value="Auto" />
+ <Setter Property="Width" Value="Auto" />
+ </Style>
+ </pu:Pagination.ItemContainerStyle>
+ </pu:Pagination>
+ </Grid>
+
+
+ <Grid Grid.Row="2" Grid.Column="1" dp:GridHelper.Space="5" dp:GridHelper.SpaceIgnore="ALL">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+
+ <DockPanel>
+ <Button DockPanel.Dock="Right" Style="{StaticResource ExportBtn}"
+x:Name="exportItemBtn" Click="Button_Click"/>
+ <Button DockPanel.Dock="Right" Margin="0,0,10,0" Style="{StaticResource QueryBtn}"
+x:Name="srhItemBtn" Click="Button_Click"/>
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Label>
+ <DockPanel Margin="-1" MinWidth="80" >
+ <Label VerticalContentAlignment="Center" BorderThickness="0" Content="娴嬭瘯缁撴灉" Foreground="{DynamicResource SuccessColorContrast}"
+ pu:LabelHelper.CornerRadius="2,0,0,2" DockPanel.Dock="Left" Background="Transparent"/>
+ <TextBlock VerticalAlignment="Center" Padding="0,0,5,0"
+ HorizontalAlignment="Center" FontSize="14" Foreground="{DynamicResource SuccessColorContrast}">
+<Run Text="{Binding SelectedStatus,Converter={x:Static uic:ResultConverter.Instance}}"/>
+ </TextBlock>
+ </DockPanel>
+
+ <Label.Style>
+ <Style TargetType="Label" BasedOn="{StaticResource {x:Static pu:StyleKeys.LabelStyle}}">
+ <Setter Property="pu:LabelHelper.CornerRadius" Value="2"/>
+ <Setter Property="Background" Value="{DynamicResource SuccessColor}"/>
+ <Setter Property="BorderBrush" Value="{DynamicResource SuccessColor}"/>
+ <Setter Property="Height" Value="25"/>
+ <Setter Property="Padding" Value="0"/>
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="BorderThickness" Value="2"/>
+ <Setter Property="FontSize" Value="10"/>
+ <Setter Property="FontWeight" Value="Bold"/>
+ <Setter Property="Foreground" Value="Black"/>
+
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedStatus}" Value="{x:Null}">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding SelectedStatus,Converter={x:Static uic:ResultConverter.Instance}}" Value="FAIL">
+ <Setter Property="Background" Value="{DynamicResource DangerColor}"/>
+ <Setter Property="BorderBrush" Value="{DynamicResource DangerColor}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="娴嬭瘯椤�"/>
+ <pu:SearchBox x:Name="stepInput" Tag="step" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+
+ <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="缁撴灉"/>
+ <pu:SearchBox x:Name="statusInput" Tag="status" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+
+ </StackPanel>
+ </DockPanel>
+
+ <DataGrid Grid.Row="1" x:Name="testItemTable" ColumnHeaderHeight="30"
+ ColumnHeaderStyle="{StaticResource SB}"
+ RowStyle="{StaticResource ThisDataGridRow}"
+ Style="{StaticResource DefaultDataGrid}">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" IsReadOnly="True" 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>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="Auto" Binding="{Binding sn}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="SN"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="*" Binding="{Binding step}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="娴嬭瘯椤�"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="*" Binding="{Binding value}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="娴嬭瘯鍊�"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding limitDown}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="涓嬮檺"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding limitUp}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="涓婇檺"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding unit}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="鍗曚綅"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="80" Binding="{Binding status}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="缁撴灉"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ <local:CustomSortTextColumn IsReadOnly="True" Width="160" Binding="{Binding time,Converter={x:Static uic:DateStrConverter.Instance}}">
+ <local:CustomSortTextColumn.Header>
+ <TextBlock Text="娴嬭瘯鏃堕棿"/>
+ </local:CustomSortTextColumn.Header>
+ </local:CustomSortTextColumn>
+
+ </DataGrid.Columns>
+ </DataGrid>
+
+ <pu:Pagination Grid.Row="2" Height="30" HorizontalAlignment="Right" Foreground="Black" ItemsBackground="Transparent"
+ItemsCornerRadius="12"
+ItemsSelectedBackground="{DynamicResource SecondPrimaryColor}"
+ x:Name="itemPage" CurrentPageChanged="page_CurrentPageChanged"
+ CurrentPage="{Binding TestItemPage}"
+ MaxPage="{Binding TestItemTotalPage}">
+ <pu:Pagination.ItemContainerStyle>
+ <Style TargetType="pu:PaginationItem">
+ <Setter Property="MinWidth" Value="30" />
+ <Setter Property="Cursor" Value="Hand" />
+ <Setter Property="Width" Value="Auto" />
+ </Style>
+ </pu:Pagination.ItemContainerStyle>
+ </pu:Pagination>
+ </Grid>
+ <ui:MaskControl Grid.Row="2" Grid.Column="1" x:Name="mask2"/>
+ </Grid>
+ <ui:MaskControl x:Name="topMask"/>
+ </Grid>
+ </Border>
+</hb:SimpleMaskControl>
diff --git a/Plugin.DataViewer/DataViewerControl.xaml.cs b/Plugin.DataViewer/DataViewerControl.xaml.cs
new file mode 100644
index 0000000..372bba9
--- /dev/null
+++ b/Plugin.DataViewer/DataViewerControl.xaml.cs
@@ -0,0 +1,800 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using HMI.Base;
+using HMI.Core;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using HMI.Util;
+using Microsoft.Win32;
+using Panuon.WPF.UI;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Data;
+using System.IO;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+
+namespace Plugin.DataViewer
+{
+ public class TestResult
+ {
+ [ExcelColumn("SN")]
+ public string sn { get; set; }
+
+ [ExcelColumn("绌翠綅鍙�")]
+ public string position { get; set; }
+
+ [ExcelColumn("鍨嬪彿")]
+ public string model { get; set; }
+
+ [ExcelColumn("娴嬭瘯缁撴灉")]
+ public string result { get; set; }
+
+ [ExcelColumn("娴嬭瘯鏃堕棿")]
+ public string time { get; set; }
+ }
+
+ public class SerialData
+ {
+ [ExcelColumn("SN")]
+ public string sn { get; set; }
+
+ [ExcelColumn("绌翠綅鍙�")]
+ public string position { get; set; }
+
+ [ExcelColumn("鍨嬪彿")]
+ public string model { get; set; }
+
+ [ExcelColumn("娴嬭瘯椤�")]
+ public string step { get; set; }
+
+ [ExcelColumn("娴嬭瘯鍊�")]
+ public string value { get; set; }
+
+ [ExcelColumn("涓嬮檺")]
+ public string limitDown { get; set; }
+
+ [ExcelColumn("涓婇檺")]
+ public string limitUp { get; set; }
+ [ExcelColumn("缁撴灉")]
+ public string status { get; set; }
+
+ [ExcelColumn("鍗曚綅")]
+ public string unit { get; set; }
+
+ [ExcelColumn("娴嬭瘯鏃堕棿")]
+ public string time { get; set; }
+ }
+
+ public class SortParam
+ {
+ public string name { get; set; }
+ public ListSortDirection direction { get; set; }
+ public string sort { get; set; }
+ }
+
+ public class ResultData
+ {
+ public string sn { get; set; }
+ public string position { get; set; }
+ }
+
+ /// <summary>
+ /// DataViewerControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class DataViewerControl : SimpleMaskControl
+ {
+ [ObservableProperty]
+ private DataView resultView;
+
+ [ObservableProperty]
+ private ObservableCollection<ResultData> resultData;
+
+ [ObservableProperty]
+ private long currentPage = 1;
+
+ [ObservableProperty]
+ private long totalPage = 0;
+
+ private int pageSize = 30;
+
+ [ObservableProperty]
+ private long totalCount;
+
+ [ObservableProperty]
+ private long passCount;
+
+ [ObservableProperty]
+ private long failCount;
+
+ [ObservableProperty]
+ private long testItemPage = 1;
+
+ [ObservableProperty]
+ private long testItemTotalPage = 0;
+
+ [ObservableProperty]
+ private object selectedResult;
+
+ [ObservableProperty]
+ private string selectedStatus;
+
+ private SortParam sorter;
+ private SortParam itemSorter;
+ public DataViewerControl()
+ {
+ DataContext = this;
+ InitializeComponent();
+ Reset();
+ }
+
+ private string[] GetFiles(DateTime? startTime, DateTime? endTime)
+ {
+ string dir = ParamSetting.DataLogFolder;
+ string startName = $"Data_{startTime?.ToString("yyyyMMdd")}";
+ string endName = $"Data_{endTime?.ToString("yyyyMMdd")}";
+ var oldFiles = Directory.GetFiles(dir, "Data_*.db");
+ oldFiles = oldFiles.Where(file =>
+ {
+ var fileName = Path.GetFileNameWithoutExtension(file);
+ bool flag = true;
+ flag &= (string.Compare(fileName, startName) == 1 || fileName == startName);
+ flag &= (string.Compare(endName, fileName) == 1 || fileName == endName);
+ return flag;
+ }).ToArray();
+ return oldFiles;
+ }
+
+ private void Reset()
+ {
+ var today = DateTime.Now;
+ var startTime = today.AddDays(-7);
+ var end = today.AddDays(1);
+
+ snInput.Text = string.Empty;
+ positionInput.Text = string.Empty;
+ modelInput.Text = string.Empty;
+ resultInput.Text = string.Empty;
+
+ startTimeInput.SelectedDateTime = DateTime.Parse(startTime.ToString("yyyy-MM-dd 00:00:00"));
+ endTimeInput.SelectedDateTime = DateTime.Parse(end.ToString("yyyy-MM-dd 00:00:00"));
+ }
+
+ private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
+ {
+ var btn = sender as Button;
+ if (btn.Name == "resetBtn")
+ {
+ Reset();
+ if (CurrentPage == 1)
+ {
+ SelectPage(1, this.pageSize);
+ }
+ else
+ {
+ CurrentPage = 1;
+ }
+ return;
+ }
+ if (btn.Name == "srhBtn")
+ {
+ if (CurrentPage == 1)
+ {
+ SelectPage(1, this.pageSize);
+ }
+ else
+ {
+ CurrentPage = 1;
+ }
+ return;
+ }
+
+ if (btn.Name == "srhItemBtn")
+ {
+ if (TestItemPage == 1)
+ {
+ RefreshTestItem(this.selectResultId, 1, this.pageSize);
+ }
+ else
+ {
+ TestItemPage = 1;
+ }
+ return;
+ }
+
+ if (btn.Name == "exportBtn")
+ {
+ TryExport();
+ }
+
+ if (btn.Name == "exportItemBtn")
+ {
+ TryExportItem();
+ }
+ }
+
+ private void TryExport()
+ {
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ Filter = "Excel 鏂囦欢 (*.xls)|*.xls"
+ };
+ if (sfd.ShowDialog() != true)
+ {
+ return;
+ }
+ string filePath = sfd.FileName;
+
+ DateTime? startTime = startTimeInput.SelectedDateTime, endTime = endTimeInput.SelectedDateTime;
+
+ topMask.ShowMask(this, () =>
+ {
+ var table = SelectResult(startTime, endTime);
+
+ ExcelHelper.ExportExcel<TestResult>(filePath, table);
+
+ }, (ex) =>
+ {
+ log.Error("Export Result Failed.", ex);
+ Dispatcher.Invoke(() =>
+ {
+ MsgBoxHelper2.Error($"瀵煎嚭澶辫触锛亄ex.Message}");
+ });
+ }, "瀵煎嚭涓�,璇风◢鍚�...");
+ }
+
+ private void TryExportItem()
+ {
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ Filter = "Excel 鏂囦欢 (*.xls)|*.xls"
+ };
+ if (sfd.ShowDialog() != true)
+ {
+ return;
+ }
+ string filePath = sfd.FileName;
+
+ DateTime? startTime = startTimeInput.SelectedDateTime, endTime = endTimeInput.SelectedDateTime;
+
+ topMask.ShowMask(this, () =>
+ {
+ var table = SelectItem(startTime, endTime);
+
+ ExcelHelper.ExportExcel<SerialData>(filePath, table);
+
+ }, (ex) =>
+ {
+ log.Error("Export Result Failed.", ex);
+ Dispatcher.Invoke(() =>
+ {
+ MsgBoxHelper2.Error($"瀵煎嚭澶辫触锛亄ex.Message}");
+ });
+ }, "瀵煎嚭涓�,璇风◢鍚�...");
+ }
+
+ private DataTable SelectResult(DateTime? startTime, DateTime? endTime)
+ {
+ var files = GetFiles(startTime, endTime);
+ if (files == null || files.Length <= 0)
+ {
+ return new DataTable();
+ }
+ using (var helper = new Sqlite3Helper(files[0]))
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ }
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (!helper.HasData($"SELECT 1 FROM pragma_table_info('testResult','db{i}') WHERE name = 'resultId';"))
+ {
+ helper.Execute($"ALTER TABLE db{i}.testResult ADD resultId TEXT;");
+ }
+ }
+
+ string sql = string.Join(" UNION ALL ", GetResultSqlsByFiles(files, startTime, endTime));
+ string sortName = "time", sortDirection = "DESC";
+ string baseSql = $"SELECT id,sn,model,station,position,result,time,resultId FROM ({sql}) as _temp";
+
+
+
+ sql = $"{baseSql} ORDER BY {sortName} {sortDirection}";
+
+ return helper.GetDataTable(sql);
+
+ //for (int i = 0; i < files.Length; i++)
+ //{
+ // helper.Execute($"DETACH DATABASE db{i}");
+ //}
+ }
+ }
+
+ private DataTable SelectItem(DateTime? startTime, DateTime? endTime)
+ {
+ if (string.IsNullOrEmpty(this.selectResultId))
+ {
+ return new DataTable();
+ }
+ var files = GetFiles(startTime, endTime);
+ if (files == null || files.Length <= 0)
+ {
+ return new DataTable();
+ }
+ using (var helper = new Sqlite3Helper(files[0]))
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ }
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (!helper.HasData($"SELECT 1 FROM pragma_table_info('serialData','db{i}') WHERE name = 'resultId';"))
+ {
+ helper.Execute($"ALTER TABLE db{i}.serialData ADD resultId TEXT;");
+ }
+ }
+
+ string sql = string.Join(" UNION ALL ", GetTestItemSqlsByFiles(this.selectResultId, files));
+
+ string sortName = "time", sortDirection = "DESC";
+
+ string baseSql = $"SELECT sn, position, model,step, limitDown, limitUp,unit, value,status,time FROM ({sql}) as _temp";
+
+ sql = $"{baseSql} ORDER BY {sortName} {sortDirection}";
+
+ return helper.GetDataTable(sql);
+
+
+ //for (int i = 0; i < files.Length; i++)
+ //{
+ // helper.Execute($"DETACH DATABASE db{i}");
+ //}
+ }
+ }
+
+ private void SelectPage(long page, long pageSize)
+ {
+ try
+ {
+ var files = GetFiles(startTimeInput.SelectedDateTime, endTimeInput.SelectedDateTime);
+ if (files == null || files.Length <= 0)
+ {
+ return;
+ }
+ using (var helper = new Sqlite3Helper(files[0]))
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ }
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (!helper.HasData($"SELECT 1 FROM pragma_table_info('testResult','db{i}') WHERE name = 'resultId';"))
+ {
+ helper.Execute($"ALTER TABLE db{i}.testResult ADD resultId TEXT;");
+ }
+ }
+
+ string sql = string.Join(" UNION ALL ", GetResultSqlsByFiles(files, startTimeInput.SelectedDateTime, endTimeInput.SelectedDateTime));
+ string sortName = "time", sortDirection = "DESC";
+
+ if (sorter != null)
+ {
+ sortName = sorter.name;
+ sortDirection = sorter.sort;
+ }
+ string countSql = $"SELECT COUNT(1) FROM ({sql}) as _temp";
+ long total = (long)helper.SelectOne(countSql);
+
+ string baseSql = $"SELECT id,sn,model,station,position,result,time,resultId FROM ({sql}) as _temp";
+
+
+
+ sql = $"{baseSql} ORDER BY {sortName} {sortDirection} LIMIT {pageSize} OFFSET {(page - 1) * pageSize}";
+
+ var dt = helper.GetDataTable(sql);
+
+ TotalPage = total / pageSize + (total % pageSize > 0 ? 1 : 0);
+ resultTable.ItemsSource = dt.DefaultView;
+
+ sql = $"SELECT result,COUNT(1) as num FROM ({baseSql}) GROUP BY result";
+ var nums = helper.GetDataTable(sql);
+
+ long all = 0, pass = 0, fail = 0;
+ foreach (DataRow row in nums.Rows)
+ {
+ if ("ok".Equals(row["result"].ToString(), StringComparison.OrdinalIgnoreCase)
+ || "pass".Equals(row["result"].ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ pass += (long)row["num"];
+ all += (long)row["num"];
+ }
+ if ("ng".Equals(row["result"].ToString(), StringComparison.OrdinalIgnoreCase)
+ || "fail".Equals(row["result"].ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ fail += (long)row["num"];
+ all += (long)row["num"];
+ }
+ }
+
+ TotalCount = all;
+ PassCount = pass;
+ FailCount = fail;
+
+ //for (int i = 0; i < files.Length; i++)
+ //{
+ // helper.Execute($"DETACH DATABASE db{i}");
+ //}
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Select TestResult Error.", ex);
+
+ }
+ }
+
+ private void RefreshTestItem(string resultId, long page, int pageSize)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(resultId))
+ {
+ testItemTable.ItemsSource = new DataTable().DefaultView;
+ return;
+ }
+
+ var files = GetFiles(startTimeInput.SelectedDateTime, endTimeInput.SelectedDateTime);
+ if (files == null || files.Length <= 0)
+ {
+ return;
+ }
+
+ string sql = string.Join(" UNION ALL ", GetTestItemSqlsByFiles(resultId, files));
+ string sortName = "time", sortDirection = "DESC";
+ if (itemSorter != null)
+ {
+ sortName = itemSorter.name;
+ sortDirection = itemSorter.sort;
+ }
+
+ mask2.ShowMask(null, () =>
+ {
+ using (var helper = new Sqlite3Helper(files[0]))
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ }
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (!helper.HasData($"SELECT 1 FROM pragma_table_info('serialData','db{i}') WHERE name = 'resultId';"))
+ {
+ helper.Execute($"ALTER TABLE db{i}.serialData ADD resultId TEXT;");
+ }
+ }
+
+
+ string countSql = $"SELECT COUNT(1) FROM ({sql}) as _temp";
+ long total = (long)helper.SelectOne(countSql);
+
+ string baseSql = $"SELECT sn, model,step, limitDown, limitUp,unit, value,status,time FROM ({sql}) as _temp";
+
+ sql = $"{baseSql} ORDER BY {sortName} {sortDirection} LIMIT {pageSize} OFFSET {(page - 1) * pageSize}";
+
+ var dt = helper.GetDataTable(sql);
+
+
+ //for (int i = 0; i < files.Length; i++)
+ //{
+ // helper.Execute($"DETACH DATABASE db{i}");
+ //}
+
+ Dispatcher.BeginInvoke(() =>
+ {
+ TestItemTotalPage = total / pageSize + (total % pageSize > 0 ? 1 : 0);
+ testItemTable.ItemsSource = dt.DefaultView;
+ }, System.Windows.Threading.DispatcherPriority.Normal);
+ }
+ }, (ex) =>
+ {
+ log.Error("Select TestItem Error.", ex);
+ },
+ "鏌ヨ涓�...");
+ }
+ catch (Exception ex)
+ {
+ log.Error("Try Select TestItem Error.", ex);
+ }
+ }
+
+ public string[] GetResultSqlsByFiles(string[] files, DateTime? startTime, DateTime? endTime)
+ {
+ string sn = string.Empty, position = string.Empty, model = string.Empty, result = string.Empty;
+ Dispatcher.Invoke(() =>
+ {
+ sn = snInput.Text;
+ position = positionInput.Text;
+ model = modelInput.Text;
+ result = resultInput.Text;
+ });
+
+ string[] sqls = new string[files.Length];
+ List<string> querys = new List<string>();
+ if (!string.IsNullOrEmpty(sn))
+ {
+ querys.Add($"sn = '{sn}'");
+ }
+
+ if (!string.IsNullOrEmpty(position))
+ {
+ querys.Add($"position = '{position}'");
+ }
+
+ if (!string.IsNullOrEmpty(model))
+ {
+ querys.Add($"model = '{model}'");
+ }
+
+ if (!string.IsNullOrEmpty(result))
+ {
+ querys.Add($"result = '{result}'");
+ }
+
+ if (startTime != null)
+ {
+ querys.Add($"time >= '{startTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}'");
+ }
+
+ if (endTime != null)
+ {
+ querys.Add($"time < '{endTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}'");
+ }
+
+ string segment = "";
+ if (querys.Count > 0)
+ {
+ segment = $" WHERE {string.Join(" AND ", querys)}";
+ }
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ sqls[i] = $"SELECT id,sn,model,station,position,result,time,resultId FROM db{i}.testResult {segment}";
+ }
+ return sqls;
+ }
+
+ private string[] GetTestItemSqlsByFiles(string resultId, string[] files)
+ {
+ List<string> querys = new List<string>() {
+ $"resultId = '{resultId}'"
+ };
+ string step = string.Empty, status = string.Empty;
+ Dispatcher.Invoke(() =>
+ {
+ step = stepInput.Text;
+ status = statusInput.Text;
+ });
+
+
+ if (!string.IsNullOrEmpty(step))
+ {
+ querys.Add($"step = '{step}'");
+ }
+
+ if (!string.IsNullOrEmpty(status))
+ {
+ querys.Add($"status = '{status}'");
+ }
+
+ string segment = string.Join(" AND ", querys); ;
+
+ string[] sqls = new string[files.Length];
+ for (int i = 0; i < files.Length; i++)
+ {
+ sqls[i] = $"SELECT sn, position, model,step, limitDown, limitUp,unit, value,status,time FROM db{i}.serialData WHERE {segment}";
+ }
+ return sqls;
+ }
+
+ public string[] GetSource(string[] files, string name, string tableName, string value)
+ {
+ try
+ {
+ if (files == null || files.Length <= 0)
+ {
+ return new string[0];
+ }
+ string[] GetModelSqls()
+ {
+ string[] sqls = new string[files.Length];
+ for (int i = 0; i < files.Length; i++)
+ {
+ sqls[i] = $"SELECT DISTINCT {name} FROM db{i}.{tableName} WHERE {name} LIKE '%{value}%'";
+ }
+ return sqls;
+ }
+
+ using (var helper = new Sqlite3Helper(files[0]))
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ }
+ string sql = string.Join(" UNION ", GetModelSqls());
+ sql = $"SELECT DISTINCT {name} FROM ({sql}) LIMIT 10";
+
+ var dt = helper.GetDataTable(sql);
+ return dt.Select().Select(row => row[name].ToString()).ToArray();
+ }
+ return new string[0];
+ }
+ catch (Exception ex)
+ {
+ return new string[0];
+ }
+ }
+
+
+ private void SearchTextChanged(object sender, Panuon.WPF.SearchTextChangedRoutedEventArgs e)
+ {
+ SearchBox sb = sender as SearchBox;
+ string tag = sb.Tag.ToString(), value = sb.Text;
+ var files = GetFiles(startTimeInput.SelectedDateTime, endTimeInput.SelectedDateTime);
+ Task.Run(() =>
+ {
+ string[] items = new string[0];
+ if (tag == "step" || tag == "status")
+ {
+ items = GetSource(files, tag, "serialData", value);
+ }
+ else
+ {
+ items = GetSource(files, tag, "testResult", value);
+ }
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ sb.ItemsSource = items;
+ }), System.Windows.Threading.DispatcherPriority.Normal);
+ });
+ }
+
+ private void Grid_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ var border = sender as Border;
+ var header = border.Tag as DataGridColumnHeader;
+ var col = header.Column as ICustomSortColumn;
+
+ if (col == null) return;
+
+ col.UpdateOther(null);
+
+ var dataGrid = col.GetOwner();
+
+ if (col.IsAsc == null)
+ {
+ col.IsAsc = true;
+
+ if (dataGrid == resultTable)
+ {
+ sorter = new SortParam { name = header.Column.SortMemberPath, direction = ListSortDirection.Ascending, sort = "ASC" };
+ }
+ else {
+ itemSorter = new SortParam { name = header.Column.SortMemberPath, direction = ListSortDirection.Ascending, sort = "ASC" };
+ }
+
+ }
+ else if (col.IsAsc == true)
+ {
+ col.IsAsc = false;
+ if (dataGrid == resultTable)
+ {
+ sorter = new SortParam { name = header.Column.SortMemberPath, direction = ListSortDirection.Descending, sort = "DESC" };
+ }
+ else
+ {
+ itemSorter = new SortParam { name = header.Column.SortMemberPath, direction = ListSortDirection.Descending, sort = "DESC" };
+ }
+ }
+ else
+ {
+ col.IsAsc = null;
+ if (dataGrid == resultTable)
+ {
+ sorter = null;
+ }
+ else
+ {
+ itemSorter = null;
+ }
+ }
+
+ if (dataGrid == resultTable)
+ {
+ if (CurrentPage == 1)
+ {
+ SelectPage(1, this.pageSize);
+ }
+ else
+ {
+ CurrentPage = 1;
+ }
+ }
+ else
+ {
+ if (TestItemPage == 1)
+ {
+ RefreshTestItem(this.selectResultId, 1, this.pageSize);
+ }
+ else
+ {
+ TestItemPage = 1;
+ }
+ }
+ }
+
+ private void page_CurrentPageChanged(object sender, Panuon.WPF.SelectedValueChangedRoutedEventArgs<int> e)
+ {
+ if (sender == page)
+ {
+ SelectPage(e.NewValue, this.pageSize);
+ }
+ else
+ {
+ RefreshTestItem(this.selectResultId, e.NewValue, this.pageSize);
+ }
+ }
+
+ private string selectResultId;
+
+ partial void OnSelectedResultChanged(object value)
+ {
+ if (value != null)
+ {
+ return;
+ }
+ var selectedRow = value as DataRowView;
+ var resultId = selectedRow?["resultId"]?.ToString();
+ this.SelectedStatus = selectedRow?["result"]?.ToString();
+ this.selectResultId = resultId;
+
+ if (TestItemPage == 1)
+ {
+ RefreshTestItem(resultId, 1, this.pageSize);
+ }
+ else
+ {
+ TestItemPage = 1;
+ }
+ }
+
+ private void resultTable_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ var selectedRow = this.SelectedResult as DataRowView;
+ var resultId = selectedRow?["resultId"]?.ToString();
+ this.SelectedStatus = selectedRow?["result"]?.ToString();
+ this.selectResultId = resultId;
+
+ if (TestItemPage == 1)
+ {
+ RefreshTestItem(resultId, 1, this.pageSize);
+ }
+ else
+ {
+ TestItemPage = 1;
+ }
+ }
+ }
+}
diff --git a/Plugin.DataViewer/Plugin.DataViewer.csproj b/Plugin.DataViewer/Plugin.DataViewer.csproj
new file mode 100644
index 0000000..71ea8f2
--- /dev/null
+++ b/Plugin.DataViewer/Plugin.DataViewer.csproj
@@ -0,0 +1,26 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ <ProjectReference Include="..\HMI.Util\HMI.Util.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.TestResult/DataTable.xaml b/Plugin.TestResult/DataTable.xaml
index 1b28592..12a6b61 100644
--- a/Plugin.TestResult/DataTable.xaml
+++ b/Plugin.TestResult/DataTable.xaml
@@ -35,12 +35,12 @@
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
-
+
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
-
+
<TextBlock FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
Converter={StaticResource FontSizeConverter}, ConverterParameter='20,940'}"
FontWeight="Bold"
@@ -75,7 +75,7 @@
<!--<local:Chart Grid.Row="2" x:Name="chart" BorderThickness="0,1,0,1" BorderBrush="Black"
MouseDoubleClick="chart_MouseDoubleClick"/>-->
- <StatusBar FontSize="18" Grid.Row="3">
+ <StatusBar FontSize="14" Grid.Row="3">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel/>
@@ -123,23 +123,29 @@
</StatusBarItem>
<StatusBarItem >
- <TextBox IsReadOnly="True" Background="Transparent" BorderThickness="0" Text="{Binding statusText}"/>
+ <TextBox IsReadOnly="True" FontSize="16" Background="Transparent" BorderThickness="0" Text="{Binding statusText}"/>
</StatusBarItem>
</StatusBar>
- <Grid Grid.Row="4">
- <Grid.ColumnDefinitions>
+ <UniformGrid Grid.Row="4" Rows="1">
+ <!--<UniformGrid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
- </Grid.ColumnDefinitions>
+ </UniformGrid.ColumnDefinitions>-->
<Button Click="ScanWindow_Click" Style="{StaticResource PrimaryButton}"
Content="{DynamicResource Tr.Scan}"/>
<Button Grid.Column="1" Click="ClearAllSnr_Click" Style="{StaticResource DangerButton}"
+ IsEnabled="{Binding IsTesting,Converter={StaticResource reverseBool}}"
Content="{DynamicResource Tr.ClearAllSNR}"/>
<!--<Button Grid.Column="2" Click="SetStationGlobal_Click" Style="{StaticResource SuccessButton}"
- Content="{DynamicResource App.Start}"/>-->
- <Button Grid.Column="2" Click="StartSingleClick">
+ Content="{DynamicResource App.Start}"/> Background="#1296db"-->
+
+ <Button Grid.Column="2" Click="Abort_Click" x:Name="abortBtn"
+ Style="{DynamicResource DangerButton}" Background="#1296db" Content="Abort"/>
+
+ <Button Grid.Column="3" Click="StartSingleClick">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource SuccessButton}">
<Setter Property="Content" Value="{DynamicResource App.Start}"/>
@@ -152,7 +158,6 @@
</Style>
</Button.Style>
</Button>
- </Grid>
-
+ </UniformGrid>
</Grid>
</UserControl>
\ No newline at end of file
diff --git a/Plugin.TestResult/DataTable.xaml.cs b/Plugin.TestResult/DataTable.xaml.cs
index 1ac79ce..2c3272e 100644
--- a/Plugin.TestResult/DataTable.xaml.cs
+++ b/Plugin.TestResult/DataTable.xaml.cs
@@ -1,10 +1,13 @@
-锘縰sing HMI.Core.Setting;
+锘縰sing HMI.Base;
+using HMI.Core.Setting;
using HMI.Core.Util;
+using HMI.LogUtil;
using HMI.UI.Util;
using HMI.Util;
using Plugin.TestResult;
using Plugin.TestResult.Util;
using Plugin.TestResult_WPF.Model;
+using Plugin.TsSupport;
using SuperSocket.SocketBase.Config;
using SuperSocket.SocketBase.Protocol;
using System;
@@ -15,6 +18,7 @@
using System.Timers;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Markup;
namespace Plugin.TestResult_WPF
{
@@ -90,7 +94,7 @@
public int index { get; private set; }
private readonly int cellCount;
private readonly string chartTitle;
- private readonly TestResultView parent;
+ public readonly TestResultView parent;
private BaseConfig config;
private LiveChart chart;
@@ -137,7 +141,7 @@
{
var cellRow = (i / config.PositionColumn) + 1;
var cellCol = (i % config.PositionColumn) + 1;
- var cellTitle = $"{title}-{cellRow}-{cellCol}";
+ var cellTitle = $"{title}-{cellRow}-{cellCol}";
var cell = new SingleCell(this, cellTitle, i, config.CellListMaxSize, countIniPath);
mainGrid.Children.Add(cell);
@@ -152,6 +156,7 @@
testTimeTimer.AutoReset = true;
testTimeTimer.Elapsed += TestTimeTimer_Elapsed;
if (!ParamSetting.ShowCoolerSetting) coolerSetting.Visibility = Visibility.Collapsed;
+ if (!ParamSetting.ShowBurnInAbort) abortBtn.Visibility = Visibility.Collapsed;
}
private void TestTimeTimer_Elapsed(object sender, ElapsedEventArgs e)
@@ -306,13 +311,42 @@
{
if (MsgBoxHelper2.WarnChoose(this.lang("Tr.MakeSureStopOvenTest", title)) == MessageBoxResult.OK)
{
+ LogHelper.Info("UI", $"鑰佸寲鐐塠{title}]鍋滄鎸夐挳鎸変笅", out _);
+ ViewControl.Logger.Info($"鑰佸寲鐐塠{title}]鍋滄鎸夐挳鎸変笅");
parent.SetStartFlag(this.index, false);
}
}
else
{
- ClearChartData();
- parent.SetStartFlag(this.index, true);
+ /// 妫�鏌ユ槸鍚﹀叧闂�
+ if (parent.executionWrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) != true)
+ {
+ /// 娌″叧闂ㄤ笉鍏佽鍚姩
+ MsgBoxHelper2.Warn("璇峰厛鍏抽棴鑸遍棬锛�");
+ return;
+ }
+
+ /// 妫�鏌ユ槸鍚︽湁鏉$爜
+ bool flag = false;
+ foreach (var cell in cells)
+ {
+ if (!string.IsNullOrEmpty(cell.sn))
+ {
+ flag = true;
+ break;
+ }
+ }
+ if (flag)
+ {
+ LogHelper.Info("UI", $"鑰佸寲鐐塠{title}]鍚姩鎸夐挳鎸変笅", out _);
+ ViewControl.Logger.Info($"鑰佸寲鐐塠{title}]鍚姩鎸夐挳鎸変笅");
+ ClearChartData();
+ parent.SetStartFlag(this.index, true);
+ }
+ else
+ {
+ MsgBoxHelper2.Warn("璇峰厛瀹屾垚鎵爜锛�");
+ }
}
}
@@ -346,8 +380,9 @@
private void Scanner_ComplateClick(object sender, RoutedEventArgs e)
{
string paramName = $"StationState.Scanner[{index}]";
- parent.engine.Globals.SetValBoolean(paramName, 1, true);
- //parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+
+ parent.executionWrapper.SetStationGlobalValue<bool>(paramName, 1, true);
+ //parent.engine.Globals.SetValBoolean(paramName, 1, true);
}
private void Scanner_Closed(object sender, EventArgs e)
@@ -357,7 +392,8 @@
private void Scanner_FinishBarcode(object sender, BarcodeEventArg e)
{
- if (parent.SequenceContext == null) return;
+ if (parent.executionWrapper == null) return;
+ //if (parent.SequenceContext == null) return;
int rows = (config.CellCount / config.PositionColumn) + 1;
CellInfo cellInfo = ScannerParser.GetCellInfoByCode(CbProduct.SelectedItem?.ToString(), mainGrid.Columns, rows, e.positionCode);
@@ -381,9 +417,11 @@
throw new Exception(this.lang("Tr.PositionCantClearSNR", oldCellInfo.OriginCode));
}
// 绉婚櫎鏉$爜
- parent.engine.Globals.SetValString(oldCellInfo.LookUpStr, 1, "");
- parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ parent.executionWrapper.SetStationGlobalValue<string>(oldCellInfo.LookUpStr, 1, "");
+ parent.executionWrapper.CommitToDisk(false);
+ //parent.engine.Globals.SetValString(oldCellInfo.LookUpStr, 1, "");
+ //parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
oldCell.SetStatus("waiting");
oldCell.ClearSN();
return;
@@ -397,8 +435,11 @@
}
// 鍐欏叆鏉$爜
- parent.engine.Globals.SetValString(LookupStr, 1, snrCode);
- parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ parent.executionWrapper.SetStationGlobalValue<string>(LookupStr, 1, snrCode);
+ parent.executionWrapper.CommitToDisk(false);
+
+ //parent.engine.Globals.SetValString(LookupStr, 1, snrCode);
+ //parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
TestResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).SetStatus("hadCode");
TestResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).sn = snrCode;
@@ -532,8 +573,6 @@
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],
@@ -747,10 +786,10 @@
private void ClearAllSnr_Click(object sender, RoutedEventArgs e)
{
- var str = $"StationState.DoorClose[{index}]";
- if (parent.engine.Globals.GetValBoolean(str, 0) == true)
+ if (parent.executionWrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) == true)
{
- MsgBoxHelper.Error(Window.GetWindow(this), this.lang("Tr.CantClearSNR"));
+ /// 鍏抽棬浜嗗氨涓嶅厑璁告竻鏉$爜
+ MsgBoxHelper2.Warn(this.lang("Tr.CantClearSNR"));
return;
}
@@ -779,8 +818,7 @@
public void TryClearCellSN(int cellIndex)
{
- var str = $"StationState.DoorClose[{this.index}]";
- if (parent.engine.Globals.GetValBoolean(str, 0) == true)
+ if (parent.executionWrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) == true)
{
MsgBoxHelper.Error(Window.GetWindow(this), this.lang("Tr.CantClearSNR"));
return;
@@ -795,18 +833,50 @@
string LookupStr = $"StationState.SN[{dutNo}]";
var lastSN = cell.sn;
cell.SetStatus("waiting");
- parent.engine.Globals.SetValString(LookupStr, 1, "");
- parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+
+ parent.executionWrapper.SetStationGlobalValue<string>(LookupStr, 1, "");
+ parent.executionWrapper.CommitToDisk(false);
+
+ //parent.engine.Globals.SetValString(LookupStr, 1, "");
+ //parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
if (!string.IsNullOrEmpty(lastSN)) Scanner.RemoveSNR(lastSN);
cell.ClearSN();
}
- private void Button_Click_2(object sender, RoutedEventArgs e)
+ private void Abort_Click(object sender, RoutedEventArgs e)
{
- if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("Tr.MakeSureStopOvenTest", title)) == MessageBoxResult.OK)
+ if (!parent.IsRunning)
{
- parent.SetStartFlag(this.index, false);
+ MsgBoxHelper.WarnMessage(this, this.lang("Tr.StartSeqFirst"), null, MessageBoxButton.OK);
+ return;
}
+
+
+
+
+ string key = $"StationState.Start[{this.index}]";
+ //if (parent.executionWrapper?.GetStationGlobalValue<bool>(key, 0) == true)
+ //{
+ // MsgBoxHelper2.Warn("娴嬭瘯鍚姩涓紝涓嶅厑璁窤bort");
+ // return;
+ //}
+ var win = new RequirePasswordByUser("admin")
+ {
+ Owner = Window.GetWindow(this)
+ };
+ if (win.ShowDialog() != true)
+ {
+ return;
+ }
+
+ if (MsgBoxHelper2.WarnChoose("璇风‘璁よ�佸寲浠撳湪瀹夊叏娓╁害锛屾按鍐锋満鍚规按瀹屾垚锛屽崟鍑籓K鎸夐挳浠撲綅鍥炲埌鍒濆鍖栫姸鎬�") != MessageBoxResult.OK)
+ {
+ return;
+ }
+ LogHelper.Info("UI", "Abort鎸夐挳鎸変笅", out _);
+ ViewControl.Logger.Info("Abort鎸夐挳鎸変笅");
+ key = $"StationState.Abort[{this.index}]";
+ parent.executionWrapper?.SetStationGlobalValue(key, 0, true);
}
}
}
diff --git a/Plugin.TestResult/InfoWindow.xaml b/Plugin.TestResult/InfoWindow.xaml
index 7d9d601..169411f 100644
--- a/Plugin.TestResult/InfoWindow.xaml
+++ b/Plugin.TestResult/InfoWindow.xaml
@@ -33,7 +33,9 @@
CanUserDeleteRows="False"
IsReadOnly="True"
ColumnWidth="*"
- VirtualizingStackPanel.VirtualizationMode="Standard"
+ VirtualizingPanel.IsContainerVirtualizable="True"
+ VirtualizingPanel.IsVirtualizing="True"
+ VirtualizingStackPanel.VirtualizationMode="Recycling"
FontSize="16">
<DataGrid.Resources>
<Style TargetType="ScrollBar" BasedOn="{StaticResource ScrollStyle_Mobile}"/>
diff --git a/Plugin.TestResult/Lixun/SNValidator.cs b/Plugin.TestResult/Lixun/SNValidator.cs
new file mode 100644
index 0000000..353b322
--- /dev/null
+++ b/Plugin.TestResult/Lixun/SNValidator.cs
@@ -0,0 +1,91 @@
+锘縰sing HMI.Core.Manager;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Plugin.TestResult.Lixun
+{
+ public class SNValidator
+ {
+ public static bool ValidateSN(string model, string sn, out string msg)
+ {
+ msg = string.Empty;
+ string validate = string.Empty;
+ try
+ {
+ validate = ProductManager.GetParameterByProductAndName(model, "SNRValidate")?.Value;
+ if (string.IsNullOrEmpty(validate))
+ {
+ msg = $"褰撳墠鍨嬪彿[{model}]鏈厤缃甋NRValidate鍙傛暟锛屾棤娉曟牎楠孲N鍚堟硶鎬�";
+ return true;
+ }
+ string[] arr = validate.Split(';');
+ if (arr.Length == 1)
+ {
+ if (!sn.Contains(arr[0]))
+ {
+ msg = $"鏉$爜涓嶅寘鍚浐瀹氱爜[{arr[0]}]";
+ return false;
+ }
+ return true;
+ }
+
+ if (arr.Length == 2)
+ {
+ int length = int.Parse(arr[1]);
+ if (!sn.Contains(arr[0]))
+ {
+ msg = $"鏉$爜涓嶅寘鍚浐瀹氱爜[{arr[0]}]";
+ return false;
+ }
+ if (sn.Length != length)
+ {
+ msg = $"鏉$爜闀垮害搴斾负[{length}]";
+ return false;
+ }
+ return true;
+ }
+
+ if (arr.Length >= 3)
+ {
+ int length = int.Parse(arr[1]);
+ int startIndex = int.Parse(arr[2]);
+
+ if (sn.Length != length)
+ {
+ msg = $"鏉$爜闀垮害搴斾负[{length}]";
+ return false;
+ }
+
+ if (startIndex >= sn.Length)
+ {
+ msg = $"鏉$爜闀胯灏忎簬璧峰涓嬫爣[{validate}]";
+ return false;
+ }
+
+ if (arr[0].Length > sn.Length)
+ {
+ msg = $"鏉$爜闀胯灏忎簬鍥哄畾鐮侀暱搴{validate}]";
+ return false;
+ }
+
+ if (sn.Substring(startIndex, arr[0].Length) != arr[0])
+ {
+ msg = $"鍥哄畾鐮佹鏌ュけ璐ワ細 [{validate}]";
+ return false;
+ }
+ return true;
+ }
+ msg = $"褰撳墠鍨嬪彿[{model}]閰嶇疆鍙傛暟[{validate}]瑙f瀽澶辫触";
+ return false;
+ }
+ catch (Exception ex)
+ {
+ msg = $"褰撳墠鍨嬪彿[{model}]閰嶇疆鍙傛暟[{validate}]瑙f瀽澶辫触";
+ return false;
+ }
+ }
+ }
+}
diff --git a/Plugin.TestResult/ManualDebugWindow.xaml b/Plugin.TestResult/ManualDebugWindow.xaml
new file mode 100644
index 0000000..9313b73
--- /dev/null
+++ b/Plugin.TestResult/ManualDebugWindow.xaml
@@ -0,0 +1,21 @@
+锘�<pu:WindowX x:Class="Plugin.TestResult.ManualDebugWindow"
+ 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"
+ mc:Ignorable="d"
+ xmlns:sb="clr-namespace:Util.SB;assembly=Util.ManualDebug"
+ Title="ManualDebugWindow"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ Style="{StaticResource ModalWindow}"
+ Closing="Window_Closing"
+ WindowStartupLocation="CenterScreen"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ Height="1000" Width="900">
+ <Grid x:Name="sb">
+ <sb:ManualDebug OvenName="{Binding OvenName,Mode=OneWay}"
+ CellName="{Binding CellName,Mode=OneWay}"
+ OvenIndex="{Binding OvenIndex,Mode=OneWay}"
+ CellIndex="{Binding CellIndex,Mode=OneWay}"/>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.TestResult/ManualDebugWindow.xaml.cs b/Plugin.TestResult/ManualDebugWindow.xaml.cs
new file mode 100644
index 0000000..c40668b
--- /dev/null
+++ b/Plugin.TestResult/ManualDebugWindow.xaml.cs
@@ -0,0 +1,95 @@
+锘縰sing HMI.Util;
+using Panuon.WPF.UI;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Windows;
+using Util.SB;
+
+namespace Plugin.TestResult
+{
+ /// <summary>
+ /// ManualDebugWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ManualDebugWindow : WindowX
+ {
+
+ private ManualDebug debug;
+
+ public ManualDebugWindow(string seqPath, string modelPath)
+ {
+ DataContext = this;
+ InitializeComponent();
+ debug = (ManualDebug)sb.Children[0];
+ ReadBtns();
+ //List<BtnConfig> settings = new List<BtnConfig> { new BtnConfig { Title = "涓婄數婵�娲�", Name = "Active" } };
+ debug.seqPath = seqPath;
+ debug.modelPath = modelPath;
+ }
+
+ private string ovenName;
+ public string OvenName
+ {
+ get => ovenName;
+ set
+ {
+ Set(ref ovenName, value);
+ }
+ }
+
+ private string cellName;
+ public string CellName
+ {
+ get => cellName;
+ set
+ {
+ Set(ref cellName, value);
+ }
+ }
+
+ private int ovenIndex;
+ public int OvenIndex
+ {
+ get => ovenIndex;
+ set
+ {
+ Set(ref ovenIndex, value);
+ }
+ }
+
+ private int cellIndex;
+ public int CellIndex
+ {
+ get => cellIndex;
+ set
+ {
+ Set(ref cellIndex, value);
+ }
+ }
+
+ private void ReadBtns()
+ {
+ string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Settings.ini");
+ var map = IniFileHelper.GetKeyValuesBySection(path, "Btns");
+ List<BtnConfig> settings = new List<BtnConfig>();
+ foreach (var kv in map)
+ {
+ settings.Add(new BtnConfig { Title = kv.Key, Name = kv.Value });
+ }
+ debug.RefreshButtons(settings);
+ }
+
+ private void Window_Closing(object sender, CancelEventArgs e)
+ {
+ if (MessageBox.Show("纭畾瑕佸叧闂悧锛�", "鎻愮ず", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
+ {
+ debug.Stop();
+ }
+ else
+ {
+ e.Cancel = true;
+ }
+ }
+ }
+}
diff --git a/Plugin.TestResult/Model/TcpServer.cs b/Plugin.TestResult/Model/TcpServer.cs
index 056e4ca..2f1fc8c 100644
--- a/Plugin.TestResult/Model/TcpServer.cs
+++ b/Plugin.TestResult/Model/TcpServer.cs
@@ -1,8 +1,6 @@
-锘縰sing ScottPlot.Colormaps;
-using SuperSocket.SocketBase;
+锘縰sing SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Text;
@@ -13,7 +11,6 @@
public override StringRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
{
rest = 0;
- StringBuilder sb = new StringBuilder();
int i = offset;
List<byte> bytes = new List<byte>();
while (i < readBuffer.Length)
@@ -23,17 +20,33 @@
{
break;
}
- sb.Append((char)b);
bytes.Add(b);
}
byte[] arr = bytes.ToArray();
- return new StringRequestInfo(DateTime.Now + "", Encoding.UTF8.GetString(arr), null);//sb.ToString()
+ return new StringRequestInfo(DateTime.Now.ToString("yyyyMMddHHmmssfff"), Encoding.UTF8.GetString(arr), null);//sb.ToString()
}
}
+ public class StringParser : IRequestInfoParser<StringRequestInfo>
+ {
+
+ public StringRequestInfo ParseRequestInfo(string source)
+ {
+ return new StringRequestInfo(DateTime.Now.ToString("yyyyMMddHHmmssfff"), source, null);
+ }
+ }
+
+ //public class TcpServer : AppServer<TcpSession>
+ //{
+ // public TcpServer() : base(new DefaultReceiveFilterFactory<DTReceiveFilter, StringRequestInfo>())
+ // {
+
+ // }
+ //}
+
public class TcpServer : AppServer<TcpSession>
{
- public TcpServer() : base(new DefaultReceiveFilterFactory<DTReceiveFilter, StringRequestInfo>())
+ public TcpServer() : base(new TerminatorReceiveFilterFactory("\n", Encoding.UTF8, new StringParser()))
{
}
diff --git a/Plugin.TestResult/Plugin.TestResult.csproj b/Plugin.TestResult/Plugin.TestResult.csproj
index 18a7c6d..dd34f6b 100644
--- a/Plugin.TestResult/Plugin.TestResult.csproj
+++ b/Plugin.TestResult/Plugin.TestResult.csproj
@@ -103,6 +103,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
</Reference>
+ <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.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>
@@ -206,6 +209,10 @@
<DependentUpon>CoolerStatus.xaml</DependentUpon>
</Compile>
<Compile Include="CSVPrinter.cs" />
+ <Compile Include="Lixun\SNValidator.cs" />
+ <Compile Include="ManualDebugWindow.xaml.cs">
+ <DependentUpon>ManualDebugWindow.xaml</DependentUpon>
+ </Compile>
<Compile Include="Model\BaseConfig.cs" />
<Compile Include="Model\CellInfo.cs" />
<Compile Include="Model\Info.cs" />
@@ -257,6 +264,10 @@
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="InfoWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="ManualDebugWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -321,7 +332,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <None Include="app.config" />
<None Include="Config\log4net.config" />
<None Include="Config\log4net.unix.config" />
<None Include="packages.config" />
@@ -382,6 +392,14 @@
<Project>{3068124e-f12b-473e-99a0-2da5a0385d05}</Project>
<Name>Plugin.TsSupport</Name>
</ProjectReference>
+ <ProjectReference Include="..\SimpleUtil\HMI.LogUtil\HMI.LogUtil.csproj">
+ <Project>{6d0aab08-0f3e-48ce-b755-9d29bc8f1225}</Project>
+ <Name>HMI.LogUtil</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Util.ManualDebug\Util.ManualDebug.csproj">
+ <Project>{d0944e62-ee52-4abe-832a-a09d98814db1}</Project>
+ <Name>Util.ManualDebug</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="Resource\abort.png" />
diff --git a/Plugin.TestResult/Scanner.xaml.cs b/Plugin.TestResult/Scanner.xaml.cs
index 991d647..48bf1c5 100644
--- a/Plugin.TestResult/Scanner.xaml.cs
+++ b/Plugin.TestResult/Scanner.xaml.cs
@@ -4,6 +4,7 @@
using HMI.UI.Util;
using HMI.Util;
using Panuon.WPF.UI;
+using Plugin.TestResult.Lixun;
using Plugin.TestResult.Model;
using Plugin.TestResult.Util;
using Plugin.TestResult_WPF.Model;
@@ -228,10 +229,34 @@
var EnableMes = ParameterManager.GetCommonParameterByName<bool>("EnableMes", false);
if (ParamSetting.CustomerCode == "LIXUN" && EnableMes)
{
- if (PNUtil.GetPN(ParamSetting.MesAddress, snr, out string pn, out string msg))
+ var table = TestResultView.tables[this.ovenIndex];
+ string currentPn = table.CbProduct.Text;
+
+ /// 妫�鏌ユ牸寮�
+ if (!SNValidator.ValidateSN(currentPn, snr, out string msg))
{
- var table = TestResultView.tables[this.ovenIndex];
- string currentPn = table.CbProduct.Text;
+ TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革細{msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+
+ /// 鑾峰彇绔欏悕
+ string stationName = ProductManager.GetParameterByProductAndName(currentPn, "MES绔欎綅")?.Value;
+ if (string.IsNullOrEmpty(stationName))
+ {
+ TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革紝褰撳墠浜у搧[{currentPn}]鏈缃弬鏁癕ES绔欎綅");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+
+ /// 妫�鏌N
+ if (PNUtil.GetPN(ParamSetting.MesAddress, stationName, snr, out string pn, out msg))
+ {
+
if (pn != currentPn)
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
@@ -249,6 +274,27 @@
snrText.Focus();
return;
}
+
+ /// 妫�鏌ュ伐搴�
+ if (PNUtil.CheckIn(ViewControl.Logger, ParamSetting.MesAddress, stationName, snr, out bool needCheckIn, out msg))
+ {
+ if (needCheckIn != true)
+ {
+ TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"鏉$爜[{snr}]宸ュ簭涓嶅湪鏈珯锛歿msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+ }
+ else
+ {
+ TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"鏉$爜[{snr}]CheckIn澶辫触锛歿msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
}
//var _ = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, snr);
//ToastHelper.Warning(this, "浜у搧鐮佹牸寮忓紓甯�");
diff --git a/Plugin.TestResult/SingleCell.xaml b/Plugin.TestResult/SingleCell.xaml
index f3d8cca..9a6c1dc 100644
--- a/Plugin.TestResult/SingleCell.xaml
+++ b/Plugin.TestResult/SingleCell.xaml
@@ -9,6 +9,7 @@
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
x:Name="uc"
+ PreviewMouseRightButtonDown="OnPreviewMouseRightButtonDown"
MouseDoubleClick="UserControl_MouseDoubleClick"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
@@ -19,13 +20,19 @@
<ToolTip Padding="5" BorderThickness="1" BorderBrush="Black" Background="Yellow" Content="{Binding tooltipContent}"/>
</UserControl.ToolTip>-->
- <UserControl.ContextMenu>
+ <!--<UserControl.ContextMenu>
<ContextMenu>
- <!--<MenuItem IsCheckable="True" IsChecked="{Binding CellIsDisabled,Mode=TwoWay}" Header="绂佺敤"/>-->
- <MenuItem IsCheckable="False" x:Name="clearSNRItem" Click="MenuItem_Click" Header="{DynamicResource Tr.ClearSNR}"/>
+ <MenuItem IsCheckable="False" DataContext="{Binding table}" IsEnabled="{Binding IsTesting,Converter={StaticResource reverseBool}}" x:Name="clearSNRItem" Click="MenuItem_Click" Header="{DynamicResource Tr.ClearSNR}"/>
<MenuItem IsCheckable="False" x:Name="exportCSVItem" Click="MenuItem_Click" Header="{DynamicResource App.ExportCSV}"/>
+ <MenuItem IsCheckable="False" x:Name="manualDebugItem" Click="MenuItem_Click" Header="鎵嬪姩璋冭瘯">
+ <MenuItem.Style>
+ <Style TargetType="MenuItem" BasedOn="{StaticResource {x:Static pu:StyleKeys.MenuItemStyle}}">
+
+ </Style>
+ </MenuItem.Style>
+ </MenuItem>
</ContextMenu>
- </UserControl.ContextMenu>
+ </UserControl.ContextMenu>-->
<UserControl.Style>
<Style TargetType="UserControl">
@@ -65,32 +72,14 @@
</UserControl.Style>
<Grid>
<Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="18"/>
+ <RowDefinition />
+ <RowDefinition Height="14"/>
+ <RowDefinition Height="14"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
- <StackPanel Orientation="Horizontal" Background="LightGray" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right">
- <TextBlock Foreground="Red" Text="{DynamicResource Ts.ProbeAlarm}">
- <TextBlock.Style>
- <Style TargetType="TextBlock">
- <Setter Property="Visibility" Value="Collapsed"/>
- <Style.Triggers>
- <DataTrigger Binding="{Binding probeAlarm}" Value="True">
- <Setter Property="Visibility" Value="Visible"/>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </TextBlock.Style>
- </TextBlock>
- <TextBlock Margin="0">
- <Run Text="{Binding ProbeCount}"/>
- <Run Text="/"/>
- <Run Text="{Binding ProbeWarn}"/>
- </TextBlock>
- </StackPanel>
<Label Grid.Row="0" Grid.Column="0" HorizontalContentAlignment="Left" VerticalContentAlignment="Top" Padding="0" Margin="5,5,0,0"
FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
Converter={StaticResource FontSizeConverter}, ConverterParameter='8,103'}"
@@ -106,9 +95,10 @@
</Style>
</Label.Style>
</Label>
- <ui:ScrollLabel Grid.Row="1" Grid.Column="0" Margin="3,0,0,5" Padding="0" Value="{Binding sn}"/>
- <Image Grid.Row="0" Grid.Column="1" Width="30" HorizontalAlignment="Right" Height="30" Margin="0,5,5,0">
+ <Image Grid.Row="0" Grid.Column="1" Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+ Converter={StaticResource FontSizeConverter}, ConverterParameter='10,20'}" HorizontalAlignment="Right"
+ Margin="0,5,5,0">
<Image.Style>
<Style TargetType="Image">
<Setter Property="HorizontalAlignment" Value="Center"/>
@@ -148,5 +138,27 @@
</Style>
</Image.Style>
</Image>
+
+ <ui:ScrollLabel Grid.Row="1" Grid.Column="0" FontSize="10" Grid.ColumnSpan="2" Margin="3,0,0,0" Padding="0" Value="{Binding sn}"/>
+
+ <StackPanel Orientation="Horizontal" Background="LightGray" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Top" HorizontalAlignment="Right">
+ <TextBlock Foreground="Red" Text="{DynamicResource Ts.ProbeAlarm}" FontSize="10">
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding probeAlarm}" Value="True">
+ <Setter Property="Visibility" Value="Visible"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ <TextBlock Margin="0" FontSize="10">
+ <Run Text="{Binding ProbeCount}"/>
+ <Run Text="/"/>
+ <Run Text="{Binding ProbeWarn}"/>
+ </TextBlock>
+ </StackPanel>
</Grid>
</UserControl>
diff --git a/Plugin.TestResult/SingleCell.xaml.cs b/Plugin.TestResult/SingleCell.xaml.cs
index bae64dd..7d5659d 100644
--- a/Plugin.TestResult/SingleCell.xaml.cs
+++ b/Plugin.TestResult/SingleCell.xaml.cs
@@ -3,8 +3,10 @@
using HMI.Core.Manager;
using HMI.Core.Setting;
using HMI.Core.Util;
+using HMI.UI.Util;
using HMI.Util;
using PLCHelper;
+using Plugin.TestResult;
using Plugin.TestResult.Util;
using Plugin.TestResult_WPF.Constant;
using Plugin.TestResult_WPF.Model;
@@ -49,7 +51,7 @@
private InfoWindow window;
private int maxSize;
- private DataTable table;
+ public DataTable table { get; private set; }
public SingleCell(DataTable table, string title, int index, int maxSize, string iniFile)
{
@@ -296,47 +298,66 @@
public void SetStatus(string status)
{
- var oldStatus = this.status;
- this.status = status;
- if (oldStatus != "testing" && status == "testing")
+ Dispatcher.Invoke(() =>
{
- UpdateProbeCount(ProbeCount + 1);
- var now = DateTime.Now;
- string dateStr = now.ToString("yyyyMMdd");
- visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}";
- helper = CheckSqlHelper(dateStr);
- }
+ var oldStatus = this.status;
+ this.status = status;
+ if (oldStatus != "testing" && status == "testing")
+ {
+ UpdateProbeCount(ProbeCount + 1);
+ var now = DateTime.Now;
+ string dateStr = now.ToString("yyyyMMdd");
+ visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}";
+ helper = CheckSqlHelper(dateStr);
+ InsertARecourd();
+ }
- if (oldStatus != "ok" && status == "ok")
- {
- SaveInfoToDB();
- }
+ if (oldStatus != "ok" && status == "ok")
+ {
+ SaveInfoToDB();
+ }
- if (oldStatus != "ng" && status == "ng")
+ if (oldStatus != "ng" && status == "ng")
+ {
+ SaveInfoToDB();
+ }
+ });
+ }
+
+ private void InsertARecourd()
+ {
+ try
{
- SaveInfoToDB();
+ string model = table?.CbProduct?.SelectedItem?.ToString();
+ var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ var sql = $"INSERT INTO testResult (sn,model,station,position,result,time,resultId) VALUES ('{sn}','{model}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+ helper.Execute(sql);
+ }
+ catch (Exception ex)
+ {
+ ViewControl.Logger.Error($"Cell[{title}] SaveToDB Error.", ex);
}
}
public void WriteCSV(Info info)
{
- try
- {
- if (ParamSetting.CustomerCode != "LIXUN")
- {
- return;
- }
- string fileName = this.sn?.Replace("/", "#")?.Replace("\\", "#") + ".csv";
- string dir = Path.Combine(ParamSetting.DataLogFolder, "csv", this.title);
- string title = $"{this.lang("Test.Name")},{this.lang("Test.Value")},{this.lang("Test.LimitDown")},{this.lang("Test.LimitUp")},{this.lang("Test.Unit")},{this.lang("Test.Result")},{this.lang("Test.TestTime")}";
- string line = $"{info.step},{info.value},{info.limitDown},{info.limitUp},{info.unit},{info.result},{info.updateTime}";
+ //try
+ //{
+ // if (ParamSetting.CustomerCode != "LIXUN")
+ // {
+ // return;
+ // }
+ // string fileName = this.sn?.Replace("/", "#")?.Replace("\\", "#") + ".csv";
+ // string dir = Path.Combine(ParamSetting.DataLogFolder, "csv", this.title);
+ // string title = $"{this.lang("Test.Name")},{this.lang("Test.Value")},{this.lang("Test.LimitDown")},{this.lang("Test.LimitUp")},{this.lang("Test.Unit")},{this.lang("Test.Result")},{this.lang("Test.TestTime")}";
+ // string line = $"{info.step},{info.value},{info.limitDown},{info.limitUp},{info.unit},{info.result},{info.updateTime}";
- CSVPrinter.Print(dir, fileName, title, line);
- // ReverseCSV(Path.Combine(dir, fileName));
- }
- catch (Exception ex)
- {
- }
+ // CSVPrinter.Print(dir, fileName, title, line);
+ // // ReverseCSV(Path.Combine(dir, fileName));
+ //}
+ //catch (Exception ex)
+ //{
+ //}
}
public void SendToChart(Info info)
@@ -378,30 +399,47 @@
allInfos.Add(info);
SendToChart(info);
WriteCSV(info);
- if (queue.Count >= maxSize)
+
+ /// 鐩墠鍏堜笉闄愬埗鏁伴噺锛屽悗缁鏋滄暟鎹繃澶氬鑷存�ц兘闂鍐嶈�冭檻闄愬埗鏁伴噺
+ //if (queue.Count >= maxSize)
+ //{
+ // queue.TryDequeue(out var first);
+ // queue.Enqueue(info);
+ // this.infos = new ObservableCollection<Info>(queue);
+ // if (window != null) window.UpdateSource(this.infos);
+ //}
+ //else
+ //{
+ // queue.Enqueue(info);
+ // if (window != null)
+ // {
+ // window.Dispatcher.Invoke(() =>
+ // {
+ // this.infos.Add(info);
+ // });
+ // }
+ // else
+ // {
+ // Dispatcher.Invoke(() =>
+ // {
+ // this.infos.Add(info);
+ // });
+ // }
+ //}
+
+ if (window != null)
{
- queue.TryDequeue(out var first);
- queue.Enqueue(info);
- this.infos = new ObservableCollection<Info>(queue);
- if (window != null) window.UpdateSource(this.infos);
+ window.Dispatcher.Invoke(() =>
+ {
+ this.infos.Add(info);
+ });
}
else
{
- queue.Enqueue(info);
- if (window != null)
+ Dispatcher.Invoke(() =>
{
- window.Dispatcher.Invoke(() =>
- {
- this.infos.Add(info);
- });
- }
- else
- {
- Dispatcher.Invoke(() =>
- {
- this.infos.Add(info);
- });
- }
+ this.infos.Add(info);
+ });
}
Dispatcher.Invoke(() =>
@@ -813,8 +851,10 @@
{
try
{
+ string model = table?.CbProduct?.SelectedItem?.ToString();
var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- var sql = $"INSERT INTO testResult (sn,station,position,result,time,resultId) VALUES ('{sn}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+ //var sql = $"INSERT INTO testResult (sn,model,station,position,result,time,resultId) VALUES ('{sn}','{model}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+ var sql = $"UPDATE testResult SET time = '{timestr}', result = '{this.status}' WHERE resultId = '{visualTestId}'";
helper.Execute(sql);
helper.Dispose();
helper = null;
@@ -850,11 +890,42 @@
case "exportCSVItem":
TryExportCSV();
break;
+ case "manualDebugItem":
+ OpenManualDebugWindow();
+ break;
default:
break;
}
}
+ /// <summary>
+ /// 鎵撳紑鎵嬪姩璋冭瘯绐楀彛
+ /// </summary>
+ private void OpenManualDebugWindow()
+ {
+ string manualDebugSeq = ParameterManager.GetCommonParameterByName("ManualDebugSeqPath")?.Value;
+ if (string.IsNullOrEmpty(manualDebugSeq))
+ {
+ MsgBoxHelper2.Error("璇峰厛璁剧疆鎵嬪姩璋冭瘯搴忓垪璺緞[ManualDebugSeqPath]!");
+ return;
+ }
+ string modelPath = table.parent.testModelFile;
+ var win = new ManualDebugWindow(manualDebugSeq, modelPath)
+ {
+ Title = $"{this.title}鎵嬪姩璋冭瘯",
+ Owner = Window.GetWindow(this),
+ OvenIndex = this.table.index,
+ OvenName = this.table.title,
+
+ CellIndex = this.index,
+ CellName = this.title
+ };
+ win.ShowDialog();
+ }
+
+ /// <summary>
+ /// 灏濊瘯瀵煎嚭CSV
+ /// </summary>
private void TryExportCSV()
{
System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog
@@ -885,5 +956,60 @@
return S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME,
$"Oven{table.index + 1}_Cell{index + 1}_Light_NG", on, out msg);
}
+
+ private void OnPreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+
+ ContextMenu contextMenu = new ContextMenu();
+ contextMenu.Closed += ContextMenu_Closed;
+
+ //< />
+ //<
+ //< MenuItem IsCheckable = "False" x: Name = "manualDebugItem" Click = "MenuItem_Click" Header = "鎵嬪姩璋冭瘯" >
+ // < MenuItem.Style >
+ // < Style TargetType = "MenuItem" BasedOn = "{StaticResource {x:Static pu:StyleKeys.MenuItemStyle}}" >
+
+ // </ Style >
+ // </ MenuItem.Style >
+ //</ MenuItem >
+
+ var item = new MenuItem
+ {
+ IsCheckable = false,
+ IsEnabled = !table.IsTesting,
+ Name = "clearSNRItem",
+ Header = this.lang("Tr.ClearSNR"),
+ };
+ item.Click += MenuItem_Click;
+ contextMenu.Items.Add(item);
+
+ item = new MenuItem
+ {
+ IsCheckable = false,
+ Name = "exportCSVItem",
+ Header = this.lang("App.ExportCSV"),
+ };
+ item.Click += MenuItem_Click;
+ contextMenu.Items.Add(item);
+
+ if (table.parent.inManualDebugMode)
+ {
+ item = new MenuItem
+ {
+ IsCheckable = false,
+ Name = "manualDebugItem",
+ Header = this.lang("鎵嬪姩璋冭瘯"),
+ };
+ item.Click += MenuItem_Click;
+ contextMenu.Items.Add(item);
+ }
+
+ this.ContextMenu = contextMenu;
+ }
+
+ private void ContextMenu_Closed(object sender, RoutedEventArgs e)
+ {
+ this.ContextMenu = null;
+ }
}
}
diff --git a/Plugin.TestResult/TestResultView.xaml.cs b/Plugin.TestResult/TestResultView.xaml.cs
index 1c93201..3712dc3 100644
--- a/Plugin.TestResult/TestResultView.xaml.cs
+++ b/Plugin.TestResult/TestResultView.xaml.cs
@@ -8,6 +8,7 @@
using Plugin.TsSupport;
using System;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
@@ -26,23 +27,31 @@
public static Dictionary<string, DataTable> nameTables { get; private set; } = new Dictionary<string, DataTable>();
private readonly BaseConfig config;
- public AxApplicationMgr testApp;
+
+
public string testModelFile;
public string testSeqFile;
- /// <summary>
- /// 娴嬭瘯搴忓垪
- /// </summary>
- private SequenceFile testSeq = null;
- public Engine engine;
- private Execution execution = null;
- /// <summary>
- /// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
- /// </summary>
- public SequenceContext SequenceContext { get; private set; } = null;
- /// <summary>
- /// 娴嬭瘯妯″瀷搴忓垪
- /// </summary>
- private SequenceFile modeSeq;
+ public bool inManualDebugMode = false;
+
+ #region TS鐩稿叧
+ //public AxApplicationMgr testApp;
+ ///// <summary>
+ ///// 娴嬭瘯搴忓垪
+ ///// </summary>
+ //private SequenceFile testSeq = null;
+ //public Engine engine;
+ //private Execution execution = null;
+ ///// <summary>
+ ///// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
+ ///// </summary>
+ //public SequenceContext SequenceContext { get; private set; } = null;
+ ///// <summary>
+ ///// 娴嬭瘯妯″瀷搴忓垪
+ ///// </summary>
+ //private SequenceFile modeSeq;
+
+ public ITestExecutionWrapper executionWrapper;
+ #endregion
public TestResultView() : this(new BaseConfig { testing = false })
{
@@ -53,7 +62,7 @@
public void RefreshCooler()
{
-
+
}
private void RefreshNumberConfig(BaseConfig config)
@@ -133,18 +142,27 @@
InitializeComponent();
- testApp = TestAppManager.GetAxApplicationMgr();
- testApp.ExitApplication += this.axApplicationMgr_ExitApplication;
- testApp.UIMessageEvent += this.axApplicationMgr_UIMessageEvent;
- testApp.ExecutionClosed += this.axApplicationMgr_ExecutionClosed;
+
+ executionWrapper = new TsExecutionWrapper(); //new TsExecutionWrapper();
+ if (executionWrapper is TsExecutionWrapper tsWrapper)
+ {
+ tsWrapper.AxApplicationMgr.ExitApplication += this.axApplicationMgr_ExitApplication;
+ tsWrapper.AxApplicationMgr.UIMessageEvent += this.axApplicationMgr_UIMessageEvent;
+ tsWrapper.AxApplicationMgr.ExecutionClosed += this.axApplicationMgr_ExecutionClosed;
+ ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
+ host.Child = tsWrapper.AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).EndInit();
+ }
- ((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
- host.Child = testApp;
- ((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit();
- //InitTestStandEngine();
- //StartTestSequence();
+ //testApp = TestAppManager.GetAxApplicationMgr();
+ //testApp.ExitApplication += this.axApplicationMgr_ExitApplication;
+ //testApp.UIMessageEvent += this.axApplicationMgr_UIMessageEvent;
+ //testApp.ExecutionClosed += this.axApplicationMgr_ExecutionClosed;
+ //((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
+ //host.Child = testApp;
+ //((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit();
}
private void Refresh()
@@ -203,12 +221,13 @@
{
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(testModelFile);
+ //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(testModelFile);
+ executionWrapper.Init();
}
catch (Exception ex)
{
@@ -222,10 +241,10 @@
try
{
if (string.IsNullOrEmpty(testSeqFile)) return;
- 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);
+ executionWrapper?.StartSequence(this.testSeqFile,
+ @"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+
+ executionWrapper.SetStationGlobalValue<bool>("StationState.StopTest", 0, false);
}
catch (Exception ex)
{
@@ -238,13 +257,24 @@
{
try
{
- if (this.SequenceContext == null)
- return;
- bool val = this.SequenceContext.StationGlobals.Exists("StationState.StopTest", 0);
- if (val)
+ executionWrapper?.SetStationGlobalValue<bool>("StationState.StopTest", 0, true, true);
+
+ try
{
- this.SequenceContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true);
- bool isStop = this.execution.WaitForEndEx(2000, true, null, null);
+ executionWrapper?.WaitForExit();
+ executionWrapper?.ReleaseSeqFile();
+ }
+ catch (Exception ex)
+ {
+ ViewControl.Logger.Error("Wait For Exit error.", ex);
+ //if (ex is NullReferenceException ne)
+ //{
+
+ //}
+ //else
+ //{
+ // throw ex;
+ //}
}
}
catch (Exception ex)
@@ -256,7 +286,7 @@
private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
{
- Environment.ExitCode = testApp.ExitCode;
+ //Environment.ExitCode = testApp.ExitCode;
//TSHelper.DoSynchronousGCForCOMObjectDestruction();
}
@@ -286,7 +316,11 @@
if (MethodCode == 0)
{
/// 璁剧疆鍙ユ焺
- this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+ //this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+ if (executionWrapper is TsExecutionWrapper tsWrapper)
+ {
+ tsWrapper.context = (SequenceContext)e.uiMsg.ActiveXData;
+ }
return;
}
@@ -425,6 +459,7 @@
int ovenIndex = int.Parse(datas_10015[0]);
int cellIndex = int.Parse(datas_10015[1]);
tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo();
+ //GC.Collect();
return;
}
if (MethodCode == 12)
@@ -550,11 +585,13 @@
int index = int.Parse(datas[0]);
if (MsgBoxHelper2.WarnChoose(datas[1], "鎻愮ず") == MessageBoxResult.OK)
{
- SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 1);
+ executionWrapper.SetStationGlobalValue<int>($"StationState.Pipe[{index}]", 1, 1);
+ //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 1);
}
else
{
- SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 0);
+ executionWrapper.SetStationGlobalValue<int>($"StationState.Pipe[{index}]", 1, 0);
+ //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 0);
}
return;
}
@@ -567,20 +604,34 @@
public void SetStartFlag(int index, bool data)
{
- if (this.SequenceContext == null) return;
string name = tables[index].title;
+ ViewControl.Logger?.Info($"灏嗚�佸寲鐐塠{name}] 鐨凷tart鍙橀噺璁剧疆涓� {data};");
string key = $"StationState.Start[{index}]";
- this.engine.Globals.SetValBoolean(key, 1, data);
- //bool val = this.engine.Globals.GetValBoolean(key, 0);
- //this.SequenceContext.StationGlobals.SetValBoolean(key, 0, data);
- //bool val = this.SequenceContext.StationGlobals.GetValBoolean(key, 0);
+
+ executionWrapper?.SetStationGlobalValue<bool>(key, 1, data);
+
+ if (data == false)
+ {
+ key = $"StationState.Scanner[{index}]";
+ executionWrapper?.SetStationGlobalValue<bool>(key, 1, false);
+ }
+ }
+
+ public bool? GetStartFlag(int index)
+ {
+ string key = $"StationState.Start[{index}]";
+ return executionWrapper.GetStationGlobalValue<bool>(key, 0);
}
public void ReleaseResource()
{
- testApp.ExitApplication -= this.axApplicationMgr_ExitApplication;
- testApp.UIMessageEvent -= this.axApplicationMgr_UIMessageEvent;
- testApp.ExecutionClosed -= this.axApplicationMgr_ExecutionClosed;
+ if (executionWrapper is TsExecutionWrapper tsWrapper)
+ {
+ tsWrapper.AxApplicationMgr.ExitApplication -= this.axApplicationMgr_ExitApplication;
+ tsWrapper.AxApplicationMgr.UIMessageEvent -= this.axApplicationMgr_UIMessageEvent;
+ tsWrapper.AxApplicationMgr.ExecutionClosed -= this.axApplicationMgr_ExecutionClosed;
+ }
+
foreach (var table in tables)
{
table.RelaseResource();
@@ -611,9 +662,10 @@
for (int i = 0; i < tables.Length; i++)
{
var table = tables[i];
- // table.SetCurrentProduct(currentProduct);
string LookupStr = $"StationState.Model[{i}]";
- string tableModel = engine?.Globals?.GetValString(LookupStr, 1);
+
+ string tableModel = executionWrapper?.GetStationGlobalValue<string>(LookupStr, 1);
+ //engine?.Globals?.GetValString(LookupStr, 1);
table.SetCurrentProduct(tableModel);
}
}
@@ -621,8 +673,12 @@
public void SetOvenProduct(int index, string product)
{
string LookupStr = $"StationState.Model[{index}]";
- engine?.Globals?.SetValString(LookupStr, 1, product);
- engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ executionWrapper?.SetStationGlobalValue<string>(LookupStr, 1, product);
+ executionWrapper?.CommitToDisk(false);
+ }
+
+ public void RefreshProducts()
+ {
}
}
}
diff --git a/Plugin.TestResult/Util/PNUtil.cs b/Plugin.TestResult/Util/PNUtil.cs
index 0b80a8b..d7bf7ec 100644
--- a/Plugin.TestResult/Util/PNUtil.cs
+++ b/Plugin.TestResult/Util/PNUtil.cs
@@ -1,4 +1,7 @@
锘縰sing HMI.Core.Util;
+using log4net;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using Plugin.TestResult_WPF;
using System;
using System.Net.Http;
@@ -15,13 +18,14 @@
public class PNUtil
{
- public static bool GetPN(string mesAddress, string sn, out string pn, out string msg)
+ public static bool GetPN(string mesAddress, string stationName, string sn, out string pn, out string msg)
{
pn = null;
msg = string.Empty;
try
{
- string json = $"{{\"csn\":\"{sn}\",\"station_name\":\"OP170Burn-In鑰佸寲\"}}";
+ //OP170Burn-In鑰佸寲
+ string json = $"{{\"csn\":\"{sn}\",\"station_name\":\"{stationName}\"}}";
HttpClient val = new HttpClient();
ViewControl.Logger.Debug($"Get PN Send: [{json}]");
try
@@ -52,5 +56,53 @@
return false;
}
}
+
+
+ public static bool CheckIn(ILog log, string mesAddress, string stationName, string sn, out bool needCheckIn, out string msg)
+ {
+ JObject data = new JObject();
+ data.Add("cmd", "QUERY_RECORD");
+ data.Add("p", "UOP");
+
+ data.Add("sn", sn);
+ data.Add("station_name", stationName);
+ data.Add("op", "A0000001");
+
+ needCheckIn = false;
+ msg = string.Empty;
+ string sendData = string.Empty;
+ string resData = null;
+ try
+ {
+ sendData = data.ToString(Formatting.None);
+ using (HttpClient val = new HttpClient())
+ {
+ StringContent val2 = new StringContent(sendData, Encoding.UTF8, "application/json");
+ HttpResponseMessage result = val.PostAsync("http://" + mesAddress + "/mes-module-system-2.1.1/lixun/api/checkIn", (HttpContent)(object)val2).Result;
+ result.EnsureSuccessStatusCode();
+ resData = result.Content.ReadAsStringAsync().Result;
+ JObject httpResult = JObject.Parse(resData);
+
+ log.Info("CheckIn Send: " + httpResult.Value<string>("sendStr"));
+ log.Info("CheckIn Receive: " + httpResult.Value<string>("receiveStr"));
+ log.Info("CheckIn Get: " + resData);
+
+ msg = httpResult.Value<string>("msg");
+ if (httpResult.Value<int>("code") == 200)
+ {
+ needCheckIn = httpResult.Value<bool>("needCheckIn");
+ return true;
+ }
+ log.Error("CheckIn Error: " + msg);
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message + " in " + ex.StackTrace + ".SendStr: " + sendData + ",ResultStr: " + resData;
+ log.Error("CheckIn Unknow Error: " + msg);
+ return false;
+ }
+ }
}
}
diff --git a/Plugin.TestResult/ViewControl.xaml b/Plugin.TestResult/ViewControl.xaml
index 27fb5e6..0b2de18 100644
--- a/Plugin.TestResult/ViewControl.xaml
+++ b/Plugin.TestResult/ViewControl.xaml
@@ -41,11 +41,24 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>-->
<local:TestResultView x:Name="testResultView" Grid.Row="1" Grid.Column="0" Loaded="testResultView_Loaded" />
- <DockPanel Margin="10,0" Grid.Row="0" Grid.Column="1" Background="#FFF" VerticalAlignment="Center">
+ <DockPanel Margin="10,0" Grid.Row="0" Grid.Column="1" LastChildFill="False" Background="#FFF" VerticalAlignment="Center">
<pu:FormGroup DockPanel.Dock="Right">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="20">
- <Button x:Name="btnStart" Click="Start_Click" Style="{StaticResource SuccessButton}"
- Width="100" FontSize="14" Padding="0" Height="30" Content="{DynamicResource App.Start}"/>
+ <Button x:Name="btnStart" Click="Start_Click"
+ Width="100" FontSize="14" Padding="0" Height="30" Content="{DynamicResource App.Start}">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource SuccessButton}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding EnableManualDebug}" Value="True">
+ <Setter Property="IsEnabled" Value="False"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding IsRunning}" Value="True">
+ <Setter Property="IsEnabled" Value="False"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
<Button x:Name="btnStop" Click="Stop_Click" Style="{StaticResource DangerButton}"
Width="100" FontSize="14" Padding="0" Height="30"
@@ -83,6 +96,13 @@
ValueChanged="StdEnableMes_ValueChanged"/>
</pu:FormGroup>
+ <pu:FormGroup x:Name="FgEnableManualDebug" Visibility="Collapsed">
+ <CheckBox FontSize="20"
+ IsChecked="{Binding EnableManualDebug,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ VerticalContentAlignment="Center"
+ Content="鎵嬪姩璋冭瘯" />
+ </pu:FormGroup>
+
<!--<pu:FormGroup Header="{DynamicResource Tr.Status}" FontSize="16">
<StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
diff --git a/Plugin.TestResult/ViewControl.xaml.cs b/Plugin.TestResult/ViewControl.xaml.cs
index 47d1fe5..d7e2f96 100644
--- a/Plugin.TestResult/ViewControl.xaml.cs
+++ b/Plugin.TestResult/ViewControl.xaml.cs
@@ -4,6 +4,7 @@
using HMI.Core.Manager;
using HMI.Core.Setting;
using HMI.Core.Util;
+using HMI.LogUtil;
using HMI.StdControl;
using HMI.UI.Util;
using log4net;
@@ -11,6 +12,7 @@
using NationalInstruments.TestStand.Interop.UI.Ax;
using PLCHelper;
using Plugin.TestResult.Util;
+using Plugin.TsSupport;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -25,10 +27,6 @@
/// </summary>
public partial class ViewControl : PluginMaskControl, IAlarmHandler
{
- /// <summary>
- /// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
- /// </summary>
- private SequenceContext SequenceContext = null;
private System.Timers.Timer timer;
@@ -59,6 +57,22 @@
set => Set(ref _fileName, value);
}
+ private bool enableManualDebug;
+ public bool EnableManualDebug
+ {
+ get => enableManualDebug;
+ set
+ {
+ if (IsRunning)
+ {
+ MsgBoxHelper2.Warn("璇峰厛缁撴潫鑷姩娴嬭瘯");
+ return;
+ }
+ testResultView.inManualDebugMode = value;
+ Set(ref enableManualDebug, value);
+ }
+ }
+
public override void SetLogger(ILog logger)
{
base.SetLogger(logger);
@@ -74,13 +88,20 @@
Set(ref isRunning, value);
testResultView.IsRunning = value;
this.modelSelect.IsEnabled = !value;
- this.btnStart.IsEnabled = !value;
this.btnStop.IsEnabled = value;
stdEnableMes.CbEnabled = !value;
}
}
private bool AutoExecuteSeq = true;
+
+ #region TS鐩稿叧
+
+ /// <summary>
+ /// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
+ /// </summary>
+ private SequenceContext SequenceContext = null;
+ #endregion
public ViewControl()
{
@@ -90,9 +111,18 @@
timer.Interval = 1000;
timer.Elapsed += Timer_Elapsed;
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);
+
+ if (testResultView.executionWrapper is TsExecutionWrapper tsWrapper)
+ {
+ tsWrapper.AxApplicationMgr.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
+ tsWrapper.AxApplicationMgr.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
+ tsWrapper.AxApplicationMgr.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
+ }
+
+
+ //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 Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
@@ -144,26 +174,35 @@
testResultView.testSeqFile = string.Empty;
FileName = string.Empty;
}
+ RefreshUIConfig();
}
- public override void DoClose(object sender, EventArgs e)
+ /// <summary>
+ /// 鍒锋柊UI閰嶇疆
+ /// </summary>
+ private void RefreshUIConfig()
{
try
{
- timer?.Stop();
- testResultView.ReleaseResource();
+ /// 杩愯涓氨涓嶇
+ if (IsRunning)
+ {
+ return;
+ }
+ bool enableManualDebug = ParameterManager.GetCommonParameterByName("EnableManualDebug", false);
+ if (enableManualDebug)
+ {
+ FgEnableManualDebug.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ FgEnableManualDebug.Visibility = Visibility.Collapsed;
+ EnableManualDebug = false;
+ }
}
- catch
+ catch (Exception ex)
{
- }
- }
-
- public override void OnClose(object sender, CancelEventArgs e)
- {
- if (IsRunning)
- {
- MsgBoxHelper2.Warn("璇峰厛鍋滄鑰佸寲娴嬭瘯锛�");
- e.Cancel = true;
+ log.Error("RefreshUIConfig Error.", ex);
}
}
@@ -265,18 +304,20 @@
productSource.Add(prd.Name);
}
testResultView.SetProductSource(productSource);
+ testResultView.SetCurrentProduct(null);
- string model = testResultView.engine.Globals.GetValString("ProductModel", 1);
- if (!string.IsNullOrEmpty(model))
- {
- this.modelSelect.SelectedItem = model;
- testResultView.SetCurrentProduct(model);
- }
- else if (products.Count > 0)
- {
- this.modelSelect.SelectedIndex = 0;
- testResultView.SetCurrentProduct(products[0].Name);
- }
+ //string model = testResultView.executionWrapper.GetStationGlobalValue<string>("ProductModel", 1);
+ ////testResultView.engine.Globals.GetValString("ProductModel", 1);
+ //if (!string.IsNullOrEmpty(model))
+ //{
+ // this.modelSelect.SelectedItem = model;
+ // testResultView.SetCurrentProduct(model);
+ //}
+ //else if (products.Count > 0)
+ //{
+ // this.modelSelect.SelectedIndex = 0;
+ // testResultView.SetCurrentProduct(products[0].Name);
+ //}
}
private void modelSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -285,8 +326,12 @@
{
string currentModel = this.modelSelect.SelectedItem.ToString();
List<ParameterData> parameters = ProductManager.GetParametersByProductName(currentModel);
- testResultView.engine.Globals.SetValString("ProductModel", 0, currentModel);
- testResultView.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+
+ testResultView.executionWrapper.SetStationGlobalValue<string>("ProductModel", 0, currentModel);
+ testResultView.executionWrapper.CommitToDisk(false);
+
+ //testResultView.engine.Globals.SetValString("ProductModel", 0, currentModel);
+ //testResultView.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
}
catch (Exception ex)
{
@@ -304,6 +349,8 @@
IsRunning = false;
return;
}
+ LogHelper.Info("UI", "鎬诲惎鍔ㄦ寜閽寜涓�", out _);
+ log.Info("鎬诲惎鍔ㄦ寜閽寜涓�");
ShowMask(() =>
{
testResultView.StartTestSequence();
@@ -332,7 +379,30 @@
{
try
{
+ bool breakStop = false;
+ foreach (var oven in TestResultView.tables)
+ {
+ if (oven.IsTesting)
+ {
+ breakStop = true;
+ break;
+ }
+ }
+ if (breakStop)
+ {
+ MsgBoxHelper2.Warn(this.lang("Tr.OvenIsTesting"));
+ return;
+ }
+
+ if (MsgBoxHelper2.WarnChoose(this.lang("Tr.MakeSureStopAllTest")) != MessageBoxResult.OK)
+ {
+ return;
+ }
+
+ LogHelper.Info("UI", "鎬诲仠姝㈡寜閽寜涓�", out _);
+ log.Info("鎬诲仠姝㈡寜閽寜涓�");
testResultView.StopTest();
+ /// 宸茬粡鍔犱簡WaitForExit,杩欓噷鍙互鏀逛负false
IsRunning = false;
}
catch (Exception ex)
@@ -368,13 +438,15 @@
private void StdEnableMes_ValueChanged(object sender, StdUIEventArg e)
{
- testResultView.SequenceContext?.StationGlobals.SetValBoolean($"SystemSetting.{e.StringValue}", 1, e.BoolValue);
+ testResultView.executionWrapper.SetStationGlobalValue<bool>($"SystemSetting.{e.StringValue}", 1, e.BoolValue);
+ //testResultView.SequenceContext?.StationGlobals.SetValBoolean($"SystemSetting.{e.StringValue}", 1, e.BoolValue);
}
public void HandleAlarm(AlarmText alarm)
{
if (alarm.Level >= 4 && TestResultView.tables != null)
{
+ log.Info($"4绾ф姤璀﹁Е鍙�: [{alarm.AlarmInfo}],灏嗗仠姝㈡墍鏈夌倝浣撴祴璇�");
foreach (var oven in TestResultView.tables)
{
testResultView.SetStartFlag(oven.index, false);
@@ -398,8 +470,37 @@
if (alarm.Level >= 3)
{
/// 3绾т互涓婄殑鎶ヨ浼氬仠姝㈡祴璇�
+ log.Info($"3绾ф姤璀﹁Е鍙�: [{alarm.AlarmInfo}],灏嗗仠姝㈣�佸寲鐐塠{targetOven.title}]娴嬭瘯");
testResultView.SetStartFlag(targetOven.index, false);
}
}
+
+ public override void Active()
+ {
+ base.Active();
+ LoadProduct();
+ RefreshUIConfig();
+ }
+
+ public override void OnClose(object sender, CancelEventArgs e)
+ {
+ if (IsRunning)
+ {
+ MsgBoxHelper2.Warn("璇峰厛鍋滄鑰佸寲娴嬭瘯锛�");
+ e.Cancel = true;
+ }
+ }
+
+ public override void DoClose(object sender, EventArgs e)
+ {
+ try
+ {
+ timer?.Stop();
+ testResultView.ReleaseResource();
+ }
+ catch
+ {
+ }
+ }
}
}
diff --git a/Plugin.TestResult/app.config b/Plugin.TestResult/app.config
deleted file mode 100644
index 2a0b690..0000000
--- a/Plugin.TestResult/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion="3.0.4.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
-</configuration>
\ No newline at end of file
diff --git a/Plugin.TestResult/packages.config b/Plugin.TestResult/packages.config
index 6b259f1..d8df014 100644
--- a/Plugin.TestResult/packages.config
+++ b/Plugin.TestResult/packages.config
@@ -9,6 +9,7 @@
<package id="LiveChartsCore.SkiaSharpView.WPF" version="2.0.0-rc5.4" targetFramework="net472" />
<package id="log4net" version="3.0.4" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net472" />
+ <package id="Newtonsoft.Json" version="13.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="Panuon.WPF" version="1.1.3" targetFramework="net472" />
diff --git a/Plugin.TsExecution/Plugin.TsExecution.csproj b/Plugin.TsExecution/Plugin.TsExecution.csproj
index cfce9b3..ef4aad0 100644
--- a/Plugin.TsExecution/Plugin.TsExecution.csproj
+++ b/Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -156,6 +156,18 @@
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
+ <Page Include="ScreenGrid.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="ScreenTouch.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="ScreenTouchWin.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="WorkOrderWin.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -173,6 +185,15 @@
<SubType>Designer</SubType>
</Page>
<Compile Include="Entity\TestStep.cs" />
+ <Compile Include="ScreenGrid.xaml.cs">
+ <DependentUpon>ScreenGrid.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="ScreenTouch.xaml.cs">
+ <DependentUpon>ScreenTouch.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="ScreenTouchWin.xaml.cs">
+ <DependentUpon>ScreenTouchWin.xaml</DependentUpon>
+ </Compile>
<Compile Include="WorkOrderWin.xaml.cs">
<DependentUpon>WorkOrderWin.xaml</DependentUpon>
</Compile>
diff --git a/Plugin.TsExecution/Properties/AssemblyInfo.cs b/Plugin.TsExecution/Properties/AssemblyInfo.cs
index 7fb240e..8c79373 100644
--- a/Plugin.TsExecution/Properties/AssemblyInfo.cs
+++ b/Plugin.TsExecution/Properties/AssemblyInfo.cs
@@ -49,6 +49,6 @@
// 鐢熸垚鍙�
// 淇鍙�
//
-[assembly: AssemblyVersion("1.0.0.2")]
-[assembly: AssemblyFileVersion("1.0.0.2")]
+[assembly: AssemblyVersion("1.0.0.3")]
+[assembly: AssemblyFileVersion("1.0.0.3")]
[assembly: PluginClassName("Plugin.TsExecution.TsExecution")]
diff --git a/Plugin.TsExecution/ScreenGrid.xaml b/Plugin.TsExecution/ScreenGrid.xaml
new file mode 100644
index 0000000..ff9f9f5
--- /dev/null
+++ b/Plugin.TsExecution/ScreenGrid.xaml
@@ -0,0 +1,15 @@
+锘�<hb:NotifyControl x:Class="Plugin.TsExecution.ScreenGrid"
+ 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.TsExecution"
+ mc:Ignorable="d"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ Background="LightGray" Padding="0" Margin="0"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid x:Name="grid" dp:GridHelper.Space="2" Margin="0">
+
+ </Grid>
+</hb:NotifyControl>
diff --git a/Plugin.TsExecution/ScreenGrid.xaml.cs b/Plugin.TsExecution/ScreenGrid.xaml.cs
new file mode 100644
index 0000000..6409d77
--- /dev/null
+++ b/Plugin.TsExecution/ScreenGrid.xaml.cs
@@ -0,0 +1,45 @@
+锘縰sing HMI.Base;
+using HMI.UI.DpUtil;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.TsExecution
+{
+ public class ScreenGridConfig
+ {
+ public int rows { get; set; }
+ public int columns { get; set; }
+ public ObservableCollection<bool> values { get; set; }
+ }
+
+ /// <summary>
+ /// ScreenTouch.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ScreenGrid : NotifyControl
+ {
+ public ScreenGrid(int rows, int columns)
+ {
+ InitializeComponent();
+
+ for (int i = 0; i < rows; i++)
+ {
+ grid.RowDefinitions.Add(new RowDefinition());
+ }
+
+ for (int i = 0; i < columns; i++)
+ {
+ grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto});
+ }
+ }
+
+ public void AddScreen(ScreenTouch screen, int row, int col)
+ {
+ grid.Children.Add(screen);
+ Grid.SetRow(screen, row);
+ Grid.SetColumn(screen, col);
+
+ GridHelper.RefreshGridSpace(grid);
+ }
+ }
+}
diff --git a/Plugin.TsExecution/ScreenTouch.xaml b/Plugin.TsExecution/ScreenTouch.xaml
new file mode 100644
index 0000000..f5ee1f2
--- /dev/null
+++ b/Plugin.TsExecution/ScreenTouch.xaml
@@ -0,0 +1,14 @@
+锘�<hb:NotifyControl x:Class="Plugin.TsExecution.ScreenTouch"
+ 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.TsExecution"
+ mc:Ignorable="d"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UniformGrid x:Name="uniform" dp:UniformGridHelper.InnerBorder="0.3" Background="LightGray"
+ dp:UniformGridHelper.InnerBorderBrush="Transparent">
+ </UniformGrid>
+</hb:NotifyControl>
diff --git a/Plugin.TsExecution/ScreenTouch.xaml.cs b/Plugin.TsExecution/ScreenTouch.xaml.cs
new file mode 100644
index 0000000..4145554
--- /dev/null
+++ b/Plugin.TsExecution/ScreenTouch.xaml.cs
@@ -0,0 +1,156 @@
+锘縰sing HMI.Base;
+using System;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace Plugin.TsExecution
+{
+ public class ColorConverter : IMultiValueConverter
+ {
+ public static ColorConverter Instance = new ColorConverter();
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values[0] is ObservableCollection<string> list && values[1] is string tag)
+ {
+ if (list?.Contains(tag) == true) return Brushes.Green;
+ return Brushes.White;
+ }
+ return values;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// ScreenTouch.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ScreenTouch : NotifyControl
+ {
+ public static readonly DependencyProperty ValuesProperty = DependencyProperty.Register(
+ nameof(Values),
+ typeof(ObservableCollection<bool>),
+ typeof(ScreenTouch),
+ new PropertyMetadata(null, OnValuesChanged));
+
+ private static void OnValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is ScreenTouch control)
+ {
+ // 濡傛灉鏈夋棫鐨勯泦鍚堬紝鍙栨秷璁㈤槄
+ if (e.OldValue is ObservableCollection<bool> oldCollection)
+ {
+ oldCollection.CollectionChanged -= control.Value_CollectionChanged;
+ }
+
+ // 濡傛灉鏈夋柊鐨勯泦鍚堬紝璁㈤槄鍙樻洿浜嬩欢
+ if (e.NewValue is ObservableCollection<bool> newCollection)
+ {
+ newCollection.CollectionChanged += control.Value_CollectionChanged;
+ }
+
+ // 鍒锋柊鎵�鏈夊崟鍏冩牸
+ control.PaintPoints();
+ }
+ }
+
+
+ public ScreenTouch(int rows, int columns)
+ {
+ this.rows = rows;
+ this.columns = columns;
+ InitializeComponent();
+ Refresh();
+ Values = new ObservableCollection<bool>(new bool[rows * columns]);
+ }
+
+ public ObservableCollection<bool> Values
+ {
+ get => (ObservableCollection<bool>)GetValue(ValuesProperty);
+ set
+ {
+ SetValue(ValuesProperty, value);
+ }
+ }
+
+ private void Value_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ PaintPoints();
+ }
+
+ public int rows { get; private set; }
+ public int columns { get; private set; }
+
+ private Border[] children;
+
+ public void Refresh()
+ {
+ uniform.Children.Clear();
+ uniform.Rows = rows;
+ uniform.Columns = columns;
+
+ children = new Border[rows * columns];
+
+
+ for (int i = 0; i < children.Length; i++)
+ {
+ var border = new Border
+ {
+ BorderThickness = new Thickness(0),
+ Background = Brushes.White
+ };
+ children[i] = border;
+ uniform.Children.Add(border);
+ }
+ }
+
+ public void Refresh(int rows, int columns)
+ {
+ this.rows = rows;
+ this.columns = columns;
+ Refresh();
+ }
+
+ public void Clear()
+ {
+ Values = new ObservableCollection<bool>(new bool[rows * columns]);
+ }
+
+ public void DrawPoint(int x, int y)
+ {
+ Values[y * columns + x] = true;
+ }
+
+ public void DrawPoints(int[][] points)
+ {
+ var temp = new ObservableCollection<bool>(new bool[rows * columns]);
+ foreach (int[] point in points)
+ {
+ //children[point[0]][point[1]].Background = Brushes.Green;
+ temp[point[1] * columns + point[0]] = true;
+ }
+ Values = temp;
+ }
+
+ private void PaintPoints()
+ {
+ for (int i = 0; i < Values.Count; i++)
+ {
+ if (Values[i])
+ {
+ children[i].Background = Brushes.Green;
+ }
+ else
+ {
+ children[i].Background = Brushes.White;
+ }
+ }
+ }
+ }
+}
diff --git a/Plugin.TsExecution/ScreenTouchWin.xaml b/Plugin.TsExecution/ScreenTouchWin.xaml
new file mode 100644
index 0000000..cd99df0
--- /dev/null
+++ b/Plugin.TsExecution/ScreenTouchWin.xaml
@@ -0,0 +1,20 @@
+锘�<pu:WindowX x:Class="Plugin.TsExecution.ScreenTouchWin"
+ 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.TsExecution"
+ mc:Ignorable="d"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ SizeChanged="Window_SizeChanged"
+ Style="{StaticResource ModalWindow}"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ WindowStartupLocation="CenterScreen"
+ WindowState="Maximized"
+ Background="LightGray"
+ Title="Screens" Height="450" Width="800">
+ <Grid x:Name="grid" HorizontalAlignment="Center">
+
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.TsExecution/ScreenTouchWin.xaml.cs b/Plugin.TsExecution/ScreenTouchWin.xaml.cs
new file mode 100644
index 0000000..b4f2c7d
--- /dev/null
+++ b/Plugin.TsExecution/ScreenTouchWin.xaml.cs
@@ -0,0 +1,67 @@
+锘縰sing Panuon.WPF.UI;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+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.TsExecution
+{
+ /// <summary>
+ /// ScreenTouchWin.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ScreenTouchWin : WindowX
+ {
+ private ScreenGrid screenGrid;
+ private ScreenTouch[] screens;
+
+ public ScreenTouchWin(ScreenTouch[] configs)
+ {
+ screenGrid = new ScreenGrid(1, configs.Length);
+ screens = new ScreenTouch[configs.Length];
+ InitializeComponent();
+
+ int space = 2 * (screens.Length + 1);
+ for (int i = 0; i < screens.Length; i++)
+ {
+ var screen = new ScreenTouch(configs[i].rows, configs[i].columns)
+ {
+ Width = Math.Max(Math.Floor((this.ActualHeight / 9 * 16 - space) / screens.Length), 0),
+ Height = Math.Max(Math.Floor((this.ActualHeight / 9 * 16 - space) / screens.Length / 16 * 9), 0)
+ };
+
+ screen.SetBinding(ScreenTouch.ValuesProperty, new Binding(nameof(ScreenTouch.Values)) { Source = configs[i], Mode = BindingMode.OneWay });
+
+ screens[i] = screen;
+ screenGrid.AddScreen(screen, 0, i);
+ }
+
+ grid.Children.Add(screenGrid);
+ }
+
+ private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if (screenGrid == null)
+ {
+ return;
+ }
+ int space = 2 * (screens.Length + 1);
+
+ for (int i = 0; i < screens.Length; i++)
+ {
+ var screen = screens[i];
+ screen.Width = Math.Max(Math.Floor((this.ActualHeight / 9 * 16 - space) / screens.Length), 0);
+ screen.Height = Math.Max(Math.Floor((this.ActualHeight / 9 * 16 - space) / screens.Length / 16 * 9), 0);
+ }
+ }
+ }
+}
diff --git a/Plugin.TsExecution/SingleControl.xaml b/Plugin.TsExecution/SingleControl.xaml
index 905a810..8a31373 100644
--- a/Plugin.TsExecution/SingleControl.xaml
+++ b/Plugin.TsExecution/SingleControl.xaml
@@ -15,6 +15,7 @@
FontSize="{Binding ActualHeight,RelativeSource={RelativeSource AncestorType=UserControl},
Converter={StaticResource hfc}, ConverterParameter='12,816'}"
x:Name="control"
+ SizeChanged="control_SizeChanged"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
@@ -51,21 +52,20 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
- <Grid dp:GridHelper.InnerBorder="1" dp:GridHelper.Space="2"
+ <Grid dp:GridHelper.InnerBorder="1" dp:GridHelper.Space="2" x:Name="tableHeader"
dp:GridHelper.InnerBorderBrush="{DynamicResource CommonBoarder}">
<Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
- <ColumnDefinition/>
+ <ColumnDefinition />
+ <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.RowSpan="3">
<StackPanel.Style>
<Style TargetType="StackPanel">
- <Setter Property="Background" Value="DeepSkyBlue"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Passed">
<Setter Property="Background" Value="{StaticResource passedColor}"/>
@@ -89,6 +89,7 @@
<Label>
<Label.Style>
<Style TargetType="Label">
+ <Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Padding" Value="10,10,10,0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="FontFamily" Value="{StaticResource iconfont}"/>
@@ -123,7 +124,7 @@
</Label.Style>
</Label>
- <Label Content="{Binding Status}" VerticalContentAlignment="Center"
+ <Label Content="{Binding Status}" VerticalAlignment="Center" VerticalContentAlignment="Center"
Padding="0"
Margin="0"
HorizontalContentAlignment="Center"
@@ -135,7 +136,7 @@
<!--<Label HorizontalContentAlignment="Left" Grid.Column="1" Content="{Binding Status}"/>-->
- <Label Style="{StaticResource baseLabel}" Background="#FFF" Grid.Row="1" Grid.Column="1">
+ <Label Style="{StaticResource baseLabel}" Background="#FFF" Grid.Row="0" Grid.Column="1">
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource baseText}" Text="{DynamicResource Ts.Total}"/>
<TextBlock Style="{StaticResource baseText}" Margin="2,0,18,0" Text="{Binding TotalNum}"/>
@@ -150,7 +151,7 @@
</StackPanel>
</Label>
- <Label Style="{StaticResource baseLabel}" Background="#FFF" Grid.Row="2" Grid.Column="1">
+ <Label Style="{StaticResource baseLabel}" Background="#FFF" Grid.Row="1" Grid.Column="1">
<StackPanel Orientation="Horizontal">
<Label Style="{StaticResource baseLabel}" Content="{DynamicResource Ts.CurrentSnr}"/>
<Label Style="{StaticResource baseLabel}" Margin="2,0,18,0" Content="{Binding Barcode}"/>
@@ -158,6 +159,9 @@
<Label Style="{StaticResource baseLabel}" Margin="2,0,18,0" Content="{Binding ElapseTime}"/>
</StackPanel>
</Label>
+ <Border x:Name="screenContainer" BorderThickness="0" Grid.Column="2" Grid.RowSpan="2" MouseLeftButtonDown="screenContainer_MouseLeftButtonDown">
+
+ </Border>
</Grid>
<Grid Grid.Row="2" x:Name="simplePanel" dp:GridHelper.Space="2" dp:GridHelper.SpaceIgnore="TOP">
@@ -337,7 +341,12 @@
</ListView.View>
</ListView>-->
- <DataGrid Grid.Row="0" Style="{StaticResource DefaultDataGrid}" Margin="2,0,2,2"
+
+
+ <Canvas Grid.Row="0" x:Name="canvas" Background="Transparent">
+ <DataGrid Canvas.Left="0" Canvas.Top="0" Height="{Binding ActualHeight,ElementName=canvas}"
+ Width="{Binding ActualWidth,ElementName=canvas}"
+ Style="{StaticResource DefaultDataGrid}" Margin="2,0,2,2"
FontSize="{DynamicResource tableFontSize}"
dp:DataGridHelper.ShowRowNumber="True"
VirtualizingPanel.IsContainerVirtualizable="True"
@@ -346,74 +355,75 @@
RowHeight="{StaticResource nanD}"
ColumnHeaderHeight="{Binding ActualWidth,ElementName=control,
Converter={StaticResource fc}, ConverterParameter='32,1093,30,45'}"
- HorizontalScrollBarVisibility="Disabled"
+ HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Datasource}" x:Name="table">
- <DataGrid.Columns>
- <DataGridTextColumn Header="#"
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="#"
ElementStyle="{StaticResource TableTextBlock}"
Binding="{Binding Header, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}, Mode=FindAncestor}}"
Width="0.4*"/>
- <DataGridTextColumn Width="2.5*" Binding="{Binding Name}"
+ <DataGridTextColumn Width="2.5*" Binding="{Binding Name}"
ElementStyle="{StaticResource TableTextBlock}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Test.Name}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="0.8*" Binding="{Binding Unit}"
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Name}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="0.8*" Binding="{Binding Unit}"
ElementStyle="{StaticResource TableTextBlock}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Test.Unit}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="2*" Binding="{Binding Value}"
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Unit}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="2*" Binding="{Binding Value}"
ElementStyle="{StaticResource TableTextBlock}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Test.Value}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="1.5*" Binding="{Binding LimitDown}"
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Value}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="1.5*" Binding="{Binding LimitDown}"
ElementStyle="{StaticResource TableTextBlock}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Test.LimitDown}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="1.5*" Binding="{Binding LimitUp}"
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.LimitDown}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="1.5*" Binding="{Binding LimitUp}"
ElementStyle="{StaticResource TableTextBlock}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Test.LimitUp}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTextColumn Width="0.6*" Binding="{Binding ConsumeTime}"
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.LimitUp}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Width="0.6*" Binding="{Binding ConsumeTime}"
ElementStyle="{StaticResource TableTextBlock}">
- <DataGridTextColumn.Header>
- <TextBlock Text="{DynamicResource Test.ConsumeTime}"/>
- </DataGridTextColumn.Header>
- </DataGridTextColumn>
- <DataGridTemplateColumn Width="1*">
- <DataGridTemplateColumn.Header>
- <TextBlock Text="{DynamicResource Test.Result}"/>
- </DataGridTemplateColumn.Header>
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <Grid x:Name="border" Margin="0">
- <TextBlock x:Name="text" Margin="-1" Padding="0" VerticalAlignment="Center" Text="{Binding Result}"/>
- </Grid>
- <DataTemplate.Triggers>
- <DataTrigger Binding="{Binding Result}" Value="Passed">
- <Setter TargetName="border" Property="Background" Value="{StaticResource passedColor}"/>
- <Setter TargetName="text" Property="Foreground" Value="#000"/>
- </DataTrigger>
- <DataTrigger Binding="{Binding Result}" Value="Failed">
- <Setter TargetName="border" Property="Background" Value="{DynamicResource DangerColor}"/>
- <Setter TargetName="text" Property="Foreground" Value="#000"/>
- </DataTrigger>
- </DataTemplate.Triggers>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- </DataGrid.Columns>
- </DataGrid>
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.ConsumeTime}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTemplateColumn Width="1*">
+ <DataGridTemplateColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Result}"/>
+ </DataGridTemplateColumn.Header>
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <Grid x:Name="border" Margin="0">
+ <TextBlock x:Name="text" Margin="-1" Padding="0" VerticalAlignment="Center" Text="{Binding Result}"/>
+ </Grid>
+ <DataTemplate.Triggers>
+ <DataTrigger Binding="{Binding Result}" Value="Passed">
+ <Setter TargetName="border" Property="Background" Value="{StaticResource passedColor}"/>
+ <Setter TargetName="text" Property="Foreground" Value="#000"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Result}" Value="Failed">
+ <Setter TargetName="border" Property="Background" Value="{DynamicResource DangerColor}"/>
+ <Setter TargetName="text" Property="Foreground" Value="#000"/>
+ </DataTrigger>
+ </DataTemplate.Triggers>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+ </Canvas>
<Grid Grid.Row="1" Height="20" Margin="0">
<ProgressBar Grid.Row="3" x:Name="testProcess" Value="{Binding ProcessValue}"/>
@@ -424,7 +434,8 @@
<Grid Background="#f1eded" Grid.Row="2" Height="25">
<DockPanel>
- <Label Padding="0" FontSize="12" VerticalContentAlignment="Center" Content="{Binding CurrentStep}"/>
+ <Label Margin="10,0,0,0" Padding="0" FontSize="16" VerticalContentAlignment="Center" Content="{Binding SocketName}"/>
+ <Label Margin="20,0,0,0" Padding="0" FontSize="14" VerticalContentAlignment="Center" Content="{Binding CurrentStep}"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" Margin="0,0,5,0">
<!--<Button FontSize="12" x:Name="scannerSetting"
diff --git a/Plugin.TsExecution/SingleControl.xaml.cs b/Plugin.TsExecution/SingleControl.xaml.cs
index e0bbebe..3e3c21a 100644
--- a/Plugin.TsExecution/SingleControl.xaml.cs
+++ b/Plugin.TsExecution/SingleControl.xaml.cs
@@ -1,4 +1,5 @@
-锘縰sing HMI.Core.Manager;
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Manager;
using HMI.Core.Util;
using HMI.Util;
using NationalInstruments.TestStand.Interop.API;
@@ -7,6 +8,7 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Timers;
using System.Windows;
@@ -36,11 +38,13 @@
}
}
#endregion
- private bool isLoadOK = false;
private int index;
private string CountIniPath;
private string status = "Ready";
+
+ private ScreenTouch[] screens;
+ private ScreenGrid screenGrid;
public string Status
{
@@ -127,6 +131,16 @@
Set("TestInfo");
}
}
+ }
+ }
+
+ private string socketName = string.Empty;
+ public string SocketName
+ {
+ get { return socketName; }
+ set
+ {
+ Set(ref socketName, value);
}
}
@@ -550,5 +564,117 @@
//Canvas.SetTop(modal, (scannerPanel.ActualHeight - scannerVisualModal.ActualHeight) / 2);
}
}
+
+ public void RefreshScreen(int[][] configs)
+ {
+ //foreach (UIElement item in canvas.Children)
+ //{
+ // if (item is ScreenTouch)
+ // {
+ // canvas.Children.Remove(item);
+ // }
+ //}
+ screenContainer.Child = null;
+
+
+ screenGrid = new ScreenGrid(1, configs.Length);
+
+ screens = new ScreenTouch[configs.Length];
+
+ int space = 2 * (screens.Length + 1);
+ for (int i = 0; i < configs.Length; i++)
+ {
+ var screen = new ScreenTouch(configs[i][0], configs[i][1])
+ {
+ Width = Math.Max((tableHeader.ActualHeight / 9 * 16 - space) / screens.Length, 0),
+ Height = Math.Max((tableHeader.ActualHeight / 9 * 16 - space) / screens.Length / 16 * 9, 0)
+ };
+ screens[i] = screen;
+ screenGrid.AddScreen(screen, 0, i);
+ }
+ screenContainer.Child = screenGrid;
+
+ //canvas.Children.Add(screens[0]);
+ //Canvas.SetBottom(screens[0], 0);
+ //Canvas.SetRight(screens[0], 0);
+ //Panel.SetZIndex(screens[0], 999);
+ }
+
+ public void DrawScreenPoint(int index, int x, int y)
+ {
+ screens[index].DrawPoint(x, y);
+ }
+
+ public void DrawScreenPoints(int index, int[][] points)
+ {
+ screens[index].DrawPoints(points);
+ }
+
+ public void ClearScreenPoint(int index)
+ {
+ screens[index].Clear();
+ }
+
+ public void RefreshProduct(ProductData product)
+ {
+ if (product == null)
+ {
+ screenContainer.Child = null;
+ return;
+ }
+ try
+ {
+ string screenSize = ProductManager.GetParameterByProductAndName(product.Name, "ScreenTouch")?.Value;
+ if (string.IsNullOrEmpty(screenSize))
+ {
+ screenContainer.Child = null;
+ return;
+ }
+ string[] arr = screenSize.Split(';');
+ int[][] configs = new int[arr.Length][];
+
+ for (int i = 0; i < arr.Length; i++)
+ {
+ string[] size = arr[i].Split(',');
+ configs[i] = new int[2] { int.Parse(size[0]), int.Parse(size[1]) };
+ }
+ RefreshScreen(configs);
+ }
+ catch (Exception ex)
+ {
+ TsExecution.logger.Error("RefreshProduct Failed.", ex);
+ screenContainer.Child = null;
+ }
+ }
+
+ private void control_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if (screenGrid == null)
+ {
+ return;
+ }
+ //screenGrid.Height = tableHeader.ActualHeight - 2;
+ //screenGrid.Width = tableHeader.ActualHeight / 9 * 16 - 2;
+
+ int space = 2 * (screens.Length + 1);
+
+ for (int i = 0; i < screens.Length; i++)
+ {
+ var screen = screens[i];
+ screen.Width = Math.Max(Math.Floor((tableHeader.ActualHeight / 9 * 16 - space) / screens.Length), 0);
+ screen.Height = Math.Max(Math.Floor(screen.Width / 16 * 9), 0);
+ }
+ }
+
+ private void screenContainer_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (e.ClickCount == 2)
+ {
+ new ScreenTouchWin(screens)
+ {
+ Owner = Window.GetWindow(this)
+ }.ShowDialog();
+ }
+ }
}
}
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 289d5be..321bd3b 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -20,6 +20,7 @@
using System.ComponentModel;
using System.IO;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
@@ -50,6 +51,8 @@
private SequenceFile modeSeq = null;
public AxApplicationMgr AxApplicationMgr;
private Execution execution = null;
+
+ private SequenceContext sequenceContext = null;
private Chart chart;
#endregion
@@ -101,6 +104,13 @@
{
Set(ref selectedProduct, value);
CurrentProductModel = value?.Name;
+ if (tsSockets != null)
+ {
+ foreach (SingleControl socket in tsSockets)
+ {
+ socket.RefreshProduct(value);
+ }
+ }
SetTestSeqFile(value);
}
}
@@ -446,6 +456,13 @@
SelectedProduct = tempProduct;
}
RefershUI();
+ if (tsSockets != null)
+ {
+ foreach (SingleControl socket in tsSockets)
+ {
+ socket.RefreshProduct(SelectedProduct);
+ }
+ }
SampleStatus = false;
}
@@ -471,24 +488,31 @@
private void InitTsEngine()
{
AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
+
+
+ //AxApplicationMgr. += AxApplicationMgr_EndExecution;
AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
- AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
- AxApplicationMgr.UIMessageEvent +=
- new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
- AxApplicationMgr.ExecutionClosed +=
- new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
+
+ AxApplicationMgr.ExitApplication += this.AxApplicationMgr_ExitApplication;
+ AxApplicationMgr.UIMessageEvent += this.AxApplicationMgr_UIMessageEvent;
+ AxApplicationMgr.ExecutionClosed += this.AxApplicationMgr_ExecutionClosed;
((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
host.Child = AxApplicationMgr;
((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
}
+ private volatile bool canSwitchModel = false;
+ private volatile Action switchAction = null;
+
private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
{
log.Info("AxApplicationMgr_EndExecution");
if (ReleaseSequenceFile())
{
+ IsTesting = false;
log.Info("Release SeqFile Success!");
+ if (canSwitchModel) switchAction?.Invoke();
}
else
{
@@ -594,10 +618,21 @@
private void RefershUI()
{
panel.Children.Clear();
+ string[] names = ParamSetting.SocketNames.Split(',');
+
//閲嶆柊鐢熸垚瀛愰潰鏉�
for (int i = 0; i < this.socketNum; i++)
{
- SingleControl control = new SingleControl(i, CountIniPath, this.probeWarn);
+ string name = string.Empty;
+ if (i < names.Length)
+ {
+ name = names[i];
+ }
+
+ SingleControl control = new SingleControl(i, CountIniPath, this.probeWarn)
+ {
+ SocketName = name
+ };
panel.Children.Add(control);
tsSockets.Add(control);
@@ -1027,7 +1062,7 @@
private void StartSequence()
{
if (!isLoadOK) return;
-
+ engine?.Globals.SetValBoolean("StationState.StopTest", 0, false);
if (ParamSetting.EnableAutoModel)
{
try
@@ -1085,35 +1120,12 @@
public void StopSequenceClick()
{
+ canSwitchModel = false;
+ switchAction = null;
ShowMask(() =>
{
bool stoped = StopSequence();
- if (stoped)
- {
- IsTesting = false;
- }
}, null, null, LangUtil.Get("App.SequenceIsStopping"));
- //new MaskWindow((WindowX)Window.GetWindow(this),
- // (win) =>
- // {
- // try
- // {
- // bool stoped = StopSequence();
- // if (stoped)
- // {
- // IsTesting = false;
- // }
- // }
- // finally
- // {
- // Dispatcher.Invoke(() =>
- // {
-
- // win.Close();
- // });
- // }
- // }
- // ).Info(LangUtil.Get("App.SequenceIsStopping"));
}
/// <summary>
@@ -1128,18 +1140,15 @@
for (int i = 0; i < tsSockets.Count; i++)
{
var context = this.tsSockets[i].SequenceFileContext;
- //bool val = context.StationGlobals.Exists("StationState.StopTest", 0);
- //if (val)
- //{
- // context.StationGlobals.SetValBoolean("StationState.StopTest", 0, true);
- // bool isStop = this.execution.WaitForEndEx(2000, true, null, null);
- //}
context?.StationGlobals.SetValBoolean("StationState.StopTest", 1, true);
}
}
if (this.execution == null) return true;
- bool res = this.execution.WaitForEndEx(2000, true, null, null);
+ //bool res = this.execution.WaitForEndEx(-1, true, null, null);
+ bool res = this.execution?.WaitForEndEx(-1, true, Type.Missing, null) == true;
+ Marshal.ReleaseComObject(this.execution);
+ this.execution = null;
return res;
}
catch (Exception ex)
@@ -1174,6 +1183,7 @@
private void StartClick()
{
+ canSwitchModel = true;
ShowMask(() =>
{
StartSequence();
@@ -1358,7 +1368,7 @@
this.tsSockets[index].ElapseTime = strData;
break;
case (int)UIMessageCodes.UIMsg_EndExecution://鎵ц缁撴潫
- IsTesting = false;
+ //IsTesting = false;
//this.ReleaseSequenceFile();
break;
case 10030://鏄剧ず娴嬭瘯杩涘害
@@ -1405,11 +1415,75 @@
case 10034:
CurrentProductModel = strData;
break;
+ case 10035:
+ string[] arr_10035 = strData.Split(';');
+
+ int[][] points = new int[arr_10035.Length - 1][];
+
+ for (int i = 1; i < arr_10035.Length; i++)
+ {
+ string[] strs = arr_10035[i].Split(',');
+ points[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
+ }
+ this.tsSockets[index].DrawScreenPoints(int.Parse(arr_10035[0]), points);
+ break;
+ case 10036:
+ this.tsSockets[index].ClearScreenPoint(int.Parse(strData));
+ break;
case 10099:
+ string[] arr = strData.Split(',');
+ if (canSwitchModel) SwitchSequenceByModel(index, arr[0], arr[1]);
break;
default:
break;
}
+ }
+
+ private void SwitchSequenceByModel(int index, string model, string snr)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ var target = Products.FirstOrDefault(e => e.Name == model);
+
+ ShowMask(() =>
+ {
+ bool stoped = StopSequence();
+ //if (stoped)
+ //{
+ // IsTesting = false;
+ //}
+ }, null, null, "鎹㈠瀷涓紝璇风◢鍚�...");
+
+ if (target == null)
+ {
+ MsgBoxHelper2.Warn($"璇峰厛鍦ㄤ骇鍝佺鐞嗛〉闈㈤厤缃瀷鍙� [{model}] 鐨勪骇鍝佷俊鎭紒");
+ return;
+ }
+
+ switchAction = () =>
+ {
+ switchAction = null;
+ log?.Info($"灏濊瘯鑷姩鎹㈠瀷: {switchAction}");
+ if (canSwitchModel)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ try
+ {
+ log?.Info("寮�濮嬭嚜鍔ㄦ崲鍨�");
+ SelectedProduct = target;
+ engine?.Globals.SetValString($"CacheSNR[{index}]", 1, snr);
+ engine?.CommitGlobalsToDisk(false);
+ StartClick();
+ }
+ catch (Exception ex)
+ {
+ log?.Error("鑷姩鎹㈠瀷澶辫触", ex);
+ }
+ });
+ }
+ };
+ });
}
private void ShowAlarm(AlarmText alarm)
@@ -1433,7 +1507,7 @@
try
{
- log.Info($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
+ log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
}
catch
{
@@ -1441,6 +1515,8 @@
}
if (eventCode == 10001)
{
+ sequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+
tsSockets[index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
return;
}
@@ -1522,6 +1598,10 @@
{
lock (this)
{
+ if (this.testSeq == null)
+ {
+ return true;
+ }
//execution.Abort();
int count = 10;
while (count > 0)
@@ -1531,15 +1611,18 @@
if (this.testSeq == null)
return true;
- if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
+ if (this.engine?.ReleaseSequenceFileEx(this.testSeq, 4) == true)
{
+ Marshal.ReleaseComObject(this.testSeq);
this.testSeq = null;
+ // GC.Collect();
}
- if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
+ if (this.engine?.ReleaseSequenceFileEx(this.modeSeq, 4) == true)
{
+ Marshal.ReleaseComObject(this.modeSeq);
this.modeSeq = null;
}
- this.engine.UnloadAllModules();
+ this.engine?.UnloadAllModules();
return this.testSeq == null && this.modeSeq == null;
}
catch (Exception ex)
diff --git a/Plugin.TsSupport/ITestExecutionWrapper.cs b/Plugin.TsSupport/ITestExecutionWrapper.cs
new file mode 100644
index 0000000..2a80a38
--- /dev/null
+++ b/Plugin.TsSupport/ITestExecutionWrapper.cs
@@ -0,0 +1,47 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+using System;
+
+namespace Plugin.TsSupport
+{
+ public class ExecutionEndEvent
+ {
+ public object Origin { get; set; }
+ public object Data { get; set; }
+ }
+
+ public class UIMessageEvent
+ {
+ public object Origin { get; set; }
+ public object Data { get; set; }
+ public int EventCode { get; set; }
+ public double NumberData { get; set; }
+ public bool BoolData { get; set; }
+ public string StrData { get; set; }
+ }
+
+ public interface ITestExecutionWrapper
+ {
+ event EventHandler<UIMessageEvent> UIMessageEvent;
+
+ event EventHandler<ExecutionEndEvent> EndExecutionEvent;
+
+ object Init();
+
+ object StartSequence(string filePath, string modelPath);
+
+ T GetStationGlobalValue<T>(string key, int option);
+
+ T GetFileGlobalValue<T>(string key, int option);
+
+ void SetStationGlobalValue<T>(string key, int option, T value, bool inContext = false);
+
+ void SetFileGlobalValue<T>(string key, int option, T value);
+
+ void CommitToDisk(bool option);
+
+ bool WaitForExit();
+
+ bool ReleaseSeqFile();
+ void SetContext(object context);
+ }
+}
diff --git a/Plugin.TsSupport/Plugin.TsSupport.csproj b/Plugin.TsSupport/Plugin.TsSupport.csproj
index 9306243..ec9f306 100644
--- a/Plugin.TsSupport/Plugin.TsSupport.csproj
+++ b/Plugin.TsSupport/Plugin.TsSupport.csproj
@@ -87,8 +87,11 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="ITestExecutionWrapper.cs" />
<Compile Include="TestAppManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="TeststandWrapper.cs" />
+ <Compile Include="TsExecutionWrapper.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
diff --git a/Plugin.TsSupport/TeststandWrapper.cs b/Plugin.TsSupport/TeststandWrapper.cs
new file mode 100644
index 0000000..b3c7f07
--- /dev/null
+++ b/Plugin.TsSupport/TeststandWrapper.cs
@@ -0,0 +1,228 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using System;
+using System.Diagnostics;
+
+namespace Plugin.TsSupport
+{
+ public class TeststandWrapper : ITestExecutionWrapper
+ {
+ #region TestStand浜嬩欢
+ /// <summary>
+ /// TS 寮曟搸
+ /// </summary>
+ private Engine engine = null;
+
+ /// <summary>
+ /// 娴嬭瘯搴忓垪璺緞
+ /// </summary>
+ private string testSeqFile = string.Empty;
+
+ /// <summary>
+ /// 娴嬭瘯搴忓垪
+ /// </summary>
+ private SequenceFile testSeq = null;
+
+ /// <summary>
+ /// 娴嬭瘯妯″瀷搴忓垪
+ /// </summary>
+ private SequenceFile modeSeq = null;
+
+ /// <summary>
+ /// 杩愯瀹炰緥
+ /// </summary>
+ private Execution execution = null;
+
+ public SequenceContext context { get; set; } = null;
+
+ /// <summary>
+ /// 浜嬩欢绠$悊鍣�
+ /// </summary>
+ public AxApplicationMgr AxApplicationMgr { get; private set; }
+ #endregion
+
+ public event EventHandler<UIMessageEvent> UIMessageEvent;
+ public event EventHandler<ExecutionEndEvent> EndExecutionEvent;
+
+ public TeststandWrapper()
+ {
+ AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
+ AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
+ AxApplicationMgr.UIMessageEvent += AxApplicationMgr_UIMessageEvent;
+
+ //AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
+ //AxApplicationMgr.ExecutionClosed +=
+ // new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
+ }
+
+ private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+ {
+ UIMessageEvent?.Invoke(this, new UIMessageEvent()
+ {
+ Origin = e,
+ EventCode = Convert.ToInt32(e.uiMsg.Event),
+ NumberData = Convert.ToInt16(e.uiMsg.NumericData),
+ Data = e.uiMsg.ActiveXData,
+ StrData = e.uiMsg.StringData
+ });
+ }
+
+ private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
+ {
+ EndExecutionEvent?.Invoke(this, new ExecutionEndEvent() { Origin = e });
+ }
+
+ public object Init()
+ {
+ this.engine = this.AxApplicationMgr.GetEngine();
+ this.engine.PersistBreakpoints = false;
+ this.AxApplicationMgr.IsEditor = true;
+ this.AxApplicationMgr.LoginOnStart = false;
+ this.AxApplicationMgr.Start();
+ return this.AxApplicationMgr;
+ }
+
+ public object StartSequence(string filePath, string modelPath)
+ {
+ this.testSeqFile = filePath;
+
+ this.modeSeq = this.engine.GetSequenceFileEx(modelPath);
+ this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+ this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+ return execution;
+ }
+
+ public T GetFileGlobalValue<T>(string key, int option)
+ {
+ if (typeof(T) == typeof(bool))
+ {
+ return (T)(object)context?.FileGlobals?.GetValBoolean(key, option);
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ return (T)(object)context?.FileGlobals?.GetValString(key, option);
+ }
+ else if (typeof(T) == typeof(int))
+ {
+ return (T)(object)context?.FileGlobals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ return (T)(object)context?.FileGlobals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(float))
+ {
+ return (T)(object)context?.FileGlobals?.GetValNumber(key, option);
+ }
+ return default(T);
+ }
+
+ public T GetStationGlobalValue<T>(string key, int option)
+ {
+ if (typeof(T) == typeof(bool))
+ {
+ return (T)(object)engine?.Globals?.GetValBoolean(key, option);
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ return (T)(object)engine?.Globals?.GetValString(key, option);
+ }
+ else if (typeof(T) == typeof(int))
+ {
+ return (T)(object)engine?.Globals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ return (T)(object)engine?.Globals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(float))
+ {
+ return (T)(object)engine?.Globals?.GetValNumber(key, option);
+ }
+ return default(T);
+ }
+
+ public void SetFileGlobalValue<T>(string key, int option, T value)
+ {
+ if (value is bool bVal)
+ {
+ context?.FileGlobals?.SetValBoolean(key, option, bVal);
+ }
+ else if (value is string sVal)
+ {
+ context?.FileGlobals?.SetValString(key, option, sVal);
+ }
+ else if (value is int iVal)
+ {
+ context?.FileGlobals?.SetValNumber(key, option, iVal);
+ }
+ else if (value is double dVal)
+ {
+ context?.FileGlobals?.SetValNumber(key, option, dVal);
+ }
+ else if (value is float fVal)
+ {
+ context?.FileGlobals?.SetValNumber(key, option, fVal);
+ }
+ }
+
+ public void SetStationGlobalValue<T>(string key, int option, T value, bool inContext = false)
+ {
+ PropertyObject obj = null;
+ if (inContext)
+ {
+ obj = context?.StationGlobals;
+ }
+ else
+ {
+ obj = engine?.Globals;
+ }
+
+ if (value is bool bVal)
+ {
+ obj?.SetValBoolean(key, option, bVal);
+ }
+ else if (value is string sVal)
+ {
+ obj?.SetValString(key, option, sVal);
+ }
+ else if (value is int iVal)
+ {
+ obj?.SetValNumber(key, option, iVal);
+ }
+ else if (value is double dVal)
+ {
+ obj?.SetValNumber(key, option, dVal);
+ }
+ else if (value is float fVal)
+ {
+ obj?.SetValNumber(key, option, fVal);
+ }
+ //engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ }
+
+ public void CommitToDisk(bool option)
+ {
+ engine?.CommitGlobalsToDisk(option);
+ }
+
+ public bool WaitForExit()
+ {
+ return this.execution?.WaitForEndEx(-1, true, Type.Missing, null) == true;
+ }
+
+ public bool ReleaseSeqFile()
+ {
+ if (testSeq != null)
+ {
+ return engine?.ReleaseSequenceFileEx(testSeq, 4) == true;
+ }
+ return true;
+ }
+
+ public void SetContext(object context)
+ {
+ this.context = (SequenceContext)context;
+ }
+ }
+}
diff --git a/Plugin.TsSupport/TsExecutionWrapper.cs b/Plugin.TsSupport/TsExecutionWrapper.cs
new file mode 100644
index 0000000..837bc75
--- /dev/null
+++ b/Plugin.TsSupport/TsExecutionWrapper.cs
@@ -0,0 +1,214 @@
+锘縰sing NationalInstruments.TestStand.Interop.API;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using System;
+
+namespace Plugin.TsSupport
+{
+ public class TsExecutionWrapper : ITestExecutionWrapper
+ {
+
+ #region TestStand浜嬩欢
+ /// <summary>
+ /// TS 寮曟搸
+ /// </summary>
+ private Engine engine = null;
+
+ /// <summary>
+ /// 娴嬭瘯搴忓垪璺緞
+ /// </summary>
+ private string testSeqFile = string.Empty;
+
+ /// <summary>
+ /// 娴嬭瘯搴忓垪
+ /// </summary>
+ private SequenceFile testSeq = null;
+
+ /// <summary>
+ /// 娴嬭瘯妯″瀷搴忓垪
+ /// </summary>
+ private SequenceFile modeSeq = null;
+
+ /// <summary>
+ /// 杩愯瀹炰緥
+ /// </summary>
+ private Execution execution = null;
+
+ public SequenceContext context { get; set; } = null;
+
+ /// <summary>
+ /// 浜嬩欢绠$悊鍣�
+ /// </summary>
+ public AxApplicationMgr AxApplicationMgr { get; private set; }
+
+ public event _ApplicationMgrEvents_EndExecutionEventHandler OnEndExecution;
+
+ public event EventHandler<UIMessageEvent> UIMessageEvent;
+ public event EventHandler<ExecutionEndEvent> EndExecutionEvent;
+
+ public TsExecutionWrapper()
+ {
+ AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
+ //AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
+ //AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
+ //AxApplicationMgr.UIMessageEvent +=
+ // new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
+ //AxApplicationMgr.ExecutionClosed +=
+ // new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
+ }
+
+ #endregion
+
+ public object Init()
+ {
+ this.engine = this.AxApplicationMgr.GetEngine();
+ this.engine.PersistBreakpoints = false;
+ this.AxApplicationMgr.IsEditor = true;
+ this.AxApplicationMgr.LoginOnStart = false;
+ this.AxApplicationMgr.Start();
+ return this.AxApplicationMgr;
+ }
+
+ public object StartSequence(string filePath, string modelPath)
+ {
+ this.testSeqFile = filePath;
+
+ this.modeSeq = this.engine.GetSequenceFileEx(modelPath);
+ this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+ this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+ return execution;
+ }
+
+ public T GetFileGlobalValue<T>(string key, int option)
+ {
+ if (typeof(T) == typeof(bool))
+ {
+ return (T)(object)context?.FileGlobals?.GetValBoolean(key, option);
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ return (T)(object)context?.FileGlobals?.GetValString(key, option);
+ }
+ else if (typeof(T) == typeof(int))
+ {
+ return (T)(object)context?.FileGlobals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ return (T)(object)context?.FileGlobals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(float))
+ {
+ return (T)(object)context?.FileGlobals?.GetValNumber(key, option);
+ }
+ return default(T);
+ }
+
+ public T GetStationGlobalValue<T>(string key, int option)
+ {
+ if (typeof(T) == typeof(bool))
+ {
+ return (T)(object)engine?.Globals?.GetValBoolean(key, option);
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ return (T)(object)engine?.Globals?.GetValString(key, option);
+ }
+ else if (typeof(T) == typeof(int))
+ {
+ return (T)(object)engine?.Globals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ return (T)(object)engine?.Globals?.GetValNumber(key, option);
+ }
+ else if (typeof(T) == typeof(float))
+ {
+ return (T)(object)engine?.Globals?.GetValNumber(key, option);
+ }
+ return default(T);
+ }
+
+ public void SetFileGlobalValue<T>(string key, int option, T value)
+ {
+ if (value is bool bVal)
+ {
+ context?.FileGlobals?.SetValBoolean(key, option, bVal);
+ }
+ else if (value is string sVal)
+ {
+ context?.FileGlobals?.SetValString(key, option, sVal);
+ }
+ else if (value is int iVal)
+ {
+ context?.FileGlobals?.SetValNumber(key, option, iVal);
+ }
+ else if (value is double dVal)
+ {
+ context?.FileGlobals?.SetValNumber(key, option, dVal);
+ }
+ else if (value is float fVal)
+ {
+ context?.FileGlobals?.SetValNumber(key, option, fVal);
+ }
+ }
+
+ public void SetStationGlobalValue<T>(string key, int option, T value, bool inContext = false)
+ {
+ PropertyObject obj = null;
+ if (inContext)
+ {
+ obj = context?.StationGlobals;
+ }
+ else
+ {
+ obj = engine?.Globals;
+ }
+
+ if (value is bool bVal)
+ {
+ obj?.SetValBoolean(key, option, bVal);
+ }
+ else if (value is string sVal)
+ {
+ obj?.SetValString(key, option, sVal);
+ }
+ else if (value is int iVal)
+ {
+ obj?.SetValNumber(key, option, iVal);
+ }
+ else if (value is double dVal)
+ {
+ obj?.SetValNumber(key, option, dVal);
+ }
+ else if (value is float fVal)
+ {
+ obj?.SetValNumber(key, option, fVal);
+ }
+ //engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ }
+
+ public void CommitToDisk(bool option)
+ {
+ engine?.CommitGlobalsToDisk(option);
+ }
+
+ public bool WaitForExit()
+ {
+ return this.execution?.WaitForEndEx(-1, true, Type.Missing, null) == true;
+ }
+
+ public bool ReleaseSeqFile()
+ {
+ if (testSeq != null)
+ {
+ return engine?.ReleaseSequenceFileEx(testSeq, 4) == true;
+ }
+ return true;
+ }
+
+ public void SetContext(object context)
+ {
+
+ }
+ }
+}
diff --git a/Plugin.UICollection/AssemblyInfo.cs b/Plugin.UICollection/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Plugin.UICollection/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Plugin.UICollection/Plugin.UICollection.csproj b/Plugin.UICollection/Plugin.UICollection.csproj
new file mode 100644
index 0000000..97514d3
--- /dev/null
+++ b/Plugin.UICollection/Plugin.UICollection.csproj
@@ -0,0 +1,25 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ <PackageReference Include="TouchSocket" Version="4.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\UILib\UILib.csproj" />
+ <ProjectReference Include="..\..\UtilLib\UtilLib.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.UICollection/TcpDebugger.xaml b/Plugin.UICollection/TcpDebugger.xaml
new file mode 100644
index 0000000..2224d08
--- /dev/null
+++ b/Plugin.UICollection/TcpDebugger.xaml
@@ -0,0 +1,176 @@
+锘�<UserControl x:Class="Plugin.UICollection.TcpDebugger"
+ 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.UICollection"
+ mc:Ignorable="d"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:UILib.DpUtil;assembly=UILib"
+ xmlns:uic="clr-namespace:UILib.Converter;assembly=UILib"
+ FontSize="16"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <!--<ResourceDictionary.MergedDictionaries>
+ <pu:StyleDictionary Excludes="Button" />
+ </ResourceDictionary.MergedDictionaries>-->
+ <Style TargetType="ComboBox"/>
+ <Style TargetType="ComboBoxItem"/>
+ <Style TargetType="Button">
+
+ </Style>
+ <Style TargetType="GroupBox">
+
+ </Style>
+ <Style TargetType="TextBox">
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="MinWidth" Value="120"/>
+ <Setter Property="Height" Value="Auto"/>
+ </Style>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+ <StackPanel dp:StackPanelHelper.ChildSpace="10" Margin="0,10,0,10">
+ <pu:FormGroup Header="IP" GroupName="client">
+ <TextBox Text="{Binding Ip}"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="Port" GroupName="client">
+ <TextBox Text="{Binding Port}"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="瀹㈡埛绔鍙�" GroupName="client">
+ <TextBox Text="{Binding ClientPort}"/>
+ </pu:FormGroup>
+
+ <Label>
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="Foreground" Value="White"/>
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="Content" Value="鏈繛鎺�"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsConnected}" Value="True">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Content" Value="宸茶繛鎺�"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+
+ <Button Tag="Connect" Content="杩炴帴" Click="Button_Click"/>
+ <GroupBox Header="鎺ユ敹璁剧疆">
+ <StackPanel dp:StackPanelHelper.ChildSpace="10" Margin="0,10">
+ <StackPanel Orientation="Horizontal">
+ <RadioButton Content="瀛楃涓�" IsChecked="{Binding ReceiveDataType,Converter={x:Static uic:RadioEnumConverter.Instance},ConverterParameter={x:Static local:DataType.String}}" GroupName="ReceiveType"/>
+ <RadioButton Content="Hex" IsChecked="{Binding ReceiveDataType,Converter={x:Static uic:RadioEnumConverter.Instance},ConverterParameter={x:Static local:DataType.HEX}}" GroupName="ReceiveType"/>
+ </StackPanel>
+ <pu:FormGroup Header="缂栫爜鏍煎紡">
+ <ComboBox x:Name="receiveEncodeInput" SelectedValue="{Binding ReceiveEncode}"/>
+ <pu:FormGroup.Style>
+ <Style TargetType="pu:FormGroup">
+ <Setter Property="IsEnabled" Value="False"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ReceiveDataType}" Value="{x:Static local:DataType.String}">
+ <Setter Property="IsEnabled" Value="True"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </pu:FormGroup.Style>
+ </pu:FormGroup>
+ </StackPanel>
+ </GroupBox>
+ </StackPanel>
+
+ <StackPanel Grid.Row="1" Grid.Column="0">
+ <GroupBox Header="鍙戦�佽缃�">
+ <StackPanel dp:StackPanelHelper.ChildSpace="10" Margin="0,10">
+ <StackPanel Orientation="Horizontal">
+ <RadioButton Content="瀛楃涓�" IsChecked="{Binding SendDataType,Converter={x:Static uic:RadioEnumConverter.Instance},ConverterParameter={x:Static local:DataType.String}}" GroupName="SendType"/>
+ <RadioButton Content="Hex" IsChecked="{Binding SendDataType,Converter={x:Static uic:RadioEnumConverter.Instance},ConverterParameter={x:Static local:DataType.HEX}}" GroupName="SendType"/>
+ </StackPanel>
+
+ <pu:FormGroup Header="缂栫爜鏍煎紡">
+ <ComboBox x:Name="sendEncodeInput" SelectedValue="{Binding SendEncode}"/>
+ <pu:FormGroup.Style>
+ <Style TargetType="pu:FormGroup">
+ <Setter Property="IsEnabled" Value="False"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SendDataType}" Value="{x:Static local:DataType.String}">
+ <Setter Property="IsEnabled" Value="True"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </pu:FormGroup.Style>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="鍒嗛殧绗�">
+ <ComboBox ItemsSource="{Binding EndMarkSource}" SelectedValue="{Binding EndMark}" DisplayMemberPath="Name" SelectedValuePath="Type"/>
+ <pu:FormGroup.Style>
+ <Style TargetType="pu:FormGroup">
+ <Setter Property="IsEnabled" Value="False"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SendDataType}" Value="{x:Static local:DataType.String}">
+ <Setter Property="IsEnabled" Value="True"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </pu:FormGroup.Style>
+ </pu:FormGroup>
+ <pu:FormGroup Header="鑷畾涔夊垎闅旂">
+ <TextBox Text="{Binding CustomEndMark}"/>
+ <pu:FormGroup.Style>
+ <Style TargetType="pu:FormGroup">
+ <Setter Property="IsEnabled" Value="False"/>
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding SendDataType}" Value="{x:Static local:DataType.String}"/>
+ <Condition Binding="{Binding EndMark}" Value="2"/>
+ </MultiDataTrigger.Conditions>
+ <Setter Property="IsEnabled" Value="True"/>
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </pu:FormGroup.Style>
+ </pu:FormGroup>
+ </StackPanel>
+ </GroupBox>
+ </StackPanel>
+
+ <Grid Grid.Row="1" Grid.Column="1">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <GroupBox Header="鏁版嵁鍙戦��">
+ <TextBox x:Name="sendBox" TextWrapping="Wrap" VerticalContentAlignment="Top"
+ PreviewTextInput="TextBox_PreviewTextInput"/>
+ </GroupBox>
+ <Button Grid.Column="1" Padding="20" Content="鍙戦��" Tag="Send" Click="Button_Click"/>
+ </Grid>
+
+ <Grid Grid.Row="0" Grid.Column="1">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <GroupBox Header="鏁版嵁鎺ユ敹">
+ <RichTextBox x:Name="console" IsReadOnly="True"/>
+ </GroupBox>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Plugin.UICollection/TcpDebugger.xaml.cs b/Plugin.UICollection/TcpDebugger.xaml.cs
new file mode 100644
index 0000000..3b52834
--- /dev/null
+++ b/Plugin.UICollection/TcpDebugger.xaml.cs
@@ -0,0 +1,393 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Media;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+using UtilLib;
+
+namespace Plugin.UICollection
+{
+ public enum DataType
+ {
+ String = 0,
+ HEX = 1
+ }
+
+ public enum SupportEncode
+ {
+ GBK = 0,
+ ASCII = 1,
+ UTF8 = 2
+ }
+
+ public class EndMarkSource
+ {
+ public string Name { get; set; }
+ public int Type { get; set; }
+ }
+
+ public class ByteStringConverter : IValueConverter
+ {
+ private TcpDebugger control { get; set; }
+
+ public ByteStringConverter(TcpDebugger control)
+ {
+ this.control = control;
+ }
+
+ public static string GroupByTwo(string str)
+ {
+ if (string.IsNullOrEmpty(str))
+ return string.Empty;
+
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < str.Length; i += 2)
+ {
+ if (i > 0)
+ result.Append(' ');
+
+ int length = Math.Min(2, str.Length - i);
+ result.Append(str.Substring(i, length));
+ }
+ return result.ToString();
+ }
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ DataType sendType = control.SendDataType;
+ if (sendType != DataType.HEX)
+ {
+ return value;
+ }
+ var str = value.ToString();
+ return GroupByTwo(str);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ DataType sendType = control.SendDataType;
+ if (sendType != DataType.HEX)
+ {
+ return value;
+ }
+ return value.ToString().Replace(" ", "");
+ }
+ }
+
+ /// <summary>
+ /// TcpDebugger.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class TcpDebugger : UserControl
+ {
+
+ [ObservableProperty]
+ private string ip = "127.0.0.1";
+
+ [ObservableProperty]
+ private int port;
+
+ [ObservableProperty]
+ private int clientPort;
+
+ [ObservableProperty]
+ private DataType receiveDataType = DataType.String;
+
+ [ObservableProperty]
+ private DataType sendDataType = DataType.String;
+
+ [ObservableProperty]
+ private bool isConnected = false;
+
+ [ObservableProperty]
+ private string sendText;
+
+ [ObservableProperty]
+ private SupportEncode receiveEncode;
+
+ [ObservableProperty]
+ private SupportEncode sendEncode;
+
+ [ObservableProperty]
+ private ObservableCollection<EndMarkSource> endMarkSource = new ObservableCollection<EndMarkSource> {
+ new EndMarkSource{ Name="鏃�",Type=-1},
+ new EndMarkSource{ Name="\\r",Type=0},
+ new EndMarkSource{ Name="\\r\\n",Type=1},
+ new EndMarkSource{ Name="鑷畾涔�",Type=2},
+ };
+
+ [ObservableProperty]
+ private int endMark;
+
+ [ObservableProperty]
+ private string customEndMark;
+
+ private ByteStringConverter bsConverter;
+
+
+ private TcpClient client;
+
+ public TcpDebugger()
+ {
+ DataContext = this;
+ InitializeComponent();
+ sendEncodeInput.ItemsSource = Enum.GetValues(typeof(SupportEncode)).Cast<SupportEncode>();
+ receiveEncodeInput.ItemsSource = Enum.GetValues(typeof(SupportEncode)).Cast<SupportEncode>();
+ DataObject.AddPastingHandler(sendBox, OnPasting);
+ bsConverter = new ByteStringConverter(this);
+ BindingOperations.SetBinding(sendBox, TextBox.TextProperty, new Binding(nameof(SendText))
+ {
+ Source = this,
+ Mode = BindingMode.TwoWay,
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
+ Converter = bsConverter
+ });
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ var btn = (Button)sender;
+ if (btn.Tag.ToString() == "Connect")
+ {
+ TryConnect();
+ return;
+ }
+
+ if (btn.Tag.ToString() == "Send")
+ {
+ TrySend();
+ return;
+ }
+
+ }
+
+ private void TryConnect()
+ {
+ try
+ {
+ if (IsConnected) return;
+ var config = new TouchSocketConfig().SetRemoteIPHost($"tcp://{Ip}:{Port}");
+ client = new TcpClient();
+ client.Received = TcpReceived;
+ client.Connected = (sender, e) =>
+ {
+ Dispatcher.Invoke(() =>
+ {
+ Add("杩炴帴", "杩炴帴鎴愬姛", Brushes.Green);
+ IsConnected = true;
+ });
+ return EasyTask.CompletedTask;
+ };
+ client.Closed = (sender, e) =>
+ {
+ Dispatcher.Invoke(() =>
+ {
+ Add("杩炴帴", "杩炴帴鏂紑", Brushes.Red);
+ IsConnected = false;
+ });
+ return EasyTask.CompletedTask;
+ };
+ client.SetupAsync(config);
+ client.ConnectAsync();
+ }
+ catch (Exception ex)
+ {
+ IsConnected = false;
+ // throw ex;
+ }
+ }
+
+ private Task TcpReceived(object sender, ReceivedDataEventArgs e)
+ {
+ try
+ {
+ var datas = e.Memory.Span.ToArray();
+ string msg = null;
+ if (ReceiveDataType == DataType.HEX)
+ {
+ msg = HexUtil.ByteArrayToHex(datas);
+ }
+ else
+ {
+ if (ReceiveEncode == SupportEncode.GBK)
+ {
+ msg = Encoding.Default.GetString(datas);
+ }
+ else if (ReceiveEncode == SupportEncode.ASCII)
+ {
+ msg = Encoding.ASCII.GetString(datas);
+ }
+ else
+ {
+
+ msg = Encoding.UTF8.GetString(datas);
+ }
+ }
+ Add("鎺ユ敹", msg, Brushes.Green);
+ }
+ catch (Exception ex)
+ {
+ //log.Error($"TcpReceived Error.", ex);
+ }
+ return EasyTask.CompletedTask;
+ }
+
+ private byte[] GetBytes(out string msg)
+ {
+ msg = null;
+ if (string.IsNullOrEmpty(SendText))
+ {
+ return null;
+ }
+ if (SendDataType == DataType.String)
+ {
+ msg = SendText + GetEndMark();
+ if (SendEncode == SupportEncode.GBK)
+ {
+ return Encoding.Default.GetBytes(msg);
+ }
+ if (SendEncode == SupportEncode.ASCII)
+ {
+ return Encoding.ASCII.GetBytes(msg);
+ }
+ if (SendEncode == SupportEncode.UTF8)
+ {
+ return Encoding.UTF8.GetBytes(msg);
+ }
+ return null;
+ }
+ msg = SendText;
+ if (msg.Length % 2 != 0)
+ {
+ msg = msg.Insert(msg.Length - 1, "0");
+ }
+ msg = ByteStringConverter.GroupByTwo(msg);
+ return HexUtil.HexToByteArray(msg);
+ }
+
+ private string GetEndMark()
+ {
+ if (EndMark == -1)
+ {
+ return string.Empty;
+ }
+ if (EndMark == 0)
+ {
+ return "\r";
+ }
+ if (EndMark == 1)
+ {
+ return "\r\n";
+ }
+ if (EndMark == 2)
+ {
+ return CustomEndMark;
+ }
+ return string.Empty;
+ }
+
+ public void TrySend()
+ {
+ if (!IsConnected)
+ {
+ MessageBox.Show("璇峰厛杩炴帴", "鎻愮ず");
+ return;
+ }
+ var datas = GetBytes(out string msg);
+ if (datas != null)
+ {
+ client.SendAsync(datas).Wait();
+ Add("鍙戦��", msg, Brushes.Blue);
+ // SendText = string.Empty;
+ }
+ }
+
+ public void Add(string type, string text, Brush color)
+ {
+ Dispatcher.BeginInvoke(() =>
+ {
+ string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ Run run = new Run();
+ run.Text = $"{time} {type}\r\n";
+ run.Foreground = Brushes.Gray;
+
+ Paragraph paragraph = new Paragraph(run)
+ {
+ LineHeight = 1
+ };
+
+ run = new Run();
+ run.Text = $"{text}\r\n";
+ run.Foreground = color;
+ paragraph.Inlines.Add(run);
+ //涔熷彲浠ユ彃鍏ュ埌鏈�鍚庨潰
+ console.Document.Blocks.InsertAfter(console.Document.Blocks.LastBlock, paragraph);
+
+ //鎻掑叆鍒版渶鍓嶉潰
+ //rtxtLog.Document.Blocks.Add(paragraph);
+
+ // 婊氬姩鑷虫渶鍚庤
+ //rtxtLog.ScrollToEnd();
+ //Console.ScrollToHome();
+ console.ScrollToEnd();
+ // 鍒犻櫎
+ //if (Console.Document.Blocks.Count > 10000)
+ //{
+ // for (int i = 1000; i < Console.Document.Blocks.Count; i++)
+ // {
+ // _ = Console.Document.Blocks.Remove(Console.Document.Blocks.FirstBlock);
+ // }
+ //}
+
+ }, System.Windows.Threading.DispatcherPriority.Normal);
+ }
+
+ private static readonly Regex HexRegex = new Regex("^[0-9A-Fa-f]+$");
+
+ private void TextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
+ {
+ if (SendDataType != DataType.HEX)
+ {
+ return;
+ }
+ var tb = (TextBox)sender;
+ string segment = e.Text;
+
+ if (!HexRegex.IsMatch(segment))
+ {
+ tb.Text = tb.Text.Replace(segment, "");
+ tb.CaretIndex = tb.Text.Length;
+ e.Handled = true;
+ return;
+ }
+ // tb.Text = tb.Text.ToUpper();
+
+ base.OnPreviewTextInput(e);
+ }
+
+ private void OnPasting(object sender, DataObjectPastingEventArgs e)
+ {
+ if (SendDataType != DataType.HEX)
+ {
+ return;
+ }
+
+ if (e.DataObject.GetDataPresent(typeof(string)))
+ {
+ string text = (string)e.DataObject.GetData(typeof(string));
+ text = text.Replace(" ", "");
+ if (!HexRegex.IsMatch(text))
+ {
+ e.CancelCommand();
+ }
+ }
+ }
+ }
+}
diff --git a/SimpleUtil/HMI.Simple.Util/Parameter.cs b/SimpleUtil/HMI.Simple.Util/Parameter.cs
index 71237da..c8650ce 100644
--- a/SimpleUtil/HMI.Simple.Util/Parameter.cs
+++ b/SimpleUtil/HMI.Simple.Util/Parameter.cs
@@ -5,6 +5,7 @@
public string Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
+ public bool IsArray { get; set; }
public string Value { get; set; }
public string Unit { get; set; }
public string Description { get; set; }
diff --git a/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs b/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
index ae461c2..8e1054e 100644
--- a/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
@@ -59,21 +59,72 @@
private static void WriteParameterData(SequenceContext context, ParameterData data)
{
string prefix = "SystemSetting";
- if (data.Type == "Bool")
+
+ if (data.IsArray)
{
- context.StationGlobals.SetValBoolean($"{prefix}.{data.Name}", 1, bool.Parse(data.Value));
- }
- else if (data.Type == "Int")
- {
- context.StationGlobals.SetValNumber($"{prefix}.{data.Name}", 1, int.Parse(data.Value));
- }
- else if (data.Type == "Double")
- {
- context.StationGlobals.SetValNumber($"{prefix}.{data.Name}", 1, double.Parse(data.Value));
+ PropertyValueTypes type;
+ if (data.Type == "Bool")
+ {
+ type = PropertyValueTypes.PropValType_Boolean;
+ }
+ else if (data.Type == "Int")
+ {
+ type = PropertyValueTypes.PropValType_Number;
+ }
+ else if (data.Type == "Double")
+ {
+ type = PropertyValueTypes.PropValType_Number;
+ }
+ else
+ {
+ type = PropertyValueTypes.PropValType_String;
+ }
+ string[] arr = data.Value?.Split(',') ?? new string[0];
+ if (arr.Length > 0)
+ {
+ context.StationGlobals.DeleteSubProperty($"{prefix}.{data.Name}", 2);
+
+ context.StationGlobals.NewSubProperty($"{prefix}.{data.Name}", type, true, null, 1);
+ context.StationGlobals.GetPropertyObject($"{prefix}.{data.Name}", 0).SetNumElements(arr.Length);
+ for (int i = 0; i < arr.Length; i++)
+ {
+ if (type == PropertyValueTypes.PropValType_String)
+ {
+ context.StationGlobals.SetValString($"{prefix}.{data.Name}[{i}]", 0, arr[i]);
+ }
+ if (data.Type == "Int")
+ {
+ context.StationGlobals.SetValNumber($"{prefix}.{data.Name}[{i}]", 0, int.Parse(arr[i]));
+ }
+ if (data.Type == "Double")
+ {
+ context.StationGlobals.SetValNumber($"{prefix}.{data.Name}[{i}]", 0, double.Parse(arr[i]));
+ }
+ if (data.Type == "Bool")
+ {
+ context.StationGlobals.SetValBoolean($"{prefix}.{data.Name}[{i}]", 0, bool.Parse(arr[i]));
+ }
+ }
+ }
}
else
{
- context.StationGlobals.SetValString($"{prefix}.{data.Name}", 1, data.Value);
+ if (data.Type == "Bool")
+ {
+ context.StationGlobals.SetValBoolean($"{prefix}.{data.Name}", 1, bool.Parse(data.Value));
+ }
+ else if (data.Type == "Int")
+ {
+ context.StationGlobals.SetValNumber($"{prefix}.{data.Name}", 1, int.Parse(data.Value));
+ }
+ else if (data.Type == "Double")
+ {
+ context.StationGlobals.SetValNumber($"{prefix}.{data.Name}", 1, double.Parse(data.Value));
+ }
+ else
+ {
+ context.StationGlobals.SetValString($"{prefix}.{data.Name}", 1, data.Value);
+ }
}
}
diff --git a/SimpleUtil/HMI.Simple.Util/ProductUtil.cs b/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
index 9a7e156..fe8c631 100644
--- a/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
@@ -10,22 +10,86 @@
private static void WriteParameterData(object instance, ParameterData data)
{
SequenceContext context = (SequenceContext)instance;
- if (data.Type == "Bool")
+ string name = $"DUTSetting.{data.Name}";
+
+ if (data.IsArray)
{
- context.FileGlobals.SetValBoolean($"DUTSetting.{data.Name}", 1, bool.Parse(data.Value));
- }
- else if (data.Type == "Int")
- {
- context.FileGlobals.SetValNumber($"DUTSetting.{data.Name}", 1, int.Parse(data.Value));
- }
- else if (data.Type == "Double")
- {
- context.FileGlobals.SetValNumber($"DUTSetting.{data.Name}", 1, double.Parse(data.Value));
+ PropertyValueTypes type;
+ if (data.Type == "Bool")
+ {
+ type = PropertyValueTypes.PropValType_Boolean;
+ }
+ else if (data.Type == "Int")
+ {
+ type = PropertyValueTypes.PropValType_Number;
+ }
+ else if (data.Type == "Double")
+ {
+ type = PropertyValueTypes.PropValType_Number;
+ }
+ else
+ {
+ type = PropertyValueTypes.PropValType_String;
+ }
+ string[] arr = data.Value?.Split(',') ?? new string[0];
+ if (arr.Length > 0)
+ {
+ context.FileGlobals.DeleteSubProperty(name, 2);
+
+ context.FileGlobals.NewSubProperty(name, type, true, null, 1);
+ context.FileGlobals.GetPropertyObject(name, 0).SetNumElements(arr.Length);
+ for (int i = 0; i < arr.Length; i++)
+ {
+ if (type == PropertyValueTypes.PropValType_String)
+ {
+ context.FileGlobals.SetValString($"{name}[{i}]", 0, arr[i]);
+ }
+ if (data.Type == "Int")
+ {
+ context.FileGlobals.SetValNumber($"{name}[{i}]", 0, int.Parse(arr[i]));
+ }
+ if (data.Type == "Double")
+ {
+ context.FileGlobals.SetValNumber($"{name}[{i}]", 0, double.Parse(arr[i]));
+ }
+ if (data.Type == "Bool")
+ {
+ context.FileGlobals.SetValBoolean($"{name}[{i}]", 0, bool.Parse(arr[i]));
+ }
+ }
+ }
}
else
{
- context.FileGlobals.SetValString($"DUTSetting.{data.Name}", 1, data.Value);
+ if (data.Type == "Bool")
+ {
+ context.FileGlobals.SetValBoolean(name, 1, bool.Parse(data.Value));
+ }
+ else if (data.Type == "Int")
+ {
+ context.FileGlobals.SetValNumber(name, 1, int.Parse(data.Value));
+ }
+ else if (data.Type == "Double")
+ {
+ context.FileGlobals.SetValNumber(name, 1, double.Parse(data.Value));
+ }
+ else
+ {
+ context.FileGlobals.SetValString(name, 1, data.Value);
+ }
}
+
+
+ }
+
+ private static string GetDataFilePath()
+ {
+ string path = ParameterUtil.GetCommonParameterValue("ShareConfig", out _);
+ if (path == null)
+ {
+ path = Path.Combine(RegUtil.GetLocaltion(), "Config");
+ }
+ return path;
}
/// <summary>
@@ -40,8 +104,7 @@
errMsg = string.Empty;
try
{
- string dir = RegUtil.GetLocaltion();
- string path = Path.Combine(dir, "Config", "Product", "Parameter", $"Parameter_{model}.data");
+ string path = Path.Combine(GetDataFilePath(), "Product", "Parameter", $"Parameter_{model}.data");
return WriteConfigToContextByPath(path, instance, out errMsg);
}
catch (Exception ex)
diff --git a/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs b/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs
index 72ab98f..78f8be5 100644
--- a/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs
+++ b/SimpleUtil/HMI.Simple.Util/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
锘縰sing System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
@@ -29,5 +28,5 @@
// 鐢熸垚鍙�
// 淇鍙�
//
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.2")]
+[assembly: AssemblyVersion("1.0.0.3")]
+[assembly: AssemblyFileVersion("1.0.0.3")]
diff --git a/Util.ManualDebug/AssemblyInfo.cs b/Util.ManualDebug/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/Util.ManualDebug/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Util.ManualDebug/ManualDebug.xaml b/Util.ManualDebug/ManualDebug.xaml
new file mode 100644
index 0000000..ca818b0
--- /dev/null
+++ b/Util.ManualDebug/ManualDebug.xaml
@@ -0,0 +1,133 @@
+<UserControl x:Class="Util.SB.ManualDebug"
+ 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:Util.SB"
+ mc:Ignorable="d"
+ x:Name="self"
+ MinHeight="400" MinWidth="500">
+
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/Util.ManualDebug;component/ManualDebugStyle.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <Grid>
+ <Grid Margin="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="5"/>
+ <RowDefinition Height="*"/>
+ <RowDefinition Height="5"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+ <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
+
+ <!-- 鎸夐挳鍜岀姸鎬佸尯鍩� -->
+ <Border Grid.Row="0" Background="{StaticResource TsPanelBrush}"
+ BorderBrush="{StaticResource BorderBrush}"
+ BorderThickness="1" CornerRadius="4" Padding="15">
+ <StackPanel>
+ <TextBlock Text="鎵嬪姩璋冭瘯鎺у埗" FontSize="14" FontWeight="SemiBold"
+ Foreground="{StaticResource PrimaryBrush}" Margin="0,0,0,15"/>
+
+ <WrapPanel x:Name="btnPanel">
+
+ </WrapPanel>
+ </StackPanel>
+ </Border>
+
+ <!-- 鍒嗛殧鏉�1 -->
+ <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch"
+ Background="Transparent" Cursor="SizeNS"/>
+
+ <!-- TX/RX 鏁版嵁鍖哄煙 -->
+ <Border Grid.Row="2" Background="{StaticResource TsPanelBrush}"
+ BorderBrush="{StaticResource BorderBrush}"
+ BorderThickness="1" CornerRadius="4" Padding="10">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ <StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,10">
+ <TextBlock Text="娴嬭瘯鏁版嵁" FontSize="14" FontWeight="SemiBold"
+ Foreground="{StaticResource PrimaryBrush}" VerticalAlignment="Center"/>
+ <Button Content="娓呯┖" Style="{StaticResource ActionButtonStyle}"
+ Margin="15,0,0,0" Click="OnClearClick"/>
+ </StackPanel>
+
+ <DataGrid x:Name="DataGridComm" Grid.Row="1"
+ ItemsSource="{Binding TestData,ElementName=self}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="娴嬭瘯椤�" Binding="{Binding Name}" Width="120" IsReadOnly="True"/>
+ <DataGridTextColumn Header="鏀�" Binding="{Binding Receive}" Width="*" IsReadOnly="True"/>
+ <DataGridTextColumn Header="鍙�" Binding="{Binding Send}" Width="*" IsReadOnly="True"/>
+ <DataGridTextColumn Header="鍗曚綅" Binding="{Binding Unit}" Width="60" IsReadOnly="True"/>
+ <DataGridTextColumn Header="涓婇檺" Binding="{Binding UpperLimit}" Width="80" IsReadOnly="True"/>
+ <DataGridTextColumn Header="涓嬮檺" Binding="{Binding LowerLimit}" Width="80" IsReadOnly="True"/>
+ <DataGridTextColumn Header="缁撴灉" Binding="{Binding Result}" Width="70" IsReadOnly="True"/>
+ <DataGridTextColumn Header="鏃堕棿" Binding="{Binding Time}" Width="90" IsReadOnly="True"/>
+ </DataGrid.Columns>
+ <DataGrid.RowStyle>
+ <Style TargetType="DataGridRow">
+ <Style.Triggers>
+ <DataTrigger Value="True">
+ <DataTrigger.Binding>
+ <MultiBinding Converter="{x:Static local:ResultFailedConverter.Instance}">
+ <Binding Path="Result"/>
+ </MultiBinding>
+ </DataTrigger.Binding>
+ <Setter Property="Background" Value="#FFE0E0"/>
+ <Setter Property="Foreground" Value="#C53030"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </DataGrid.RowStyle>
+ </DataGrid>
+ </Grid>
+ </Border>
+
+ <!-- 鍒嗛殧鏉�2 -->
+ <GridSplitter Grid.Row="3" Height="5" HorizontalAlignment="Stretch"
+ Background="Transparent" Cursor="SizeNS"/>
+
+ <!-- 鏃ュ織鍖哄煙 -->
+ <Border Grid.Row="4" Background="{StaticResource TsPanelBrush}"
+ BorderBrush="{StaticResource BorderBrush}"
+ BorderThickness="1" CornerRadius="4" Padding="10">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ <StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,8">
+ <TextBlock Text="鏃ュ織" FontSize="14" FontWeight="SemiBold"
+ Foreground="{StaticResource PrimaryBrush}" VerticalAlignment="Center"/>
+ <Button Content="娓呯┖鏃ュ織" Style="{StaticResource ActionButtonStyle}"
+ Margin="15,0,0,0" Click="OnClearLogClick"/>
+ </StackPanel>
+
+ <RichTextBox x:Name="LogRichTextBox" Grid.Row="1"
+ IsReadOnly="True"
+ VerticalScrollBarVisibility="Auto"
+ FontFamily="Consolas"
+ FontSize="11"
+ BorderThickness="1"
+ BorderBrush="Black"
+ Padding="4"/>
+ </Grid>
+ </Border>
+ </Grid>
+ <Border Background="#AAFFFFFF" x:Name="mask">
+ <TextBlock Text="鍒濆鍖栦腑..."
+ FontSize="16" FontWeight="Bold" Foreground="{StaticResource PrimaryBrush}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+ </Border>
+ </Grid>
+</UserControl>
diff --git a/Util.ManualDebug/ManualDebug.xaml.cs b/Util.ManualDebug/ManualDebug.xaml.cs
new file mode 100644
index 0000000..7fa336e
--- /dev/null
+++ b/Util.ManualDebug/ManualDebug.xaml.cs
@@ -0,0 +1,467 @@
+using Plugin.TsSupport;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Media;
+
+namespace Util.SB
+{
+ public class BtnConfig
+ {
+ public string Title { get; set; }
+ public string Name { get; set; }
+ }
+
+ // 结果失败判断转换器(支持不区分大小写)
+ public class ResultFailedConverter : IMultiValueConverter
+ {
+ public static readonly ResultFailedConverter Instance = new ResultFailedConverter();
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values.Length > 0 && values[0] is string)
+ {
+ string result = (string)values[0];
+ string upper = result.ToUpperInvariant();
+ return upper == "NG" || upper == "FAIL";
+ }
+ return false;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ // 日志级别枚举
+ public enum LogLevel
+ {
+ Debug = 0,
+ Info = 1,
+ Warn = 2,
+ Error = 3
+ }
+
+ public partial class ManualDebug : UserControl
+ {
+ public static readonly DependencyProperty OvenNameProperty = DependencyProperty.Register(
+ "OvenName",
+ typeof(string),
+ typeof(ManualDebug),
+ new PropertyMetadata(""));
+
+ public static readonly DependencyProperty CellNameProperty = DependencyProperty.Register(
+ "CellName",
+ typeof(string),
+ typeof(ManualDebug),
+ new PropertyMetadata(""));
+
+ public static readonly DependencyProperty OvenIndexProperty = DependencyProperty.Register(
+ "OvenIndex",
+ typeof(int),
+ typeof(ManualDebug),
+ new PropertyMetadata(0));
+
+ public static readonly DependencyProperty CellIndexProperty = DependencyProperty.Register(
+ "CellIndex",
+ typeof(int),
+ typeof(ManualDebug),
+ new PropertyMetadata(0));
+
+ public string OvenName
+ {
+ get { return (string)GetValue(OvenNameProperty); }
+ set
+ {
+ SetValue(OvenNameProperty, value);
+ }
+ }
+
+ public string CellName
+ {
+ get { return (string)GetValue(CellNameProperty); }
+ set { SetValue(CellNameProperty, value); }
+ }
+
+ public int OvenIndex
+ {
+ get { return (int)GetValue(OvenIndexProperty); }
+ set { SetValue(OvenIndexProperty, value); }
+ }
+
+ public int CellIndex
+ {
+ get { return (int)GetValue(CellIndexProperty); }
+ set { SetValue(CellIndexProperty, value); }
+ }
+
+ public ObservableCollection<TestDataItem> TestData { get; private set; } = new ObservableCollection<TestDataItem>();
+
+ private Dictionary<string, StatusBtn> btnCache = new Dictionary<string, StatusBtn>();
+
+ // 日志级别颜色
+ private readonly SolidColorBrush _debugBrush;
+ private readonly SolidColorBrush _infoBrush;
+ private readonly SolidColorBrush _warnBrush;
+ private readonly SolidColorBrush _errorBrush;
+
+ private ITestExecutionWrapper executionWrapper;
+
+ public string seqPath { get; set; }
+ public string modelPath { get; set; } = "C:\\Program Files\\National Instruments\\TestStand 2020\\Components\\Models\\TestStandModels\\ParallelModel.seq";
+
+ public ManualDebug()
+ {
+ _debugBrush = new SolidColorBrush(Color.FromRgb(0x71, 0x80, 0x8A)); // 灰色
+ _infoBrush = new SolidColorBrush(Colors.Black);
+ _warnBrush = new SolidColorBrush(Color.FromRgb(0xD6, 0x9E, 0x2E)); // 橙黄色
+ _errorBrush = new SolidColorBrush(Color.FromRgb(0xC5, 0x30, 0x30)); // 红色
+ this.Loaded += ManualDebug_Loaded;
+ InitializeComponent();
+ RefreshButtons(null);
+ }
+
+ private void ManualDebug_Loaded(object sender, RoutedEventArgs e)
+ {
+ Task.Run(() =>
+ {
+ System.Threading.Thread.Sleep(500);
+ Dispatcher.BeginInvoke(() =>
+ {
+ InitWrapper();
+ StartSeq();
+ mask.Visibility = Visibility.Collapsed;
+ });
+ });
+ }
+
+ public void RefreshButtons(List<BtnConfig> settings)
+ {
+ if (settings == null) return;
+
+ for (int i = 0; i < settings.Count; i++) {
+ var setting = settings[i];
+
+ var margin = new Thickness(0, 0, 20, 0);
+ if (i == settings.Count - 1)
+ {
+ margin = new Thickness(0);
+ }
+
+ var btn = new StatusBtn
+ {
+ Title = setting.Title,
+ Tag = setting,
+ Margin = margin
+ };
+ btn.BtnClick += Btn_BtnClick;
+ btnCache[setting.Name] = btn;
+ btnPanel.Children.Add(btn);
+ }
+ }
+
+ public void StartSeq()
+ {
+ try
+ {
+ executionWrapper?.StartSequence(seqPath, modelPath);
+ }
+ catch (Exception ex)
+ {
+ AppendLog(LogLevel.Error, $"启动测试序列失败 {ex.Message} {ex.StackTrace}");
+ }
+ }
+
+ private void InitWrapper()
+ {
+ try
+ {
+ var wrapper = new TeststandWrapper();
+ var AxApplicationMgr = wrapper.AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
+ host.Child = AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+ wrapper.Init();
+ executionWrapper = wrapper;
+
+ wrapper.UIMessageEvent += Wrapper_UIMessageEvent;
+ }
+ catch (Exception ex)
+ {
+ AppendLog(LogLevel.Error, $"初始化Teststand {ex.Message} {ex.StackTrace}");
+ }
+ }
+
+ private void Wrapper_UIMessageEvent(object sender, UIMessageEvent e)
+ {
+ try
+ {
+ if (e.EventCode == 10000)
+ {
+ executionWrapper?.SetContext(e.Data);
+ return;
+ }
+ if (e.EventCode == 10001)
+ {
+ string[] arr = e.StrData.Split(',');
+ Dispatcher.BeginInvoke(() =>
+ {
+ AddTestData(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7]);
+ });
+ return;
+ }
+ if (e.EventCode == 10002)
+ {
+ string[] arr = e.StrData.Split(',');
+ LogLevel level = (LogLevel)int.Parse(arr[0]);
+ Dispatcher.BeginInvoke(() =>
+ {
+ AppendLog(level, arr[1]);
+ });
+ return;
+ }
+ if (e.EventCode == 10003)
+ {
+ string[] arr = e.StrData.Split(',');
+ DebugStatus status = (DebugStatus)int.Parse(arr[1]);
+ Dispatcher.BeginInvoke(() =>
+ {
+ SetStatus(arr[0], status);
+ });
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ AppendLog(LogLevel.Error, $"处理UI信息失败 {ex.Message} {ex.StackTrace}");
+ }
+ }
+
+
+
+ private void Btn_BtnClick(object sender, RoutedEventArgs e)
+ {
+ var btn = (StatusBtn)sender;
+ BtnConfig config = (BtnConfig)btn.Tag;
+ StartSingleTest(config.Name);
+ }
+
+ private void StartSingleTest(string name)
+ {
+ try
+ {
+ string key = $"Running.OvenName";
+ executionWrapper?.SetFileGlobalValue(key, 1, OvenName);
+
+ key = $"Running.CellName";
+ executionWrapper?.SetFileGlobalValue(key, 1, CellName);
+
+ key = $"Running.OvenIndex";
+ executionWrapper?.SetFileGlobalValue(key, 1, OvenIndex);
+
+ key = $"Running.CellIndex";
+ executionWrapper?.SetFileGlobalValue(key, 1, CellIndex);
+
+ key = $"Running.ActionName";
+ executionWrapper?.SetFileGlobalValue(key, 1, name);
+ }
+ catch (Exception ex)
+ {
+ AppendLog(LogLevel.Error, $"启动功能失败 {ex.Message} {ex.StackTrace}");
+ }
+ }
+
+ // 设置状态显示
+ private void SetStatus(string labelName, DebugStatus status)
+ {
+ if (btnCache.ContainsKey(labelName))
+ {
+ var btn = btnCache[labelName];
+ btn.Status = status;
+ }
+ }
+
+ // 重置状态显示
+ private void ResetStatus(string labelName)
+ {
+ SetStatus(labelName, DebugStatus.Idle);
+ }
+
+ // 设置测试中状态并禁用按钮
+ private void SetTestingStatus(string labelName, Button button)
+ {
+ SetStatus(labelName, DebugStatus.Testing);
+ button.IsEnabled = false;
+ }
+
+ private void OnClearClick(object sender, RoutedEventArgs e)
+ {
+ TestData.Clear();
+ }
+
+ private void OnClearLogClick(object sender, RoutedEventArgs e)
+ {
+ LogRichTextBox.Document.Blocks.Clear();
+ }
+
+ private void AddTestData(string name, string send, string receive, string unit, string upper, string lower, string result, string time)
+ {
+ TestData.Add(new TestDataItem
+ {
+ Name = name,
+ Send = send,
+ Receive = receive,
+ Unit = unit,
+ UpperLimit = upper,
+ LowerLimit = lower,
+ Result = result,
+ Time = time
+ });
+
+ if (DataGridComm.Items.Count > 0)
+ {
+ DataGridComm.ScrollIntoView(DataGridComm.Items[DataGridComm.Items.Count - 1]);
+ }
+ }
+
+ // 获取日志级别对应的颜色
+ private Brush GetLogLevelBrush(LogLevel level)
+ {
+ switch (level)
+ {
+ case LogLevel.Debug:
+ return _debugBrush;
+ case LogLevel.Info:
+ return _infoBrush;
+ case LogLevel.Warn:
+ return _warnBrush;
+ case LogLevel.Error:
+ return _errorBrush;
+ default:
+ return _infoBrush;
+ }
+ }
+
+ // 添加带级别的日志
+ private void AppendLog(LogLevel level, string message)
+ {
+ Dispatcher.BeginInvoke(() =>
+ {
+ string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
+ string levelStr = level.ToString().ToUpper();
+
+ Paragraph? paragraph = LogRichTextBox.Document.Blocks.LastBlock as Paragraph;
+ if (paragraph == null)
+ {
+ paragraph = new Paragraph();
+ LogRichTextBox.Document.Blocks.Add(paragraph);
+ }
+
+ // 时间戳(灰色)
+ Run timestampRun = new Run("[" + timestamp + "] ") { Foreground = _debugBrush };
+ paragraph.Inlines.Add(timestampRun);
+
+ // 级别标签
+ Brush levelBrush = GetLogLevelBrush(level);
+ Run levelRun = new Run("[" + levelStr + "] ") { Foreground = levelBrush, FontWeight = FontWeights.SemiBold };
+ paragraph.Inlines.Add(levelRun);
+
+ // 消息内容
+ Run messageRun = new Run(message + "\n") { Foreground = levelBrush };
+ paragraph.Inlines.Add(messageRun);
+
+ LogRichTextBox.ScrollToEnd();
+ });
+ }
+
+ // 兼容旧调用方式,默认 Info 级别
+ private void AppendLog(string message)
+ {
+ AppendLog(LogLevel.Info, message);
+ }
+
+ public void Stop()
+ {
+ try
+ {
+ executionWrapper?.SetFileGlobalValue("Running.StopTest", 1, true);
+ executionWrapper?.WaitForExit();
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+ }
+
+ public class TestDataItem : INotifyPropertyChanged
+ {
+ private string _name = "";
+ private string _receive = "";
+ private string _send = "";
+ private string _unit = "";
+ private string _upperLimit = "";
+ private string _lowerLimit = "";
+ private string _result = "";
+ private string _time = "";
+
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; OnPropertyChanged("Name"); }
+ }
+
+ public string Receive
+ {
+ get { return _receive; }
+ set { _receive = value; OnPropertyChanged("Receive"); }
+ }
+
+ public string Send
+ {
+ get { return _send; }
+ set { _send = value; OnPropertyChanged("Send"); }
+ }
+
+ public string Unit
+ {
+ get { return _unit; }
+ set { _unit = value; OnPropertyChanged("Unit"); }
+ }
+
+ public string UpperLimit
+ {
+ get { return _upperLimit; }
+ set { _upperLimit = value; OnPropertyChanged("UpperLimit"); }
+ }
+
+ public string LowerLimit
+ {
+ get { return _lowerLimit; }
+ set { _lowerLimit = value; OnPropertyChanged("LowerLimit"); }
+ }
+
+ public string Result
+ {
+ get { return _result; }
+ set { _result = value; OnPropertyChanged("Result"); }
+ }
+
+ public string Time
+ {
+ get { return _time; }
+ set { _time = value; OnPropertyChanged("Time"); }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
diff --git a/Util.ManualDebug/ManualDebugStyle.xaml b/Util.ManualDebug/ManualDebugStyle.xaml
new file mode 100644
index 0000000..cf459fb
--- /dev/null
+++ b/Util.ManualDebug/ManualDebugStyle.xaml
@@ -0,0 +1,130 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+ <!-- 棰滆壊瀹氫箟 -->
+ <SolidColorBrush x:Key="TsBgBrush" Color="#F0F2F5"/>
+ <SolidColorBrush x:Key="TsPanelBrush" Color="#FFFFFF"/>
+ <SolidColorBrush x:Key="BorderBrush" Color="#A0AEC0"/>
+ <SolidColorBrush x:Key="PrimaryBrush" Color="#2E5C8A"/>
+
+ <!-- 鐘舵�侀鑹茬敾鍒� -->
+ <SolidColorBrush x:Key="StatusOKBrush" Color="#2D8659"/>
+ <SolidColorBrush x:Key="StatusNGBrush" Color="#C53030"/>
+ <SolidColorBrush x:Key="StatusTestingBrush" Color="#3182CE"/>
+ <SolidColorBrush x:Key="StatusDefaultBrush" Color="#E0E0E0"/>
+ <SolidColorBrush x:Key="BorderDarkBrush" Color="#718096"/>
+
+ <!-- ActionButtonStyle 鎸夐挳鏍峰紡 -->
+ <Style x:Key="ActionButtonStyle" TargetType="Button">
+ <Setter Property="Height" Value="22"/>
+ <Setter Property="Padding" Value="8,0"/>
+ <Setter Property="Background" Value="White"/>
+ <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
+ <Setter Property="BorderThickness" Value="1"/>
+ <Setter Property="FontSize" Value="11"/>
+ <Setter Property="Cursor" Value="Hand"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Border Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="2"
+ Padding="{TemplateBinding Padding}">
+ <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="#F0F0F0"/>
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <!-- ManualDebug 绐楀彛涓撶敤鎸夐挳鏍峰紡 -->
+ <Style x:Key="DebugButtonStyle" TargetType="Button">
+ <Setter Property="Width" Value="100"/>
+ <Setter Property="Height" Value="32"/>
+ <Setter Property="Background" Value="White"/>
+ <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
+ <Setter Property="BorderThickness" Value="1"/>
+ <Setter Property="FontSize" Value="11"/>
+ <Setter Property="Cursor" Value="Hand"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Border Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="4"
+ Padding="{TemplateBinding Padding}">
+ <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="#E8E8E8"/>
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Background" Value="#D0D0D0"/>
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Background" Value="LightGray"/>
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <!-- DataGrid鏍峰紡 -->
+ <Style TargetType="DataGrid">
+ <Setter Property="AutoGenerateColumns" Value="False"/>
+ <Setter Property="CanUserAddRows" Value="False"/>
+ <Setter Property="CanUserDeleteRows" Value="False"/>
+ <Setter Property="HeadersVisibility" Value="Column"/>
+ <Setter Property="GridLinesVisibility" Value="All"/>
+ <Setter Property="HorizontalGridLinesBrush" Value="{StaticResource BorderBrush}"/>
+ <Setter Property="VerticalGridLinesBrush" Value="{StaticResource BorderBrush}"/>
+ <Setter Property="BorderBrush" Value="{StaticResource BorderDarkBrush}"/>
+ <Setter Property="BorderThickness" Value="1"/>
+ <Setter Property="Background" Value="White"/>
+ <Setter Property="RowBackground" Value="White"/>
+ <Setter Property="AlternatingRowBackground" Value="#F5F5F5"/>
+ <Setter Property="FontSize" Value="11"/>
+ </Style>
+
+ <Style TargetType="DataGridColumnHeader">
+ <Setter Property="Background" Value="#F5F5F5"/>
+ <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
+ <Setter Property="BorderThickness" Value="0,0,1,1"/>
+ <Setter Property="Padding" Value="4"/>
+ <Setter Property="Height" Value="26"/>
+ <Setter Property="FontWeight" Value="Normal"/>
+ </Style>
+
+ <Style TargetType="DataGridCell">
+ <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="Padding" Value="2,4"/>
+ <Style.Triggers>
+ <Trigger Property="IsSelected" Value="True">
+ <Setter Property="Background" Value="#BBDEFB"/>
+ <Setter Property="Foreground" Value="Black"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style TargetType="DataGridRow">
+ <Style.Triggers>
+ <Trigger Property="IsSelected" Value="True">
+ <Setter Property="Background" Value="#BBDEFB"/>
+ </Trigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="#E3F2FD"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+</ResourceDictionary>
diff --git a/Util.ManualDebug/StatusBtn.xaml b/Util.ManualDebug/StatusBtn.xaml
new file mode 100644
index 0000000..7b96029
--- /dev/null
+++ b/Util.ManualDebug/StatusBtn.xaml
@@ -0,0 +1,75 @@
+锘�<UserControl x:Class="Util.SB.StatusBtn"
+ 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:Util.SB"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="/Util.ManualDebug;component/ManualDebugStyle.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ <Style x:Key="StatusTextStyle" TargetType="TextBlock">
+ <Setter Property="HorizontalAlignment" Value="Center"/>
+ <Setter Property="VerticalAlignment" Value="Center"/>
+ <Setter Property="FontWeight" Value="SemiBold"/>
+ <Setter Property="FontSize" Value="12"/>
+ <Setter Property="Text" Value="-"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.NG}">
+ <Setter Property="Text" Value="NG"/>
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.OK}">
+ <Setter Property="Text" Value="OK"/>
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.Testing}">
+ <Setter Property="Text" Value="TESTING"/>
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+
+ <!-- 鐘舵�佽竟妗嗘牱寮� -->
+ <Style x:Key="StatusBorderStyle" TargetType="Border">
+ <Setter Property="Background" Value="{StaticResource StatusDefaultBrush}"/>
+ <Setter Property="CornerRadius" Value="2"/>
+ <Setter Property="HorizontalAlignment" Value="Center"/>
+ <Setter Property="Width" Value="100"/>
+ <Setter Property="Height" Value="24"/>
+ <Setter Property="Margin" Value="0,5,0,0"/>
+
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.NG}">
+ <Setter Property="Background" Value="{StaticResource StatusNGBrush}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.OK}">
+ <Setter Property="Background" Value="{StaticResource StatusOKBrush}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.Testing}">
+ <Setter Property="Background" Value="{StaticResource StatusTestingBrush}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="btnStyle" TargetType="Button" BasedOn="{StaticResource DebugButtonStyle}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static local:DebugStatus.Testing}">
+ <Setter Property="IsEnabled" Value="False"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ResourceDictionary>
+
+ </UserControl.Resources>
+ <StackPanel>
+ <Button x:Name="btn" Content="{Binding Title}" Style="{StaticResource btnStyle}" Click="Button_Click"/>
+ <Border Style="{StaticResource StatusBorderStyle}">
+ <TextBlock Style="{StaticResource StatusTextStyle}"/>
+ </Border>
+ </StackPanel>
+</UserControl>
diff --git a/Util.ManualDebug/StatusBtn.xaml.cs b/Util.ManualDebug/StatusBtn.xaml.cs
new file mode 100644
index 0000000..11c2783
--- /dev/null
+++ b/Util.ManualDebug/StatusBtn.xaml.cs
@@ -0,0 +1,40 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Util.SB
+{
+ // 鐘舵�佹灇涓�
+ public enum DebugStatus
+ {
+ Idle = 0, // 绌洪棽
+ Testing = 1, // 娴嬭瘯涓�
+ OK = 2, // 閫氳繃
+ NG = 3 // 澶辫触
+ }
+ /// <summary>
+ /// StatusBtn.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class StatusBtn : UserControl
+ {
+ public event RoutedEventHandler BtnClick;
+
+ public StatusBtn()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ [ObservableProperty]
+ private string title = string.Empty;
+
+ [ObservableProperty]
+ private DebugStatus status = DebugStatus.Idle;
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ BtnClick?.Invoke(this, e);
+ }
+ }
+}
diff --git a/Util.ManualDebug/Util.ManualDebug.csproj b/Util.ManualDebug/Util.ManualDebug.csproj
new file mode 100644
index 0000000..fcf9c6e
--- /dev/null
+++ b/Util.ManualDebug/Util.ManualDebug.csproj
@@ -0,0 +1,33 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <Platforms>AnyCPU;x64;x86</Platforms>
+ <FileVersion>1.0.0.0</FileVersion>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Plugin.TsSupport\Plugin.TsSupport.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Reference Include="NationalInstruments.TestStand.Interop.API">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="WindowsFormsIntegration" />
+ </ItemGroup>
+
+</Project>
diff --git a/WPFProject/App.config b/WPFProject/App.config
index d9a1988..fabccd6 100644
--- a/WPFProject/App.config
+++ b/WPFProject/App.config
@@ -9,7 +9,7 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <probing privatePath="Libs;ThirdParty;Plugin;3rds;Api;" />
+ <probing privatePath="Libs;ThirdParty;Plugin;3rds;Api;OpenTap;" />
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
diff --git a/WPFProject/App.xaml.cs b/WPFProject/App.xaml.cs
index c63a2e2..f20a0c6 100644
--- a/WPFProject/App.xaml.cs
+++ b/WPFProject/App.xaml.cs
@@ -93,7 +93,7 @@
{
var process = GetProcess();
- mutex = new Mutex(true, "TestPlatform_OnlyRun_CRNS");
+ mutex = new Mutex(true, "TestPlatform_OnlyRun_CRNS__");
if (mutex.WaitOne(0, false))//&& process == null
{
WriteRegister();
diff --git a/WPFProject/Controls/MainTabControl.xaml b/WPFProject/Controls/MainTabControl.xaml
index 3e49600..d48c9c8 100644
--- a/WPFProject/Controls/MainTabControl.xaml
+++ b/WPFProject/Controls/MainTabControl.xaml
@@ -159,7 +159,7 @@
<DockPanel Background="Transparent">
<Border DockPanel.Dock="Left" BorderThickness="1,1,0,1" Background="Transparent" BorderBrush="{StaticResource PrimaryColor}" Width="50"></Border>
<ListBox DockPanel.Dock="Left" Grid.Row="0" x:Name="Menu"
- Style="{StaticResource ListBoxItemStyle1}" FontSize="16"
+ Style="{StaticResource ListBoxItemStyle1}" FontSize="14"
BorderBrush="{StaticResource PrimaryColor}"
BorderThickness="1"
SelectionChanged="Menu_SelectionChanged"
diff --git a/WPFProject/Controls/MainTabControl.xaml.cs b/WPFProject/Controls/MainTabControl.xaml.cs
index a476ebd..72ae3eb 100644
--- a/WPFProject/Controls/MainTabControl.xaml.cs
+++ b/WPFProject/Controls/MainTabControl.xaml.cs
@@ -1,6 +1,7 @@
锘縰sing HMI.Base;
using HMI.Core.Api;
using Panuon.WPF.UI;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
@@ -11,6 +12,12 @@
namespace WPFProject.Controls
{
+ public class TabChangedEventArg
+ {
+ public IPlugin oldValue { get; set; }
+ public IPlugin newValue { get; set; }
+ }
+
/// <summary>
/// MainTabControl.xaml 鐨勪氦浜掗�昏緫
/// </summary>
@@ -46,21 +53,7 @@
}
// Tab鍒囨崲浜嬩欢
- public static readonly RoutedEvent OnTabChangeEvent =
- EventManager.RegisterRoutedEvent("OnTabChange", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MenuTabControl));
-
- public event RoutedEventHandler OnTabChange
- {
- add
- {
- AddHandler(OnTabChangeEvent, value);
- }
-
- remove
- {
- RemoveHandler(OnTabChangeEvent, value);
- }
- }
+ public event EventHandler<TabChangedEventArg> TabChanged;
private ObservableCollection<PluginInfo> _MenuItems;
@@ -193,6 +186,7 @@
{
page.Child = (UIElement)content;
}
+ TabChanged?.Invoke(this, new TabChangedEventArg { oldValue = last, newValue = newPlugin });
}
}
diff --git a/WPFProject/Lang/en-US/TestResult.json b/WPFProject/Lang/en-US/TestResult.json
index cc222d3..ae6c6b8 100644
--- a/WPFProject/Lang/en-US/TestResult.json
+++ b/WPFProject/Lang/en-US/TestResult.json
@@ -50,5 +50,7 @@
"Tr.CantClearSNR": "Program is running, can't clear snr!",
"Tr.MakeSureStopOvenTest": "Are you sure you want stop [{0}] test?",
"Tr.PositionCantClearSNR": "Position [{0}] can't clear snr now!",
+ "Tr.MakeSureStopAllTest": "Are you sure you want to stop test?",
+ "Tr.OvenIsTesting": "Oven is testing, can't stop test.'",
"Tr.TestProgram": "Test Program"
}
\ No newline at end of file
diff --git a/WPFProject/Lang/en-US/app.json b/WPFProject/Lang/en-US/app.json
index 88da64d..ebacd15 100644
--- a/WPFProject/Lang/en-US/app.json
+++ b/WPFProject/Lang/en-US/app.json
@@ -104,7 +104,7 @@
"App.MenuLoadFailed": "{0} load failed: {1} {2}",
"App.MenuCount": "There are {0} menus is loading...",
"App.SelectIcon": "Select icon",
- "App.Welcome": "Welcom! {0}",
+ "App.Welcome": "Welcome! {0}",
"App.MakeSureLogout": "Are you sure you want to logout?",
"App.MakeSureRestartApp": "Are you sure you want to restart锛�",
"App.NoExportData": "No Data To Export",
@@ -159,5 +159,11 @@
"App.ScannerSetting": "Scanner Setting",
"App.SequenceIsStarting": "Starting Test,Please Wait...",
"App.Status": "Status",
- "App.LoadPluginError": "Load plugin error,please check."
+ "App.LoadPluginError": "Load plugin error,please check.",
+ "App.Version": "Ver.",
+ "App.PluginVersion": "Plugin Ver.",
+ "App.CPUUsage": "CPU Usage",
+ "App.RemUsage": "Rem Usage",
+ "App.TotalCPUUsage": "PC CPU Usage",
+ "App.TotalRemUsage": "PC Rem Usage"
}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/TestResult.json b/WPFProject/Lang/zh-CN/TestResult.json
index 0d6ea0e..411cb80 100644
--- a/WPFProject/Lang/zh-CN/TestResult.json
+++ b/WPFProject/Lang/zh-CN/TestResult.json
@@ -50,5 +50,7 @@
"Tr.CantClearSNR": "绋嬪簭杩愯涓紝涓嶈兘娓呯┖鏉$爜",
"Tr.MakeSureStopOvenTest": "纭疄鍋滄鑰佸寲鐐塠{0}]鐨勬祴璇曞悧锛�",
"Tr.PositionCantClearSNR": "绌翠綅[{0}]褰撳墠涓嶅厑璁告竻闄ゆ潯鐮侊紒",
+ "Tr.MakeSureStopAllTest": "纭畾瑕佸仠姝㈡墍鏈夋祴璇曞悧锛�",
+ "Tr.OvenIsTesting": "鏈変粨浣嶆鍦ㄦ祴璇曚腑锛屼笉鑳藉仠姝㈡祴璇�",
"Tr.TestProgram": "娴嬭瘯绋嬪簭"
}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/app.json b/WPFProject/Lang/zh-CN/app.json
index 6684cdf..6194e08 100644
--- a/WPFProject/Lang/zh-CN/app.json
+++ b/WPFProject/Lang/zh-CN/app.json
@@ -158,5 +158,11 @@
"App.ScannerSetting": "鎵爜鏋缃�",
"App.SequenceIsStarting": "姝e湪鍚姩娴嬭瘯搴忓垪锛岃绋嶅悗...",
"App.Status": "鐘舵��",
- "App.LoadPluginError": "鍔犺浇鍑洪敊锛岃纭"
+ "App.LoadPluginError": "鍔犺浇鍑洪敊锛岃纭",
+ "App.Version": "杞欢鐗堟湰:",
+ "App.PluginVersion": "鎻掍欢鐗堟湰:",
+ "App.CPUUsage": "CPU浣跨敤",
+ "App.RemUsage": "鍐呭瓨浣跨敤",
+ "App.TotalCPUUsage": "鎬籆PU浣跨敤",
+ "App.TotalRemUsage": "鎬诲唴瀛樹娇鐢�"
}
\ No newline at end of file
diff --git a/WPFProject/PanuonWindow.xaml b/WPFProject/PanuonWindow.xaml
index 943d9d0..b783a52 100644
--- a/WPFProject/PanuonWindow.xaml
+++ b/WPFProject/PanuonWindow.xaml
@@ -22,7 +22,7 @@
pu:WindowXCaption.HeaderAlignment="Stretch"
Title="TestPlatform"
pu:WindowXCaption.Background="Transparent"
- pu:WindowXCaption.Height="80"
+ pu:WindowXCaption.Height="60"
IsOverlayerVisible="True"
pu:WindowXCaption.Foreground="#FFF">
<Window.Resources>
@@ -40,7 +40,6 @@
<Setter Property="pu:MenuHelper.TopLevelItemsHoverBackground" Value="{x:Null}"/>
<Setter Property="pu:MenuHelper.TopLevelDropDownPlacement" Value="BottomLeft"/>
</Style>
-
</Window.Resources>
<Window.Background>
<ImageBrush Stretch="Uniform" AlignmentX="Left" AlignmentY="Top"
@@ -49,9 +48,10 @@
<pu:WindowXCaption.HeaderTemplate>
<DataTemplate>
- <DockPanel DataContext="{Binding ElementName=window}" WindowChrome.IsHitTestVisibleInChrome="True" VerticalAlignment="Center" Height="100">
+ <DockPanel DataContext="{Binding ElementName=window}" WindowChrome.IsHitTestVisibleInChrome="True"
+ VerticalAlignment="Center" Height="80">
<StackPanel Orientation="Horizontal">
- <Image DockPanel.Dock="Left" Source="{Binding WindowLogo}" Margin="5,0,20,0" Height="60" VerticalAlignment="Center" Stretch="Fill"
+ <Image DockPanel.Dock="Left" Source="{Binding WindowLogo}" Margin="5,0,20,0" Height="40" VerticalAlignment="Center" Stretch="Fill"
RenderOptions.BitmapScalingMode="HighQuality" />
<TextBlock FontSize="30" VerticalAlignment="Center" Text="{Binding WindowTitle}">
<TextBlock.Effect>
@@ -71,9 +71,7 @@
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" VerticalAlignment="Top" Margin="10,10,0,0" Orientation="Horizontal">
<Menu Margin="0" Padding="0" VerticalAlignment="Top"
- VerticalContentAlignment="Center" Style="{StaticResource UserMenu}"
-
- Background="Transparent">
+ VerticalContentAlignment="Center" Style="{StaticResource UserMenu}" Background="Transparent">
<MenuItem x:Name="userMenu" Header="{Binding WelcomeTitle}" FontSize="16">
<MenuItem Icon="" Cursor="Hand" FontSize="14" Header="閫�鍑虹櫥褰�"
x:Name="MiLogout" Click="MenuItem_Click"/>
@@ -131,11 +129,14 @@
</Button.Style>
</Button>
</StackPanel>
- <Button Grid.Row="1" Margin="20,0,0,20" Foreground="#FFF"
- Visibility="{Binding Alarms.Count,Converter={StaticResource cv}}"
- HorizontalContentAlignment="Left" Style="{StaticResource LinkButton}"
- Click="Clear_AllAlarm_Click"
- Content="娓呴櫎鍏ㄩ儴鎶ヨ"/>
+ <DockPanel Margin="20,0,0,20" Grid.Row="1" LastChildFill="False">
+ <Button DockPanel.Dock="Left" Foreground="#FFF"
+ Visibility="{Binding Alarms.Count,Converter={StaticResource cv}}"
+ HorizontalContentAlignment="Left" Style="{StaticResource LinkButton}"
+ Click="Clear_AllAlarm_Click"
+ Content="娓呴櫎鍏ㄩ儴鎶ヨ"/>
+ <!--<local:ResourceUI x:Name="resourceUI" Loaded="resourceUI_Loaded" DockPanel.Dock="Right"/>-->
+ </DockPanel>
</Grid>
<ListBox x:Name="list"
@@ -234,7 +235,7 @@
<Setter Property="Padding" Value="0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
- <Setter Property="Height" Value="70"/>
+ <Setter Property="Height" Value="50"/>
<Setter Property="Margin" Value="0,0,0,1"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
@@ -254,13 +255,27 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
- <ctl:MainTabControl Grid.Row="0" x:Name="menuTab">
+ <ctl:MainTabControl Grid.Row="0" x:Name="menuTab" TabChanged="menuTab_TabChanged">
</ctl:MainTabControl>
<!--<ctl:MenuTabControl Grid.Row="1" x:Name="menuTab" OnTabChange="menuTab_OnTabChange"> </ctl:MenuTabControl>-->
- <!--<StatusBar Grid.Row="1" Background="{StaticResource HoriBar}"></StatusBar>-->
+ <DockPanel Grid.Row="1" Height="20" Background="{StaticResource PrimaryColor}" LastChildFill="False">
+
+ <TextBlock Margin="20,0,0,0" FontSize="14" VerticalAlignment="Center" Foreground="#FFF">
+<Run Text="{DynamicResource App.Version}"/>
+<Run Text="{Binding SoftwareVersion}"/>
+ </TextBlock>
+
+ <TextBlock Margin="20,0,0,0" FontSize="14" VerticalAlignment="Center" Foreground="#FFF">
+<Run Text="{DynamicResource App.PluginVersion}"/>
+<Run Text="{Binding PluginVersion}"/>
+ </TextBlock>
+
+ <local:ResourceUI FontSize="14" Margin="0,1,20,1" DockPanel.Dock="Right" x:Name="resourceUI"/>
+
+ </DockPanel>
</Grid>
</pu:WindowX>
diff --git a/WPFProject/PanuonWindow.xaml.cs b/WPFProject/PanuonWindow.xaml.cs
index 3ed72b3..06799af 100644
--- a/WPFProject/PanuonWindow.xaml.cs
+++ b/WPFProject/PanuonWindow.xaml.cs
@@ -5,12 +5,14 @@
using HMI.Core.Util;
using HMI.UI.Util;
using HMI.Util.Alarm;
+using log4net;
using Panuon.WPF.UI;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
@@ -33,9 +35,11 @@
/// </summary>
public partial class PanuonWindow : WindowX, IPluginContainer, IAlarmShow
{
+ private ILog log = LogManager.GetLogger("MainWindow");
public PanuonWindow()
{
this.Loaded += PanuonWindow_Loaded;
+ SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
private UserInfo currentUser;
@@ -73,6 +77,26 @@
get => Alarms?.Count ?? 0;
}
+ private string softwareVersion;
+ public string SoftwareVersion
+ {
+ get => softwareVersion;
+ set
+ {
+ Set(ref softwareVersion, value);
+ }
+ }
+
+ private string pluginVersion;
+ public string PluginVersion
+ {
+ get => pluginVersion;
+ set
+ {
+ Set(ref pluginVersion, value);
+ }
+ }
+
public ListBox sb
{
get; set;
@@ -80,17 +104,28 @@
private void PanuonWindow_Loaded(object sender, RoutedEventArgs e)
{
- DataContext = this;
- RefrshConfig();
- InitializeComponent();
- AlarmShowHelper.Register(this);
- var sb = WindowXCaption.GetHeaderTemplate(this);
- //sb.FindName("list",this.Con);
+ try
+ {
+ DataContext = this;
+ RefrshConfig();
+ InitializeComponent();
+ AlarmShowHelper.Register(this);
- WelcomeTitle = this.lang("App.Welcome", UserInfo.User.Name);
- ShowMenu = false;
- Application.Current.MainWindow = this;
- SystemSetting.SystemSettingChanged += SystemSetting_SystemSettingChanged;
+ WelcomeTitle = this.lang("App.Welcome", UserInfo.User.Name);
+ ShowMenu = false;
+ Application.Current.MainWindow = this;
+ SystemSetting.SystemSettingChanged += SystemSetting_SystemSettingChanged;
+
+ Task.Run(() =>
+ {
+ ResourceListener.Instance.RefreshEvent += this.resourceUI.Refresh;
+ ResourceListener.Instance.Start();
+ });
+ }
+ catch (Exception ex)
+ {
+ log.Error("Window Loaded Error.", ex);
+ }
}
private void RefrshConfig()
@@ -223,6 +258,7 @@
{
try
{
+ ResourceListener.Instance.Stop();
AlarmUtil.Release();
PluginLoader.Reset();
UserInfo.Logout();
@@ -232,7 +268,7 @@
{
}
- Application.Current.Shutdown();
+ Application.Current.Shutdown(0);
}
private void Button_Click(object sender, RoutedEventArgs e)
@@ -296,6 +332,21 @@
Alarms?.Clear();
}
+ private void menuTab_TabChanged(object sender, Controls.TabChangedEventArg e)
+ {
+ Dispatcher.BeginInvoke(() =>
+ {
+ if (e.newValue == null)
+ {
+ PluginVersion = string.Empty;
+ }
+ else
+ {
+ PluginVersion = e.newValue.GetType().Assembly.GetName().Version.ToString();
+ }
+ }, System.Windows.Threading.DispatcherPriority.Normal);
+ }
+
//private void BaseWindow_Loaded(object sender, RoutedEventArgs e)
//{
// var s = (Style)this.Resources["WindowButton"];
diff --git a/WPFProject/Properties/AssemblyInfo.cs b/WPFProject/Properties/AssemblyInfo.cs
index a10859f..c79e593 100644
--- a/WPFProject/Properties/AssemblyInfo.cs
+++ b/WPFProject/Properties/AssemblyInfo.cs
@@ -53,6 +53,6 @@
//鍙互鎸囧畾鎵�鏈夎繖浜涘�硷紝涔熷彲浠ヤ娇鐢ㄢ�滅敓鎴愬彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊�
//閫氳繃浣跨敤 "*"锛屽涓嬫墍绀�:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.0.1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: XmlConfigurator(ConfigFile = "Config/log4net.config", Watch = true)]
\ No newline at end of file
diff --git a/WPFProject/ResourceListener.cs b/WPFProject/ResourceListener.cs
new file mode 100644
index 0000000..a03f00e
--- /dev/null
+++ b/WPFProject/ResourceListener.cs
@@ -0,0 +1,135 @@
+锘縰sing HMI.Simple.Util;
+using log4net;
+using System;
+using System.Diagnostics;
+using System.Management;
+using System.Timers;
+using System.Xml.Linq;
+
+namespace WPFProject
+{
+ public class RunTimeState
+ {
+ public float cpuRate { get; set; }
+ public double remRate { get; set; }
+
+ public float totalCpuRate { get; set; }
+ public double totalRemRate { get; set; }
+ }
+
+ public class ResourceListener
+ {
+ public event EventHandler<RunTimeState> RefreshEvent;
+ private Timer timer;
+ private System.Threading.CancellationTokenSource _can;
+
+ private static ResourceListener instance;
+ public static ResourceListener Instance
+ {
+ get
+ {
+
+ if (instance == null)
+ {
+ instance = new ResourceListener();
+ }
+ return instance;
+ }
+ }
+ private ILog log = LogManager.GetLogger("ResourceListener");
+
+ // CPU鍗犵敤
+ private PerformanceCounter totalCpuCounter;
+
+ private PerformanceCounter cpuCounter;
+
+ private ResourceListener()
+ {
+ totalCpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
+ cpuCounter = new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName, true);
+ }
+
+ public void Start()
+ {
+ _can = new System.Threading.CancellationTokenSource();
+ Refresh();
+ timer = new Timer();
+ timer.AutoReset = false;
+ timer.Interval = 30000;
+ timer.Elapsed += Timer_Elapsed;
+ timer.Enabled = true;
+ }
+
+ private void Refresh()
+ {
+ try
+ {
+ var _cpuCount = Environment.ProcessorCount;
+ ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
+ ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql);
+
+ string prcName = Process.GetCurrentProcess().ProcessName;
+ var counter_Exec = new PerformanceCounter("Process", "Working Set - Private", prcName);
+ ulong dWsp_Exec = (ulong)(counter_Exec.RawValue / 1024);
+
+ var totalCpuRate = totalCpuCounter.NextValue();
+ var cpuRate = cpuCounter.NextValue() / _cpuCount;
+
+ foreach (ManagementObject obj in searcher.Get())
+ {
+ ulong totalVisibleMemorySize = (ulong)obj["TotalVisibleMemorySize"];
+ ulong freePhysicalMemory = (ulong)obj["FreePhysicalMemory"];
+
+ ulong usedMemory = totalVisibleMemorySize - freePhysicalMemory;
+ string info = $"\r\n鎬诲唴瀛�: {totalVisibleMemorySize / 1024} MB\r\n";
+
+ info += $"宸蹭娇鐢ㄥ唴瀛�: {usedMemory / 1024} MB\r\n";
+ double usagePercent = usedMemory * 100d / totalVisibleMemorySize;
+ info += $"鍐呭瓨鍗犵敤鐜�: {usagePercent:F2}%\r\n";
+
+ info += $"搴旂敤鍗犵敤鍐呭瓨: {dWsp_Exec / 1024} MB\r\n";
+ double appPercent = dWsp_Exec * 100d / totalVisibleMemorySize;
+ info += $"搴旂敤鍐呭瓨鍗犵敤鐜�: {appPercent:F2}%";
+ RefreshEvent?.Invoke(this, new RunTimeState
+ {
+ cpuRate = cpuRate,
+ remRate = appPercent,
+ totalCpuRate = totalCpuRate,
+ totalRemRate = usagePercent
+ });
+ log.Info(info);
+ if (usagePercent > 80)
+ {
+ // AlarmUtil.CreateAlarm("App", "鍐呭瓨鍗犵敤杩囬珮锛岃秴80%", out _);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Refresh Resource Error.", ex);
+ }
+ }
+
+ private void Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ try
+ {
+ timer.Enabled = false;
+ _can.Token.ThrowIfCancellationRequested();
+ Refresh();
+ timer.Enabled = true;
+ }
+ catch
+ {
+
+ }
+ }
+
+ public void Stop()
+ {
+ _can?.Cancel();
+ _can?.Dispose();
+ instance = null;
+ }
+ }
+}
diff --git a/WPFProject/Settings.ini b/WPFProject/Settings.ini
new file mode 100644
index 0000000..2f052e0
--- /dev/null
+++ b/WPFProject/Settings.ini
@@ -0,0 +1,6 @@
+[Btns]
+;名称=ActionName
+上电激活=Active
+CAN测试=CanTest
+LIN测试=LinTest
+DoIP测试=DOIPTest
\ No newline at end of file
diff --git a/WPFProject/UI/ResourceUI.xaml b/WPFProject/UI/ResourceUI.xaml
new file mode 100644
index 0000000..6a2050e
--- /dev/null
+++ b/WPFProject/UI/ResourceUI.xaml
@@ -0,0 +1,63 @@
+锘�<hb:NotifyControl x:Class="WPFProject.ResourceUI"
+ 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:WPFProject.UI"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <hb:NotifyControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <pu:StyleDictionary Includes="Label" />
+ </ResourceDictionary.MergedDictionaries>
+ <Style x:Key="def" TargetType="Label" BasedOn="{StaticResource {x:Static pu:StyleKeys.LabelStyle}}">
+ <Setter Property="pu:LabelHelper.CornerRadius" Value="3"/>
+ <Setter Property="Padding" Value="5,0"/>
+ <Setter Property="Margin" Value="0"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="Foreground" Value="#FFF"/>
+ </Style>
+ </ResourceDictionary>
+ </hb:NotifyControl.Resources>
+
+ <Grid dp:GridHelper.Space="10" dp:GridHelper.SpaceIgnore="ALL">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+
+ <Label Grid.Column="0" Style="{StaticResource def}" x:Name="l1">
+ <TextBlock>
+ <Run Text="{DynamicResource App.CPUUsage}"/>
+ <Run Text="{Binding CpuRate}"/>
+ </TextBlock>
+ </Label>
+
+ <Label Grid.Column="1" Style="{StaticResource def}" x:Name="l2">
+ <TextBlock>
+ <Run Text="{DynamicResource App.RemUsage}"/>
+ <Run Text="{Binding RemRate}"/>
+ </TextBlock>
+ </Label>
+
+ <Label Grid.Column="2" Style="{StaticResource def}" x:Name="l3">
+ <TextBlock Grid.Column="2">
+ <Run Text="{DynamicResource App.TotalCPUUsage}"/>
+ <Run Text="{Binding TotalCpuRate}"/>
+ </TextBlock>
+ </Label>
+
+ <Label Grid.Column="3" Style="{StaticResource def}" x:Name="l4">
+ <TextBlock Grid.Column="3">
+ <Run Text="{DynamicResource App.TotalRemUsage}"/>
+ <Run Text="{Binding TotalRemRate}"/>
+ </TextBlock>
+ </Label>
+ </Grid>
+</hb:NotifyControl>
diff --git a/WPFProject/UI/ResourceUI.xaml.cs b/WPFProject/UI/ResourceUI.xaml.cs
new file mode 100644
index 0000000..7efd5f2
--- /dev/null
+++ b/WPFProject/UI/ResourceUI.xaml.cs
@@ -0,0 +1,91 @@
+锘縰sing HMI.Base;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace WPFProject
+{
+ /// <summary>
+ /// ResourceListener.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ResourceUI : NotifyControl
+ {
+ private string cpuRate;
+ public string CpuRate
+ {
+ get => cpuRate;
+ set
+ {
+ Set(ref cpuRate, value);
+ }
+ }
+
+ private string remRate;
+ public string RemRate
+ {
+ get => remRate;
+ set
+ {
+ Set(ref remRate, value);
+ }
+ }
+
+ private string totalCpuRate;
+ public string TotalCpuRate
+ {
+ get => totalCpuRate;
+ set
+ {
+ Set(ref totalCpuRate, value);
+ }
+ }
+
+ private string totalRemRate;
+ public string TotalRemRate
+ {
+ get => totalRemRate;
+ set
+ {
+ Set(ref totalRemRate, value);
+ }
+ }
+
+ public ResourceUI()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ public void Refresh(object sender, RunTimeState state)
+ {
+ Dispatcher.BeginInvoke(() =>
+ {
+ CpuRate = $"{state.cpuRate:F1}%";
+ SetColor(state.cpuRate, l1);
+ RemRate = $"{state.remRate:F1}%";
+ SetColor(state.remRate, l2);
+
+ TotalCpuRate = $"{state.totalCpuRate:F1}%";
+ SetColor(state.totalCpuRate, l3);
+ TotalRemRate = $"{state.totalRemRate:F1}%";
+ SetColor(state.totalRemRate, l4);
+ }, System.Windows.Threading.DispatcherPriority.Normal);
+ }
+
+ private void SetColor(double val, Label label)
+ {
+ if (val > 80)
+ {
+ label.Background = Brushes.Red;
+ }
+ else if (val > 60)
+ {
+ label.Background = Brushes.Orange;
+ }
+ else
+ {
+ label.Background = Application.Current.FindResource("SecondPrimaryColor") as Brush;
+ }
+ }
+ }
+}
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 6e6566b..10f5341 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -198,6 +198,10 @@
<Compile Include="PanuonWindow.xaml.cs">
<DependentUpon>PanuonWindow.xaml</DependentUpon>
</Compile>
+ <Compile Include="ResourceListener.cs" />
+ <Compile Include="UI\ResourceUI.xaml.cs">
+ <DependentUpon>ResourceUI.xaml</DependentUpon>
+ </Compile>
<Compile Include="UI\TestWindow.xaml.cs">
<DependentUpon>TestWindow.xaml</DependentUpon>
</Compile>
@@ -239,6 +243,10 @@
<DependentUpon>MenuTabControl.xaml</DependentUpon>
</Compile>
<Page Include="PanuonWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="UI\ResourceUI.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -299,6 +307,9 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="鍙樻洿璁板綍\2025-12-24.txt" />
+ <None Include="Settings.ini">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
<Resource Include="Icon\b1.jpg" />
<Resource Include="Icon\b2.jpg" />
<Resource Include="Icon\b3.jpg" />
@@ -437,6 +448,10 @@
<ProjectReference Include="..\ModBusTcpController\ModBusTcpController.csproj">
<Project>{49db0c9b-b239-4608-a91e-f5ed43afaf96}</Project>
<Name>ModBusTcpController</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Plugin.DataViewer\Plugin.DataViewer.csproj">
+ <Project>{dbfe5040-963f-4bbf-93fb-26b3f18fda90}</Project>
+ <Name>Plugin.DataViewer</Name>
</ProjectReference>
<ProjectReference Include="..\Plugin.SeqEditor\Plugin.SeqEditor.csproj">
<Project>{1260f995-1ae9-17b6-feb5-c430c1416bec}</Project>
@@ -587,6 +602,8 @@
move /y "$(TargeDir)Plugin.ModelManage.dll" $(TargeDir)Plugin\Plugin.ModelManage.dll"
move /y "$(TargeDir)Plugin.CurrentSensorControl.dll" $(TargeDir)Plugin\Plugin.CurrentSensorControl.dll"
move /y "$(TargeDir)Plugin.TsSupport.dll" $(TargeDir)Plugin\Plugin.TsSupport.dll"
+move /y "$(TargeDir)Plugin.DataViewer.dll" $(TargeDir)Plugin\Plugin.DataViewer.dll"
+move /y "$(TargeDir)Util.ManualDebug.dll" $(TargeDir)Plugin\Util.ManualDebug.dll"
setlocal enabledelayedexpansion
@@ -609,7 +626,7 @@
)
for %25%25F in ("%25source_folder%25\*") do (
- if /I not "%25%25~nxF"=="$(TargetFileName)" if /I not "%25%25~nxF"=="$(TargetFileName).config" if /I not "%25%25~nxF"=="$(TargetName).pdb" if /I not "%25%25~nxF"=="clear.bat" if /I not "%25%25~nxF"=="瀹夎MSMQ.bat" (
+ if /I not "%25%25~nxF"=="$(TargetFileName)" if /I not "%25%25~nxF"=="$(TargetFileName).config" if /I not "%25%25~nxF"=="$(TargetName).pdb" if /I not "%25%25~nxF"=="clear.bat" if /I not "%25%25~nxF"=="瀹夎MSMQ.bat" if /I not "%25%25~nxF"=="Settings.ini" (
move /Y "%25%25F" "%25destination_folder%25"
)
)
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index ba5a291..b4b4b91 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -75,6 +75,16 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.SeqEditor", "..\Plugin.SeqEditor\Plugin.SeqEditor.csproj", "{1260F995-1AE9-17B6-FEB5-C430C1416BEC}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.DataViewer", "..\Plugin.DataViewer\Plugin.DataViewer.csproj", "{DBFE5040-963F-4BBF-93FB-26B3F18FDA90}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.UICollection", "..\Plugin.UICollection\Plugin.UICollection.csproj", "{22DC8D91-50B2-47CA-86A8-29A6DA48F388}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtilLib", "..\..\UtilLib\UtilLib.csproj", "{A132F114-A26B-4428-BAEC-4851F38C0E14}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UILib", "..\..\UILib\UILib.csproj", "{27325FE0-3CE2-4CD5-8EB5-7E45CC441479}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Util.ManualDebug", "..\Util.ManualDebug\Util.ManualDebug.csproj", "{D0944E62-EE52-4ABE-832A-A09D98814DB1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -505,6 +515,66 @@
{1260F995-1AE9-17B6-FEB5-C430C1416BEC}.Release|x64.Build.0 = Release|x64
{1260F995-1AE9-17B6-FEB5-C430C1416BEC}.Release|x86.ActiveCfg = Release|x86
{1260F995-1AE9-17B6-FEB5-C430C1416BEC}.Release|x86.Build.0 = Release|x86
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Debug|x64.Build.0 = Debug|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Debug|x86.Build.0 = Debug|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Release|x64.ActiveCfg = Release|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Release|x64.Build.0 = Release|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Release|x86.ActiveCfg = Release|Any CPU
+ {DBFE5040-963F-4BBF-93FB-26B3F18FDA90}.Release|x86.Build.0 = Release|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Debug|x64.Build.0 = Debug|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Debug|x86.Build.0 = Debug|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Release|x64.ActiveCfg = Release|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Release|x64.Build.0 = Release|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Release|x86.ActiveCfg = Release|Any CPU
+ {22DC8D91-50B2-47CA-86A8-29A6DA48F388}.Release|x86.Build.0 = Release|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Debug|x64.Build.0 = Debug|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Debug|x86.Build.0 = Debug|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Release|x64.ActiveCfg = Release|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Release|x64.Build.0 = Release|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Release|x86.ActiveCfg = Release|Any CPU
+ {A132F114-A26B-4428-BAEC-4851F38C0E14}.Release|x86.Build.0 = Release|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Debug|x64.Build.0 = Debug|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Debug|x86.Build.0 = Debug|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Release|Any CPU.Build.0 = Release|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Release|x64.ActiveCfg = Release|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Release|x64.Build.0 = Release|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Release|x86.ActiveCfg = Release|Any CPU
+ {27325FE0-3CE2-4CD5-8EB5-7E45CC441479}.Release|x86.Build.0 = Release|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Debug|x64.ActiveCfg = Debug|x64
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Debug|x64.Build.0 = Debug|x64
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Debug|x86.ActiveCfg = Debug|x86
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Debug|x86.Build.0 = Debug|x86
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x64.ActiveCfg = Release|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x64.Build.0 = Release|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x86.ActiveCfg = Release|Any CPU
+ {D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
--
Gitblit v1.9.1