alielie
2025-03-13 ba6207f52db76ab47cd6534de0cf1712674ff179
完善国际化语言;
76个文件已修改
29个文件已添加
2 文件已重命名
84个文件已删除
86203 ■■■■■ 已修改文件
HMI.AlermInfoManage/AlarmInfoManage.xaml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmInfoManage.xaml.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmInfoManage_SettingA.xaml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmInfoManage_SettingA.xaml.cs 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmSettingList.xaml 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmSettingList.xaml.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Base/PluginLoader.cs 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Core/Setting/SystemSetting.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Core/Util/LangUtil.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Core/Util/SqliteHelper.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.Core/Util/XmlHelper.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/DataViewer.xaml 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/DataViewer.xaml.cs 370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/DbSettingModal.xaml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/DbSettingModal.xaml.cs 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/HMI.DataViewer.csproj 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.DataViewer/packages.config 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.IOMonitor/HMI.IOMonitor.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.IOMonitor/IOMonitor.xaml 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.IOMonitor/IOMonitor.xaml.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.IOMonitor/IPManageModal.xaml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.IOMonitor/IPManageModal.xaml.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.LogViewer/HMI.LogViewer.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.MenuManage/HMI.MenuManage.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.MenuManage/MenuManage.xaml.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.MenuManage/Modal/MenuModal.xaml.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.MenuManage/Modal/RoleModal.xaml.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.MenuManage/Modal/UserModal.xaml.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.MenuManage/RoleManage.xaml.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/HMI.ParameterManage.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/Model/XmlModel.cs 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterManage.xaml 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterManage.xaml.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterModal.xaml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterModal.xaml.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterSetting.xaml 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ParameterSetting.xaml.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ProductModal.xaml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/ProductModal.xaml.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.ParameterManage/Util/ParameterManager.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.SettingControl/HMI.SettingControl.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/DpUtil/DataGridTextColumnHelper.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/DpUtil/FormGroupHelper.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/HMI.UI.csproj 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/Resources/Font/iconfont.json 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/Resources/Font/iconfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/Style/FormStyle.xaml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/Style/PanuonResource.xaml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.UI/Util/MsgBoxHelper.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/CommonLibs.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/ConfigManage.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/DatabaseHelper.dll.config 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/DatabaseHelper.xml 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/FTPTool.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/FactoryControl.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/FactoryControlX.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/FactoryControlX.xml 518 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/GetMD5Value.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/HMI.Framework.Logger.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/ICSharpCode.SharpZipLib.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/KeyGenDlls.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/KeyboardControl.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/KeyboardControl.xml 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LSMSInterface.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LSMSInterface.xml 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LTMES.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LTSCADA.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LTSCADAApi.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LTSqlHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LTSqlHelper.dll.config 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LV2CSharp.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LV2CSharp.xml 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/LampHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/MenuHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Microsoft.Practices.Unity.Configuration.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Microsoft.Practices.Unity.RegistrationByConvention.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Microsoft.Practices.Unity.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NPOI.OOXML.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NPOI.OpenXml4Net.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NPOI.OpenXmlFormats.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NPOI.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.API.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.API.xml 21060 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.AdapterAPI.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.AdapterAPI.xml 6819 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.SequenceAnalyzer.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.UI.AxControls.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.UI.Support.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.UI.Support.xml 1277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.UI.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Interop.UI.xml 10517 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Utility.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/NationalInstruments.TestStand.Utility.xml 2303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Newtonsoft.Json.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Newtonsoft.Json.xml 9646 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/OfficeNpoiHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/OfficeNpoiHelper.xml 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/ParameterHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/PathHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/PictureHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Plugin.Keygen.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/Plugin.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.Common.XML 1346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.Common.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.Facility.XML 601 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.Facility.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.SocketBase.XML 5405 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.SocketBase.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.SocketEngine.XML 1291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SuperSocket.SocketEngine.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SupersocketCommon.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/System.Data.SQLite.dll.config 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/System.Data.SQLite.xml 21379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/System.Runtime.Serialization.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/SystemSetting.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/UserInfo.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/UserInfo.dll.config 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/UserInfo.xml 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/WcfServer.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/WcfServer.dll.config 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/WcfServer.xml 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/WcfServiceContract.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/WcfServiceContract.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/languageHelper.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/languageHelper.dll.config 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Libs/log4net.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/mscorlib.dll 补丁 | 查看 | 原始文档 | blame | 历史
Libs/stdole.dll 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/ChartWindow.xaml.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/DataTable.xaml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/DataTable.xaml.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/InfoTable.xaml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/InfoWindow.xaml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/OpenTK.dll.config 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/Plugin.TestResult.csproj 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/Scanner.xaml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/Scanner.xaml.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/SingleCell.xaml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/TestResultView.xaml.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/ViewControl.xaml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/ViewControl.xaml.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/supersocket.cmd 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TestResult/supersocket.sh 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/Plugin.TsExecution.csproj 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/SingleControl.xaml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/SingleControl.xaml.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Plugin.TsExecution/TsExecution.xaml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/3rds/3rds Libs.txt 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/App.config 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/App.xaml.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Config/Database/database.db 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Config/Put Your Config Here.txt 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Config/log4net.config 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/b1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/b2.jpg 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/b3.jpg 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/b4.jpg 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/pic1.png 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/t1.png 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/t2.png 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/t3.png 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Icon/t4.png 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/JingCeLogo2.ico 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/AlarmInfoManage.json 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/DataViewer.json 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/IOMonitor.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/ParamManage.json 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/TestExecution.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/TestResult.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/app.json 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/setting.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/en-US/ts.json 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/AlarmInfoManage.json 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/DataViewer.json 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/IOMonitor.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/ParamManage.json 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/TestExecution.json 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/TestResult.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Lang/zh-CN/app.json 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Libs/SQLite.Interop.dll 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/LoadingWindow.xaml 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/LoadingWindow.xaml.cs 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Login.xaml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/PanuonWindow.xaml.cs 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Properties/AssemblyInfo.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/Properties/app.manifest 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/TextFile1.txt 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WPFProject/WPFProject.csproj 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HMI.AlermInfoManage/AlarmInfoManage.xaml
@@ -4,6 +4,7 @@
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
             xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
             xmlns:local="clr-namespace:HMI.AlarmInfoManage"
             xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
             xmlns:pw="https://opensource.panuon.com/wpf"
@@ -12,19 +13,6 @@
             Background="{StaticResource WorkspaceBackground}"
             Loaded="UserControl_Loaded"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/HMI.UI;component/Style/BaseWindow.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Style/FormStyle.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Style/MsgBoxStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <uic:PathImageConverter x:Key="path2Image"/>
            <uic:DataGridRowNumberConverter x:Key="rowNumber"/>
        </ResourceDictionary>
    </UserControl.Resources>
    <Border Style="{StaticResource CardBoarder}">
        <StackPanel>
@@ -34,13 +22,9 @@
                    <Button Style="{StaticResource RfhBtn}" x:Name="refreshBtn" Click="Button_Click"/>
                    <Button Style="{StaticResource ImportBtn}" x:Name="importBtn" Click="Button_Click"/>
                </StackPanel>
                <!--<Button DockPanel.Dock="Right" pu:ButtonHelper.Icon="&#xe934;"
                        Style="{StaticResource DangerButton}">删除</Button>-->
                <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" 
                           VerticalAlignment="Center" HorizontalAlignment="Left" Text="报警信息列表"/>
                           VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource Alm.Title}"/>
            </DockPanel>
            <DataGrid x:Name="table" Style="{StaticResource DefaultDataGrid}" ItemsSource="{Binding Datasource}">
@@ -60,21 +44,40 @@
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Width="*" Binding="{Binding Source}" Header="来源" />
                    <DataGridTextColumn Width="*" Binding="{Binding Code}" Header="编码" />
                    <DataGridTextColumn Width="*" Binding="{Binding Info}" Header="信息" />
                    <DataGridTextColumn Width="*" Binding="{Binding Time}" Header="时间" />
                    <DataGridTemplateColumn Header="操作" Width="100" IsReadOnly="True" CanUserResize="False">
                    <DataGridTextColumn Width="*" Binding="{Binding Source}">
                        <DataGridTextColumn.Header>
                            <TextBlock Text="{DynamicResource Alm.Source}"/>
                        </DataGridTextColumn.Header>
                    </DataGridTextColumn>
                    <DataGridTextColumn Width="*" Binding="{Binding Code}">
                        <DataGridTextColumn.Header>
                            <TextBlock Text="{DynamicResource Alm.Code}"/>
                        </DataGridTextColumn.Header>
                    </DataGridTextColumn>
                    <DataGridTextColumn Width="*" Binding="{Binding Info}">
                        <DataGridTextColumn.Header>
                            <TextBlock Text="{DynamicResource Alm.Info}"/>
                        </DataGridTextColumn.Header>
                    </DataGridTextColumn>
                    <DataGridTextColumn Width="*" Binding="{Binding Time}">
                        <DataGridTextColumn.Header>
                            <TextBlock Text="{DynamicResource Alm.Time}"/>
                        </DataGridTextColumn.Header>
                    </DataGridTextColumn>
                    <DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
                        <DataGridTemplateColumn.Header>
                            <TextBlock Text="{DynamicResource App.Opt}"/>
                        </DataGridTemplateColumn.Header>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Button x:Name="editBtn" Style="{StaticResource LinkButton}"
                                    <Button x:Name="editBtn" Style="{StaticResource EditLink}"
                            Margin="0,0,10,0" 
                            Click="Button_Click"
                            DataContext="{Binding }">编辑</Button>
                                    <Button x:Name="delBtn" Style="{StaticResource DangerLinkButton}"
                            DataContext="{Binding }"/>
                                    <Button x:Name="delBtn" Style="{StaticResource DeleteLink}"
                            DataContext="{Binding }"
                            Click="Button_Click">删除</Button>
                            Click="Button_Click"/>
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
HMI.AlermInfoManage/AlarmInfoManage.xaml.cs
@@ -5,7 +5,6 @@
using HMI.Core.Util;
using HMI.UI.Util;
using Microsoft.Win32;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.UserModel;
using Sharp7;
using SimensDriver;
@@ -119,6 +118,9 @@
                case "settingBtn":
                    OpenSettingWindow();
                    break;
                case "refreshBtn":
                    //Model.
                    break;
                case "importBtn":
                    ImportText();
                    break;
@@ -150,7 +152,7 @@
            catch (Exception ex)
            {
                log.Error("AlarmText Import Failed.", ex);
                ToastHelper.Error(Window.GetWindow(this), $"导入失败!{ex.Message}");
                ToastHelper.Error(Window.GetWindow(this), $"{this.lang("App.ImportFailed")}: {ex.Message}");
            }
        }
@@ -166,7 +168,7 @@
            {
                if (excelFile.IndexOf(".xlsm") < 0)
                {
                    this.Warning("仅支持xlsm格式文件");
                    this.Warning(this.lang("Alm.OnlySupportXlsm"));
                    return;
                }
@@ -199,12 +201,12 @@
                    XmlHelper.SerializeToXml(textSettingPath, this.alarmTexts);
                }
                this.Success("导入成功");
                this.Success(this.lang("App.ImportSuccess"));
            }
            catch (Exception ex)
            {
                log.Error($"Row {index} AlarmText Import Failed.", ex);
                this.Error($"第{index}行导入异常!{ex.Message}");
                this.Error($"{this.lang("Alm.RowImportFailed", index)}: {ex.Message}");
            }
        }
HMI.AlermInfoManage/AlarmInfoManage_SettingA.xaml
@@ -1,4 +1,4 @@
<UserControl x:Class="HMI.AlarmInfoManage.AlarmInfoManage_Setting"
<UserControl x:Class="HMI.AlarmInfoManage.AlarmInfoManage_SettingA"
             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" 
HMI.AlermInfoManage/AlarmInfoManage_SettingA.xaml.cs
@@ -9,9 +9,9 @@
    /// <summary>
    /// AlarmInfoManage_Setting.xaml 的交互逻辑
    /// </summary>
    public partial class AlarmInfoManage_Setting : UserControl, IConfigManager
    public partial class AlarmInfoManage_SettingA : UserControl, IConfigManager
    {
        public AlarmInfoManage_Setting()
        public AlarmInfoManage_SettingA()
        {
            InitializeComponent();
        }
HMI.AlermInfoManage/AlarmSettingList.xaml
@@ -12,20 +12,10 @@
            Title="{Binding SelectedValue,Mode=OneWay}"
            SizeToContent="Height"
            pu:WindowXModalDialog.Buttons="OK"
            pu:WindowXModalDialog.OKButtonContent="{Binding Converter={StaticResource lc},ConverterParameter='App.Close'}"
            pu:WindowXModalDialog.OKButtonContent="{DynamicResource App.Close}"
            Width="800"
            Height="600"
            Style="{StaticResource ModalWindow}">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <pu:StyleDictionary Includes="TabControl"/>
                <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Margin="10">
        <Border BorderThickness="1" BorderBrush="Gray">
            <Grid>
@@ -35,7 +25,7 @@
                    <RowDefinition />
                </Grid.RowDefinitions>
                <ListBox ItemsSource="{Binding Items}" SelectedValue="{Binding SelectedValue}" BorderThickness="0">
                <ListBox ItemsSource="{Binding Items}" SelectedIndex="{Binding ItemIndex}" BorderThickness="0">
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
@@ -97,22 +87,37 @@
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding DBAddress}" Header="DB地址" />
                        <DataGridTextColumn Width="*" Binding="{Binding StartAddress}" Header="起始地址" />
                        <DataGridTextColumn Width="*" Binding="{Binding Length}" Header="DB长度" />
                        <DataGridTemplateColumn Header="操作" Width="100" IsReadOnly="True" CanUserResize="False">
                        <DataGridTextColumn Width="*" Binding="{Binding DBAddress}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Alm.DbAddress}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding StartAddress}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Alm.StartAddress}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding Length}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Alm.DbLength}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
                            <DataGridTemplateColumn.Header>
                                <TextBlock Text="{DynamicResource App.Opt}"/>
                            </DataGridTemplateColumn.Header>
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <Button x:Name="editBtn" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}" 
                                                Style="{StaticResource RowLink}"
                                                Style="{StaticResource EditLink}"
        Margin="0,0,10,0" 
        Click="Button_Click"
        DataContext="{Binding }">编辑</Button>
        DataContext="{Binding }"/>
                                        <Button x:Name="delBtn" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}" 
                                                Style="{StaticResource DangerLinkButton}"
                                                Style="{StaticResource DeleteLink}"
        DataContext="{Binding }"
        Click="Button_Click">删除</Button>
        Click="Button_Click"/>
                                    </StackPanel>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
HMI.AlermInfoManage/AlarmSettingList.xaml.cs
@@ -47,7 +47,7 @@
        }
        private ObservableCollection<string> items =
            new ObservableCollection<string> { "DB块报警", "标志位报警" };
            new ObservableCollection<string> { LangUtil.Get("Alm.DbBlockAlarm"), LangUtil.Get("Alm.TagAlarm") };
        public ObservableCollection<string> Items
        {
@@ -55,14 +55,13 @@
            set { Set(ref items, value); }
        }
        private string selectedValue;
        public string SelectedValue
        private int itemIndex;
        public int ItemIndex
        {
            get { return selectedValue; }
            get => itemIndex;
            set
            {
                Set(ref selectedValue, value);
                Set(ref itemIndex, value);
                LoadData();
            }
        }
@@ -99,12 +98,12 @@
            try
            {
                ObservableCollection<AlarmSetting> datasource = new ObservableCollection<AlarmSetting>();
                if (SelectedValue == "DB块报警" && File.Exists(blockFile))
                if (ItemIndex == 0 && File.Exists(blockFile))
                {
                    datasource =
                        XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(blockFile);
                }
                else if (SelectedValue == "标志位报警" && File.Exists(markFile))
                else if (ItemIndex == 1 && File.Exists(markFile))
                {
                    datasource =
                        XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(markFile);
@@ -113,7 +112,7 @@
            }
            catch (Exception ex)
            {
                ToastHelper.Error(this, $"加载错误!{ex.Message}");
                ToastHelper.Error(this, $"{this.lang("App.LoadFailed")}: {ex.Message}");
            }
        }
@@ -121,10 +120,11 @@
        {
            try
            {
                var file = SelectedValue == "DB块报警" ? blockFile : markFile;
                var file = ItemIndex == 0 ? blockFile : markFile;
                var temp = ItemIndex == 0 ? this.lang("Alm.DbBlockAlarm") : this.lang("Alm.TagAlarm");
                var modal = new AlarmSettingModal(log)
                {
                    Title = $"新增{SelectedValue}",
                    Title = $"{this.lang("App.Add")}{temp}",
                    Owner = Window.GetWindow(this),
                };
                if (modal.Open(-1, data, Datasource, file) == true)
@@ -135,7 +135,7 @@
            catch (Exception ex)
            {
                log.Error("Add AlarmSetting Failed.", ex);
                ToastHelper.Error(this, $"新增失败!{ex.Message}");
                ToastHelper.Error(this, $"{this.lang("App.AddFailed")}: {ex.Message}");
            }
        }
@@ -143,10 +143,11 @@
        {
            try
            {
                var file = SelectedValue == "DB块报警" ? blockFile : markFile;
                var file = ItemIndex == 0 ? blockFile : markFile;
                var temp = ItemIndex == 0 ? this.lang("Alm.DbBlockAlarm") : this.lang("Alm.TagAlarm");
                var modal = new AlarmSettingModal(log)
                {
                    Title = $"编辑{SelectedValue}",
                    Title = $"{this.lang("App.Edit")}{temp}",
                    Owner = Window.GetWindow(this),
                };
                if (modal.Open(index, data, Datasource, file) == true)
@@ -157,16 +158,16 @@
            catch (Exception ex)
            {
                log.Error("Edit AlarmSetting Failed.", ex);
                ToastHelper.Error(this, $"编辑失败!{ex.Message}");
                ToastHelper.Error(this, $"{this.lang("App.EditFailed")}: {ex.Message}");
            }
        }
        private void DeleteData(int index)
        {
            try
            {
                if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), "确定要删除该项吗?该操作不可逆") == MessageBoxResult.OK)
                if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeleteThis")) == MessageBoxResult.OK)
                {
                    var file = SelectedValue == "DB块报警" ? blockFile : markFile;
                    var file = ItemIndex == 0 ? blockFile : markFile;
                    var temp = XmlHelper.DeepClone(Datasource);
                    temp.RemoveAt(index);
@@ -177,7 +178,7 @@
            catch (Exception ex)
            {
                log.Error("Delete AlarmSetting Failed.", ex);
                ToastHelper.Error(this, $"删除失败!{ex.Message}");
                ToastHelper.Error(this, $"{this.lang("App.DeleteFailed")}: {ex.Message}");
            }
        }
        private void DeleteBatchData()
@@ -187,13 +188,14 @@
                var temp = Datasource.Where(e => e.IsSelected).ToList();
                if (temp == null || temp.Count <= 0)
                {
                    ToastHelper.Warning(Window.GetWindow(this), "请选择要删除的数据");
                    ToastHelper.Warning(Window.GetWindow(this), this.lang("HMI.NoDeleteData"));
                    return;
                }
                if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除{temp.Count}项数据吗?该操作不可逆") == MessageBoxResult.OK)
                if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeletes", temp.Count))
                    == MessageBoxResult.OK)
                {
                    var file = SelectedValue == "DB块报警" ? blockFile : markFile;
                    var file = ItemIndex == 0 ? blockFile : markFile;
                    temp = Datasource.Where(e => !e.IsSelected).ToList();
                    XmlHelper.SerializeToXml(file, temp);
                    LoadData();
@@ -202,13 +204,13 @@
            catch (Exception ex)
            {
                log.Error("Delete Batch AlarmSetting Failed.", ex);
                ToastHelper.Error(this, $"删除失败!{ex.Message}");
                ToastHelper.Error(this, $"{this.lang("App.DeleteFailed")}: {ex.Message}");
            }
        }
        private void WindowX_Loaded(object sender, RoutedEventArgs e)
        {
            SelectedValue = "DB块报警";
            ItemIndex = 0;
            Loaded -= WindowX_Loaded;
        }
    }
HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
@@ -171,7 +171,7 @@
  <ItemGroup />
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml
@@ -17,30 +17,24 @@
            BorderBrush="#3E3E45"
            BorderThickness="1"
            Foreground="Black"
            pu:WindowXCaption.Background="{StaticResource PrimaryColor}"
            pu:WindowXModalDialog.ButtonStyle="{StaticResource ModalButton}"
            pu:WindowXCaption.Foreground="#FFF"
            pu:WindowXCaption.Buttons="Close"
            pu:WindowXModalDialog.Buttons="OKCancel"
            pu:WindowXModalDialog.CancelButtonContent="取消"
            pu:WindowXModalDialog.OKButtonContent="保存"
            pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
            Style="{StaticResource ModalWindow}">
    <Grid Margin="10">
        <StackPanel x:Name="formPanel">
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
            <pu:FormGroup Header="{DynamicResource Alm.DbAddress}"
                dp:FormGroupHelper.IsRequired="True"
                                dp:FormGroupHelper.ValidateMethod="ValidateDBAddress"
                          Header="DB地址" GroupName="MyFormGroup">
                           GroupName="MyFormGroup">
                <pu:NumberInput Style="{StaticResource FormNumberInput}" 
                                x:Name="dbAddress" Interval="1"/>
            </pu:FormGroup>
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
              Header="起始地址" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource Alm.StartAddress}" dp:FormGroupHelper.IsRequired="True"
                          GroupName="MyFormGroup">
                <pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="startAddress" Interval="1"/>
            </pu:FormGroup>
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
              Header="长度" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource Alm.DbLength}" dp:FormGroupHelper.IsRequired="True"
                          GroupName="MyFormGroup">
                <pu:NumberInput Style="{StaticResource FormNumberInput}" x:Name="length" Interval="1"/>
            </pu:FormGroup>
        </StackPanel>
HMI.AlermInfoManage/Modal/AlarmSettingModal.xaml.cs
@@ -56,7 +56,7 @@
                catch (Exception ex)
                {
                    log.Error("AlarmSetting Form Submit Failed.", ex);
                    ToastHelper.Error(this, $"未知异常!{ex.Message}");
                    ToastHelper.Error(this, $"Error: {ex.Message}");
                    e.Cancel = true;
                    return;
                }
@@ -75,7 +75,7 @@
            int dbAddress = Convert.ToInt32(value);
            if (Datasource.FirstOrDefault(e => e.DBAddress == dbAddress) != null)
            {
                err = "DB地址已存在";
                err = this.lang("App.MustBeUnique", this.lang("Alm.DbAddress"));
                return false;
            }
            return true;
HMI.Base/PluginLoader.cs
@@ -8,15 +8,27 @@
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace HMI.Base
{
    public enum LoadMsgType
    {
        INIT, LOADING, FINISHED
    }
    public class LoadMsg
    {
        public string Message { get; set; }
        public bool? Result { get; set; }
        public LoadMsgType Type { get; set; }
        public int NumData { get; set; }
    }
    public class PluginLoader
    {
        private static ILog log = LogManager.GetLogger("PluginLoader");
        private static string PluginFolder = PathHelper.PluginFolder();
        public bool Completed { get; private set; } = false;
@@ -25,8 +37,7 @@
        public List<PluginInfo> Plugins { get; private set; }
        public static PluginLoader Instance { get; private set; }
        public event EventHandler<string> LoadMessageAppend;
        public event EventHandler Loaded;
        public event EventHandler<LoadMsg> LoadMessageAppend;
        private PluginLoader()
        {
@@ -48,13 +59,20 @@
            {
                Plugins = new List<PluginInfo>();
                Menus = LoadTreeMenu(dispatcher);
                Loaded?.Invoke(this, null);
                dispatcher.Invoke(() =>
                {
                    LoadMessageAppend?.Invoke(this, new LoadMsg { Type = LoadMsgType.FINISHED });
                });
            }
        }
        private void LoadChildrenMenu(PluginInfo menu, Dispatcher dispatcher)
        {
            LoadMessageAppend?.Invoke(this, $"正在加载{menu.Name}菜单...");
            LoadMessageAppend?.Invoke(this, new LoadMsg
            {
                Type = LoadMsgType.LOADING,
                Message = $"正在加载{menu.Name}菜单..."
            });
            try
            {
                Application.Current.Dispatcher.Invoke(() =>
@@ -89,7 +107,13 @@
            }
            catch (Exception ex)
            {
                LoadMessageAppend?.Invoke(this, $"{ex.Message} {ex.StackTrace}");
                LoadMessageAppend?.Invoke(this,
                     new LoadMsg
                     {
                         Type = LoadMsgType.LOADING,
                         Result = false,
                         Message = $"{ex.Message} {ex.StackTrace}"
                     });
            }
        }
@@ -98,13 +122,19 @@
            foreach (var menu in Plugins)
            {
                CountdownEvent c = new CountdownEvent(1);
                Thread.Sleep(10);
                Thread.Sleep(100);
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    try
                    {
                        LoadMessageAppend?.Invoke(this, $"正在加载{menu.Name}菜单...");
                        LoadMessageAppend?.Invoke(this,
                            new LoadMsg
                            {
                                Type = LoadMsgType.LOADING,
                                Message = this.lang("App.IsLoadingMenu", menu.Name)
                            }
                        );
                        if (!string.IsNullOrEmpty(menu.DllPath))
                        {
                            string dllPath = Path.Combine(PluginFolder, menu.DllPath);
@@ -134,11 +164,23 @@
                                }
                            }
                        }
                        LoadMessageAppend?.Invoke(this, $"加载完");
                        LoadMessageAppend?.Invoke(this,
                            new LoadMsg
                            {
                                Type = LoadMsgType.LOADING,
                                Result = true,
                                Message = this.lang("App.MenuLoadSuccess", menu.Name),
                            });
                    }
                    catch (Exception ex)
                    {
                        LoadMessageAppend?.Invoke(this, $"{ex.Message} {ex.StackTrace}");
                        log.Error("Load Plugin Failed.", ex);
                        LoadMessageAppend?.Invoke(this, new LoadMsg
                        {
                            Type = LoadMsgType.LOADING,
                            Result = false,
                            Message = this.lang("App.MenuLoadFailed", menu.Name, ex.Message, ex.StackTrace)
                        });
                    }
                    finally
                    {
@@ -165,9 +207,16 @@
                DataTable dt = sqliteHelper.GetDataTable(sql);
                if (dt != null)
                {
                    //LoadMessageAppend?.Invoke(this, $"共有{dt.Rows.Count}条菜单待加载...");
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        LoadMessageAppend?.Invoke(this,
                          new LoadMsg
                          {
                              Type = LoadMsgType.INIT,
                              NumData = dt.Rows.Count,
                              Message = this.lang("App.MenuCount", dt.Rows.Count),
                          });
                        foreach (DataRow dr in dt.Rows)
                        {
                            string path = Path.Combine(PathHelper.IconFolder, dr["iconPath"].ToString());
HMI.Core/Setting/SystemSetting.cs
@@ -25,11 +25,11 @@
        }
        public string LogoPath { get; private set; }
        public string WindowTitle { get; private set; }
        public string LogoPath { get; private set; } = ".\\JingCeLogo.png";
        public string WindowTitle { get; private set; } = "产品测试平台";
        public string PlcIp { get; private set; }
        public bool PlcEnabled { get; private set; }
        public string CurrentLanguage { get; private set; }
        public string CurrentLanguage { get; private set; } = "zh-CN";
        private static void LoadFromXml()
        {
HMI.Core/Util/LangUtil.cs
@@ -4,6 +4,7 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using System.Windows;
@@ -28,9 +29,17 @@
        {
        }
        public static void LoadLang()
        private static string GetLang()
        {
            var lang = SystemSetting.Instance.CurrentLanguage;
            if (string.IsNullOrEmpty(lang)) lang = CultureInfo.CurrentUICulture.ToString();
            return lang;
        }
        public static void LoadLang()
        {
            var lang = GetLang();
            if (!ResourceMap.ContainsKey(lang)) return;
            var newLang = ResourceMap[lang];
            if (currentResource == newLang)
@@ -47,16 +56,22 @@
        public static void Load()
        {
            /// 按Json加载
            //LoadAllDataByJson();
            /// 下面是按xaml加载
            LoadAllDataByXaml();
            LoadLang();
            try
            {
                /// 按Json加载
                //LoadAllDataByJson();
                /// 下面是按xaml加载
                LoadAllDataByXaml();
                LoadLang();
            }
            finally {
            }
        }
        public static string Get(string key)
        {
            var lang = SystemSetting.Instance.CurrentLanguage;
            var lang = GetLang();
            if (!JsonMap.ContainsKey(lang)) return key;
            if (!JsonMap[lang].ContainsKey(key)) return key;
            return JsonMap[lang][key].ToString();
@@ -171,7 +186,7 @@
    public static class LangReader
    {
        public static string lang(this DependencyObject dp, string key, params object[] datas)
        public static string lang(this object dp, string key, params object[] datas)
        {
            return string.Format(LangUtil.Get(key), datas);
        }
HMI.Core/Util/SqliteHelper.cs
@@ -7,7 +7,7 @@
{
    public class SqliteHelper
    {
        private string DataBaseFile = string.Empty;
        public string DataBaseFile { get; private set; } = string.Empty;
        private string ConnectString = string.Empty;
HMI.Core/Util/XmlHelper.cs
@@ -1,13 +1,8 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Serialization;
using static System.Net.WebRequestMethods;
namespace HMI.Core.Util
{
HMI.DataViewer/DataViewer.xaml
@@ -13,18 +13,6 @@
             Background="{StaticResource WorkspaceBackground}"
             Loaded="PluginControl_Loaded"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <pu:StyleDictionary Includes="TreeView" />
                <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <uic:PathImageConverter x:Key="path2Image"/>
            <uic:DataGridRowNumberConverter x:Key="rowNumber"/>
        </ResourceDictionary>
    </UserControl.Resources>
    <Border Style="{StaticResource CardBoarder}">
        <Grid dp:GridHelper.Space="10">
            <Grid.RowDefinitions>
@@ -41,10 +29,11 @@
            <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="数据查询"/>
                <TextBlock Style="{StaticResource TitleBox}" Text="{DynamicResource Dv.Title}"/>
            </DockPanel>
            <!--<Grid>
@@ -55,28 +44,40 @@
            </Grid>-->
            <StackPanel Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Left" Style="{StaticResource ButtonGroup}">
                <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}" Text="开始时间"/>
                <TextBlock Style="{StaticResource TitleBox}" FontSize="{StaticResource ContentFontSize2}"
                           Text="{DynamicResource Dv.SelectItem}"/>
                <ComboBox x:Name="programInput"
                          MinWidth="180"
                          SelectionChanged="programInput_SelectionChanged"/>
                <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="结束时间"/>
                <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"/>
                <Menu x:Name="anyBtn" Style="{StaticResource CommonMenu}">
                <Button Style="{StaticResource ExportBtn}"
                        x:Name="exportBtn" Click="Button_Click"/>
                <!--<Menu x:Name="anyBtn" Style="{StaticResource CommonMenu}">
                    <MenuItem Header="分析">
                        <MenuItem Header="CPK" Click="MenuItem_Click"/>
                        <MenuItem Header="RandR" />
                    </MenuItem>
                </Menu>
                </Menu>-->
            </StackPanel>
            <DockPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="0,10,0,0">
                <pu:Drawer DockPanel.Dock="Left" x:Name="DrwMenu" MinWidth="34" MaxWidth="400"
                <pu:Drawer DockPanel.Dock="Left" x:Name="DrwMenu" MinWidth="35" MaxWidth="400"
                           Padding="0"
                           ShadowColor="{x:Null}"
                           AnimationDuration="0" BorderThickness="2,0,0,2" BorderBrush="{StaticResource CommonBoarder}">
@@ -90,42 +91,48 @@
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <DockPanel Grid.ColumnSpan="2" Background="{StaticResource CommonBoarder}">
                            <ToggleButton x:Name="drawerBtn" BorderThickness="0"
                                          DockPanel.Dock="Right"
                                          Background="Transparent"
                                          Width="34" Height="34" HorizontalAlignment="Right"
                                          RenderTransformOrigin="0.5,0.5"
                                          FontFamily="{StaticResource iconfont}"
                                          Content="&#xe60e;" IsChecked="{Binding IsOpen, ElementName=DrwMenu, Mode=TwoWay}">
                                <ToggleButton.Style>
                                    <Style TargetType="ToggleButton" BasedOn="{StaticResource CommonToggle}">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="False">
                                                <Setter Property="RenderTransform">
                                                    <Setter.Value>
                                                        <RotateTransform Angle="-90"/>
                                                    </Setter.Value>
                                                </Setter>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="True">
                                                <Setter Property="Background" Value="Red"/>
                                                <Setter Property="RenderTransform">
                                                    <Setter.Value>
                                                        <RotateTransform Angle="90"/>
                                                    </Setter.Value>
                                                </Setter>
                                            </DataTrigger>
                                            <Trigger Property="IsChecked" Value="True">
                                                <Setter Property="Background" Value="Red"/>
                                            </Trigger>
                                        </Style.Triggers>
                                    </Style>
                                </ToggleButton.Style>
                            </ToggleButton>
                        <Border Grid.ColumnSpan="2" BorderThickness="2" BorderBrush="{StaticResource CommonBoarder}" Background="{StaticResource VerBar}">
                            <DockPanel Height="35">
                                <ToggleButton x:Name="drawerBtn" BorderThickness="0"
                  DockPanel.Dock="Right"
                  Background="Transparent"
                  Width="35" Height="35" HorizontalAlignment="Right"
                  RenderTransformOrigin="0.5,0.5"
                                              Foreground="{StaticResource PrimaryColorContract}"
                  FontFamily="{StaticResource iconfont}"
                  Content="&#xe60e;" IsChecked="{Binding IsOpen, ElementName=DrwMenu, Mode=TwoWay}">
                                    <ToggleButton.Style>
                                        <Style TargetType="ToggleButton" BasedOn="{StaticResource CommonToggle}">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="False">
                                                    <Setter Property="RenderTransform">
                                                        <Setter.Value>
                                                            <RotateTransform Angle="-90"/>
                                                        </Setter.Value>
                                                    </Setter>
                                                </DataTrigger>
                                                <DataTrigger Binding="{Binding IsOpen, ElementName=DrwMenu}" Value="True">
                                                    <Setter Property="Background" Value="Red"/>
                                                    <Setter Property="RenderTransform">
                                                        <Setter.Value>
                                                            <RotateTransform Angle="90"/>
                                                        </Setter.Value>
                                                    </Setter>
                                                </DataTrigger>
                                                <Trigger Property="IsChecked" Value="True">
                                                    <Setter Property="Background" Value="Red"/>
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </ToggleButton.Style>
                                </ToggleButton>
                            <TextBlock Text="高级查询" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        </DockPanel>
                                <TextBlock Text="{DynamicResource Dv.Advanced}" FontSize="16"
                                           Foreground="{StaticResource PrimaryColorContract}"
                                           VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </DockPanel>
                        </Border>
                        <Grid Grid.Row="1">
                            <Grid.RowDefinitions>
@@ -137,12 +144,12 @@
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <DockPanel Margin="10,10,10,0" Grid.ColumnSpan="2">
                                <Label Content="选择查询项目"/>
                            <!--<DockPanel Margin="10,10,10,0" Grid.ColumnSpan="2">
                                <Label Content="{DynamicResource Dv.SelectItem}"/>
                                <ComboBox Grid.Column="1" x:Name="programInput" SelectionChanged="programInput_SelectionChanged"/>
                            </DockPanel>
                            </DockPanel>-->
                            <DataGrid Margin="10" Grid.Row="1" Grid.ColumnSpan="2" Style="{StaticResource DefaultDataGrid}"
                            <DataGrid Grid.Row="1" Grid.ColumnSpan="2" Style="{StaticResource DefaultDataGrid}"
                                      IsReadOnly="False"
                                      SelectionMode="Single"
                                      BorderThickness="0"
@@ -156,9 +163,17 @@
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>
                                    <DataGridTextColumn IsReadOnly="True" Width="*" Binding="{Binding Key}" Header="筛选条件" />
                                    <DataGridTemplateColumn Width="*" Header="对比方式">
                                    <DataGridTextColumn IsReadOnly="True" Width="*" Binding="{Binding Key}">
                                        <DataGridTextColumn.Header>
                                            <TextBlock Text="{DynamicResource Dv.Field}"/>
                                        </DataGridTextColumn.Header>
                                    </DataGridTextColumn>
                                    <DataGridTemplateColumn Width="*">
                                        <DataGridTemplateColumn.Header>
                                            <TextBlock Text="{DynamicResource Dv.Condition}"/>
                                        </DataGridTemplateColumn.Header>
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Condition}"/>
@@ -178,7 +193,10 @@
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>
                                    <DataGridTextColumn Width="*" Binding="{Binding Value}" Header="筛选值" >
                                    <DataGridTextColumn Width="*" Binding="{Binding Value}" >
                                        <DataGridTextColumn.Header>
                                            <TextBlock Text="{DynamicResource Dv.Value}"/>
                                        </DataGridTextColumn.Header>
                                        <DataGridTextColumn.HeaderTemplate>
                                            <DataTemplate>
                                                <StackPanel Orientation="Horizontal">
@@ -196,7 +214,7 @@
                        <Label Grid.Row="1" Grid.Column="1"  Width="100" Height="34"
                               VerticalContentAlignment="Center"
                               HorizontalContentAlignment="Center"
                                   Content="高级查询"
                                   Content="{DynamicResource Dv.Advanced}"
                                   FontSize="16">
                            <Label.LayoutTransform>
                                <RotateTransform CenterX="25" CenterY="25" Angle="270"/>
HMI.DataViewer/DataViewer.xaml.cs
@@ -2,7 +2,8 @@
using HMI.Core.Util;
using HMI.DataViewer.Entity;
using HMI.UI.Util;
using Panuon.WPF.UI;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -12,7 +13,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Forms;
using System.Windows.Media;
namespace HMI.DataViewer
@@ -48,15 +49,20 @@
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            System.Windows.Controls.Button btn = sender as System.Windows.Controls.Button;
            switch (btn.Name)
            {
                case "addBtn":
                    OpenSettingModal(new DataBase_Setting());
                    OpenSettingModal(-1, new DataBase_Setting());
                    break;
                case "editBtn":
                    EditSettingModal();
                    break;
                case "rfhBtn":
                    LoadData();
                    break;
                case "delBtn":
                    DeleteDatasource();
                    break;
                case "srhBtn":
                    SearchData();
@@ -64,80 +70,74 @@
                case "resetBtn":
                    ResetDataTable();
                    break;
                case "exportBtn":
                    ExportData();
                    break;
                default:
                    break;
            }
        }
        private void OpenSettingModal(DataBase_Setting data)
        private void DeleteDatasource()
        {
            DbSettingModal modal = new DbSettingModal(log)
            {
                Title = "新增数据源",
                Owner = Window.GetWindow(this)
            };
            if (modal.Open(-1, data, Settings, SourceFilePath) == true)
            {
                LoadData();
            }
        }
        private void SearchData()
        {
            string program = programInput.Text;
            if (!Map.ContainsKey(program))
            {
                ToastHelper.Error(Window.GetWindow(this), "参数异常,请刷新重试");
                return;
            }
            var datas = Datas?.Where(d => !string.IsNullOrEmpty(d.Value)).ToList();
            if (datas == null || datas.Count <= 0)
            {
                ToastHelper.Warning(Window.GetWindow(this), "请设置查询条件值");
                return;
            }
            DataBase_Setting setting = Map[program];
            string fields = string.Join(",", Datas?.Select(d => $"[{d.Key}]").ToList());
            string conditon = string.Join(" AND ", datas.Select(d => $"[{d.Key}] {d.Condition} '{d.Value}'").ToList());
            string timeCol = setting.TimeCol;
            if (string.IsNullOrEmpty(timeCol))
            {
                timeCol = "time";
            }
            if (!string.IsNullOrEmpty(startTimeInput.Text))
            {
                conditon += $" AND {timeCol} >= '{startTimeInput.Text}'";
            }
            if (!string.IsNullOrEmpty(endTimeInput.Text))
            {
                conditon += $" AND {timeCol} < '{endTimeInput.Text}'";
            }
            conditon = string.IsNullOrEmpty(conditon) ? string.Empty : $" WHERE {conditon}";
            SqliteHelper helper = null;
            string sql = string.Empty;
            try
            {
                helper = new SqliteHelper(setting.DBFilePath);
                sql = $"SELECT {fields} FROM {setting.TableName} {conditon}";
                DataTable dt = helper.GetDataTable(sql);
                HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
                dataTable.ItemsSource = dt.DefaultView;
                var key = programInput.Text;
                if (string.IsNullOrEmpty(key))
                {
                    ToastHelper.Warning(Window.GetWindow(this), this.lang("Dv.SelectDatasourceFirst"));
                    return;
                }
                if (!Map.ContainsKey(key))
                {
                    ToastHelper.Error(Window.GetWindow(this), this.lang("App.ParameterException"));
                    return;
                }
                DataBase_Setting setting = Map[key];
                if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeleteSingle", setting.Program))
                    == MessageBoxResult.OK)
                {
                    var temp = XmlHelper.DeepClone(Settings);
                    temp.RemoveAt(Settings.IndexOf(setting));
                    XmlHelper.SerializeToXml(SourceFilePath, temp);
                    ToastHelper.Success(Window.GetWindow(this), this.lang("App.DeleteSuccess"));
                    LoadData();
                }
            }
            catch (Exception ex)
            {
                log.Error($"Select Data Failed. SQL: {sql}", ex);
                ToastHelper.Error(Window.GetWindow(this), $"查询失败!{ex.Message}");
                log.Error("Delete Datasource Failed.", ex);
                ToastHelper.Success(Window.GetWindow(this), $"{this.lang("App.DeleteFailed")}: {ex.Message}");
            }
            finally
        }
        private void EditSettingModal()
        {
            var key = programInput.Text;
            if (string.IsNullOrEmpty(key))
            {
                helper?.Close();
                ToastHelper.Warning(Window.GetWindow(this), this.lang("Dv.SelectDatasourceFirst"));
                return;
            }
            if (!Map.ContainsKey(key))
            {
                ToastHelper.Error(Window.GetWindow(this), this.lang("App.ParameterException"));
                return;
            }
            DataBase_Setting setting = Map[key];
            OpenSettingModal(Settings.IndexOf(setting), setting);
        }
        private void OpenSettingModal(int index, DataBase_Setting data)
        {
            DbSettingModal modal = new DbSettingModal(log)
            {
                Title = this.lang("Dv.AddDatasource"),
                Owner = Window.GetWindow(this)
            };
            if (modal.Open(index, data, Settings, SourceFilePath) == true)
            {
                LoadData();
            }
        }
@@ -166,26 +166,43 @@
        private void LoadData()
        {
            ObservableCollection<DataBase_Setting> settings = new ObservableCollection<DataBase_Setting>();
            if (File.Exists(SourceFilePath))
            {
                List<string> names = new List<string>();
                Settings = XmlHelper.DeserializeFromXml<ObservableCollection<DataBase_Setting>>(SourceFilePath);
                Map.Clear();
                foreach (var data in Settings)
                {
                    Map.Add(data.Program, data);
                    names.Add(data.Program);
                }
                programInput.ItemsSource = names;
                settings = XmlHelper.DeserializeFromXml<ObservableCollection<DataBase_Setting>>(SourceFilePath);
            }
            List<string> names = new List<string>();
            Map.Clear();
            foreach (var data in settings)
            {
                Map.Add(data.Program, data);
                names.Add(data.Program);
            }
            programInput.ItemsSource = names;
            //ResetInput();
            UpdateAdvanced();
            Settings = settings;
        }
        private void programInput_SelectionChanged(object sender, SelectionChangedEventArgs e)
        private void ResetInput()
        {
            var key = e.AddedItems[0].ToString();
            programInput.Text = string.Empty;
            Datas.Clear();
            var temp = dataTable.Columns[0];
            HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
            dataTable.Columns.Clear();
            dataTable.Columns.Add(temp);
            currentColumns?.Clear();
        }
        private void UpdateAdvanced()
        {
            var key = programInput.Text;
            if (!Map.ContainsKey(key))
            {
                ToastHelper.Error(Window.GetWindow(this), "参数异常,请刷新重试");
                ResetInput();
                return;
            }
            DataBase_Setting setting = Map[key];
@@ -196,21 +213,54 @@
            HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
            dataTable.Columns.Clear();
            dataTable.Columns.Add(temp);
            List<DataGridTextColumn> columns = new List<DataGridTextColumn>();
            foreach (var data in Datas)
            {
                AddDataGridTextColumn(data.Name, data.Key);
                columns.Add(AddDataGridTextColumn(data.Name, data.Key));
            }
            currentColumns = columns;
        }
        private void AddDataGridTextColumn(string header, string bindingPath)
        private void programInput_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems == null || e.AddedItems.Count <= 0) return;
            var key = e.AddedItems[0].ToString();
            if (!Map.ContainsKey(key))
            {
                ToastHelper.Error(Window.GetWindow(this), this.lang("App.ParameterException"));
                programInput.Text = string.Empty;
                return;
            }
            DataBase_Setting setting = Map[key];
            Datas = new ObservableCollection<QueryData>(
                setting?.Condition?.Select(d => new QueryData { Key = d.Key, Name = d.Desc, Condition = "=" }).ToList());
            var temp = dataTable.Columns[0];
            HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
            dataTable.Columns.Clear();
            dataTable.Columns.Add(temp);
            List<DataGridTextColumn> columns = new List<DataGridTextColumn>();
            foreach (var data in Datas)
            {
                columns.Add(AddDataGridTextColumn(data.Name, data.Key));
            }
            currentColumns = columns;
        }
        private List<DataGridTextColumn> currentColumns;
        private DataGridTextColumn AddDataGridTextColumn(string header, string bindingPath)
        {
            DataGridTextColumn textColumn = new DataGridTextColumn
            {
                Header = header,
                Binding = new Binding(bindingPath),
                Binding = new System.Windows.Data.Binding(bindingPath),
                Width = new DataGridLength(1, DataGridLengthUnitType.Star)
            };
            dataTable.Columns.Add(textColumn);
            return textColumn;
        }
        private void dataTable_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
@@ -252,10 +302,168 @@
            }
        }
        private DataTable DoSearchData(DataBase_Setting setting, List<QueryData> datas)
        {
            string fields = string.Join(",", Datas?.Select(d => $"[{d.Key}]").ToList());
            string conditon = string.Join(" AND ", datas.Select(d => $"[{d.Key}] {d.Condition} '{d.Value}'").ToList());
            string timeCol = setting.TimeCol;
            if (string.IsNullOrEmpty(timeCol))
            {
                timeCol = "time";
            }
            if (!string.IsNullOrEmpty(startTimeInput.Text))
            {
                conditon += $" AND {timeCol} >= '{startTimeInput.Text}'";
            }
            if (!string.IsNullOrEmpty(endTimeInput.Text))
            {
                conditon += $" AND {timeCol} < '{endTimeInput.Text}'";
            }
            conditon = string.IsNullOrEmpty(conditon) ? string.Empty : $" WHERE {conditon}";
            SqliteHelper helper = null;
            string sql = string.Empty;
            try
            {
                helper = new SqliteHelper(setting.DBFilePath);
                sql = $"SELECT {fields} FROM {setting.TableName} {conditon}";
                DataTable dt = helper.GetDataTable(sql);
                HMI.UI.DpUtil.DataGridHelper.SetSelectedColumn(dataTable, null);
                dataTable.ItemsSource = dt.DefaultView;
                return dt;
            }
            catch (Exception ex)
            {
                log.Error($"Select Data Failed. SQL: {sql}", ex);
                throw ex;
            }
            finally
            {
                helper?.Close();
            }
        }
        private void SearchData()
        {
            string program = programInput.Text;
            if (!Map.ContainsKey(program))
            {
                ToastHelper.Error(Window.GetWindow(this), this.lang("App.ParameterException"));
                return;
            }
            var datas = Datas?.Where(d => !string.IsNullOrEmpty(d.Value)).ToList();
            if (datas == null || datas.Count <= 0)
            {
                ToastHelper.Warning(Window.GetWindow(this), this.lang("Dv.QueryCantBeEmpty"));
                return;
            }
            DataBase_Setting setting = Map[program];
            try
            {
                DoSearchData(setting, datas);
            }
            catch (Exception ex)
            {
                ToastHelper.Error(Window.GetWindow(this), $"{this.lang("App.QueryFailed")}: {ex.Message}");
            }
        }
        private void ExportData()
        {
            try
            {
                string program = programInput.Text;
                if (string.IsNullOrEmpty(program))
                {
                    ToastHelper.Warning(Window.GetWindow(this), this.lang("Dv.SelectDatasourceFirst"));
                    return;
                }
                if (!Map.ContainsKey(program))
                {
                    ToastHelper.Error(Window.GetWindow(this), this.lang("App.ParameterException"));
                    return;
                }
                var datas = Datas?.Where(d => !string.IsNullOrEmpty(d.Value)).ToList();
                if (datas == null || datas.Count <= 0)
                {
                    ToastHelper.Warning(Window.GetWindow(this), this.lang("Dv.QueryCantBeEmpty"));
                    return;
                }
                DataBase_Setting setting = Map[program];
                DataTable dt;
                try
                {
                    dt = DoSearchData(setting, datas);
                }
                catch (Exception ex)
                {
                    ToastHelper.Error(Window.GetWindow(this), $"{this.lang("App.QueryFailed")}: {ex.Message}");
                    return;
                }
                if (currentColumns == null) return;
                var dataView = dt?.DefaultView;
                if (dataView == null) return;
                string fname = string.Empty;
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "";
                sfd.DefaultExt = "xls";
                sfd.FileName = setting.Program;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    fname = sfd.FileName;
                }
                /*导出当前dataGridView中的所有数据到xls文件
                1.引入库文件,新建lib文件夹,复制相关文件
                2.在项目中添加对这几个dll的引用
                3.在内存中建立 excel表文件  */
                XSSFWorkbook workbook = new XSSFWorkbook();
                workbook.CreateSheet("sheet1");////新建一个工作表
                XSSFSheet SheetOne = (XSSFSheet)workbook.GetSheet("Sheet1"); ////获取名称为Sheet1的工作表,创建标题头
                IRow row1 = SheetOne.CreateRow(0);////获取Sheet1工作表的首行,设置表头,获取列
                XSSFCell[] SheetCell = new XSSFCell[currentColumns.Count];
                for (int i = 0; i < currentColumns.Count; i++)
                {
                    row1.CreateCell(i).SetCellValue(currentColumns[i].Header.ToString());
                }
                for (int i = 0; i < dataView.Count; i++)
                {
                    IRow rowTemp = SheetOne.CreateRow(i + 1);
                    for (int j = 0; j < currentColumns.Count; j++)
                    {
                        string name = ((System.Windows.Data.Binding)currentColumns[j].Binding).Path.Path;
                        var value = dataView[i][name].ToString();
                        rowTemp.CreateCell(j).SetCellValue(value);
                    }
                }
                using (FileStream fs = new FileStream(fname, FileMode.Create))
                {
                    workbook.Write(fs);
                }
                ToastHelper.Success(Window.GetWindow(this), this.lang("App.ExportSuccess"));
            }
            catch (Exception ex)
            {
                log.Error("Export Data Failed.", ex);
                ToastHelper.Error(Window.GetWindow(this), $"{this.lang("App.ExportFailed")}: {ex.Message}");
            }
        }
        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            DataGridColumn column = HMI.UI.DpUtil.DataGridHelper.GetSelectedColumn(dataTable);
        }
    }
}
HMI.DataViewer/DbSettingModal.xaml
@@ -17,21 +17,20 @@
            BorderBrush="#3E3E45"
            BorderThickness="1"
            Foreground="Black"
            pu:WindowXCaption.Background="{StaticResource PrimaryColor}"
            pu:WindowXModalDialog.ButtonStyle="{StaticResource ModalButton}"
            pu:WindowXCaption.Foreground="#FFF"
            pu:WindowXCaption.Buttons="Close"
            pu:WindowXModalDialog.Buttons="OKCancel"
            pu:WindowXModalDialog.CancelButtonContent="取消"
            pu:WindowXModalDialog.OKButtonContent="保存"
            pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
            Style="{StaticResource ModalWindow}">
    <Grid Margin="10">
        <StackPanel x:Name="formPanel">
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="名称" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource Dv.Datasource.Name}"
                          dp:FormGroupHelper.IsRequired="True"
                          Style="{StaticResource InputFormGroupStyle}"
                          GroupName="MyFormGroup">
                <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="programInput"/>
            </pu:FormGroup>
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="数据文件" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource Dv.Datasource.File}"
                          dp:FormGroupHelper.IsRequired="True"
                          Style="{StaticResource InputFormGroupStyle}"
                          GroupName="MyFormGroup">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
@@ -42,12 +41,15 @@
                </Grid>
            </pu:FormGroup>
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True" Header="数据表" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource Dv.Datasource.Table}"
                          dp:FormGroupHelper.IsRequired="True"
                          Style="{StaticResource InputFormGroupStyle}"
                          GroupName="MyFormGroup">
                <ComboBox Style="{StaticResource FormComboxStyle}" SelectedValuePath="Content" 
                          x:Name="tableNameInput" SelectionChanged="ComboxSelectionChanged"/>
            </pu:FormGroup>
            <pu:FormGroup Header="字段设置" Orientation="Vertical" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource Dv.Datasource.Fields}" Orientation="Vertical" GroupName="MyFormGroup">
                <Grid dp:GridHelper.Space="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
@@ -69,19 +71,29 @@
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding }" Header="字段名" />
                            <DataGridTextColumn Width="*" Binding="{Binding }">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource Dv.Datasource.FieldName}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                    <StackPanel Grid.Column="1" VerticalAlignment="Stretch" dp:StackPanelHelper.ChildSpace="10">
                        <Button Style="{StaticResource PrimaryButton}" x:Name="selectAllBtn" Click="Button_Click">全选</Button>
                        <Button Style="{StaticResource PrimaryButton}" x:Name="addBtn" Click="Button_Click">添加</Button>
                        <Button Style="{StaticResource PrimaryButton}" x:Name="delBtn" Click="Button_Click">删除</Button>
                        <Button Style="{StaticResource PrimaryButton}" x:Name="selectAllBtn" Click="Button_Click"
                                Content="{DynamicResource App.SelectAll}"
                                />
                        <Button Style="{StaticResource PrimaryButton}" x:Name="addBtn" Click="Button_Click"
                                Content="{DynamicResource App.AddTo}"/>
                        <Button Style="{StaticResource PrimaryButton}" x:Name="delBtn" Click="Button_Click"
                                Content="{DynamicResource App.Delete}"
                                />
                    </StackPanel>
                    <DataGrid Grid.Column="2" Style="{StaticResource DefaultDataGrid}"
                              BorderThickness="1"
                              IsReadOnly="False"
                              SelectionMode="Extended"
                              pu:DataGridHelper.ColumnHeaderFontSize="12"
                              ItemsSource="{Binding Conditions}" x:Name="conditionTable">
                        <DataGrid.Columns>
@@ -93,14 +105,24 @@
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                            <DataGridTextColumn Width="*" IsReadOnly="True" Binding="{Binding Key}" Header="字段名" />
                            <DataGridTextColumn Width="*" Binding="{Binding Desc}" Header="显示名" />
                            <DataGridTemplateColumn Width="*" Header="映射时间" IsReadOnly="True">
                            <DataGridTextColumn Width="*" IsReadOnly="True" Binding="{Binding Key}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource Dv.Datasource.FieldName}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Desc}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource Dv.Datasource.Desc}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTemplateColumn Width="*" IsReadOnly="True">
                                <DataGridTemplateColumn.Header>
                                    <TextBlock Text="{DynamicResource Dv.Datasource.TimeField}"/>
                                </DataGridTemplateColumn.Header>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <RadioButton IsChecked="{Binding IsTimeCol,Mode=OneWay}" 
                                                     Click="RadioButton_Click"
                                                     ></RadioButton>
                                                     Click="RadioButton_Click"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
HMI.DataViewer/DbSettingModal.xaml.cs
@@ -6,8 +6,10 @@
using Microsoft.Win32;
using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows.Controls;
@@ -87,7 +89,7 @@
                catch (Exception ex)
                {
                    log.Error("IPManage Form Submit Failed.", ex);
                    ToastHelper.Error(this, $"未知异常!{ex.Message}");
                    ToastHelper.Error(this, $"{this.lang("App.App.UnhandledException")}: {ex.Message}");
                    e.Cancel = true;
                    return;
                }
@@ -133,7 +135,16 @@
            programInput.Text = Data.Program;
            dbFilePathInput.Text = Data.DBFilePath;
            tableNameInput.Text = Data.TableName;
            Conditions = data?.Condition ?? new ObservableCollection<QueryCondition>();
            if (!string.IsNullOrEmpty(Data.DBFilePath) && File.Exists(Data.DBFilePath))
            {
                UpdateDbHelper(Data.DBFilePath);
                UpdateTableSource();
                tableNameInput.SelectedItem = Data.TableName;
                UpdateColumnSource(Data.TableName);
            }
            return this.ShowDialog();
        }
@@ -164,7 +175,8 @@
        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Button btn = sender as Button;
            switch (btn.Name) {
            switch (btn.Name)
            {
                case "searchBtn":
                    OpenSelectDbDialog();
                    break;
@@ -175,31 +187,56 @@
                    AddCondition();
                    break;
                case "delBtn":
                    RemoveCondition();
                    break;
                default:
                    break;
            }
        }
        private void UpdateDbHelper(string filePath)
        {
            if (Helper == null)
            {
                Helper = new SqliteHelper(filePath);
            }
            else if (Helper.DataBaseFile != filePath)
            {
                Helper.Close();
                Helper = new SqliteHelper(filePath);
            }
        }
        private void UpdateTableSource()
        {
            string[] tableNames = Helper.GetAllTableInFile();
            tableNameInput.ItemsSource = tableNames;
        }
        private void UpdateColumnSource(string tableName)
        {
            string[] cols = Helper.GetColumnNameFromTable(tableName);
            Columns = new ObservableCollection<string>(cols);
        }
        private void OpenSelectDbDialog()
        {
            string BasePath = PathHelper.IconFolder;
            string BasePath = PathHelper.ConfigFolder;
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "(*.db)|*.db";
            openFileDialog.InitialDirectory = BasePath;
            openFileDialog.Title = "选择数据库文件";
            openFileDialog.Title = this.lang("Dv.SelectDbFile");
            openFileDialog.Multiselect = false;
            if (openFileDialog.ShowDialog() == true)
            {
                string FileName = openFileDialog.FileName;
                dbFilePathInput.Text = FileName;
                Helper = new SqliteHelper(FileName);
                string[] tableNames = Helper.GetAllTableInFile();
                tableNameInput.ItemsSource = tableNames;
                UpdateDbHelper(FileName);
                UpdateTableSource();
            }
        }
@@ -220,11 +257,17 @@
            Conditions = temp;
        }
        private void ComboxSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        private void RemoveCondition()
        {
            string[] cols = Helper.GetColumnNameFromTable(e.AddedItems[0].ToString());
            Columns = new ObservableCollection<string>(cols);
            if (conditionTable.SelectedItems == null || conditionTable.SelectedItems.Count <= 0) return;
            Conditions = new ObservableCollection<QueryCondition>(
                Conditions.Where(d => !conditionTable.SelectedItems.Contains(d)).ToList());
        }
        private void ComboxSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UpdateColumnSource(e.AddedItems[0].ToString());
            Conditions = new ObservableCollection<QueryCondition>();
        }
        private void RadioButton_Click(object sender, System.Windows.RoutedEventArgs e)
HMI.DataViewer/HMI.DataViewer.csproj
@@ -50,8 +50,23 @@
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <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.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
      <HintPath>..\WPFProject\packages\log4net.3.0.3\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>
    <Reference Include="NPOI.OOXML, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
      <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.OOXML.dll</HintPath>
    </Reference>
    <Reference Include="NPOI.OpenXml4Net, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
      <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.OpenXml4Net.dll</HintPath>
    </Reference>
    <Reference Include="NPOI.OpenXmlFormats, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
      <HintPath>..\WPFProject\packages\NPOI.2.4.1\lib\net45\NPOI.OpenXmlFormats.dll</HintPath>
    </Reference>
    <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.2.2\lib\net472\Panuon.WPF.dll</HintPath>
@@ -63,6 +78,7 @@
    <Reference Include="System.Configuration" />
    <Reference Include="System.Data" />
    <Reference Include="System.Web" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
@@ -73,7 +89,9 @@
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationCore">
      <Private>False</Private>
    </Reference>
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
@@ -136,7 +154,7 @@
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.DataViewer/packages.config
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="log4net" version="3.0.3" targetFramework="net472" />
  <package id="NPOI" version="2.4.1" targetFramework="net472" />
  <package id="Panuon.WPF" version="1.1.2.2" targetFramework="net472" />
  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
  <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
</packages>
HMI.IOMonitor/HMI.IOMonitor.csproj
@@ -157,7 +157,7 @@
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.IOMonitor/IOMonitor.xaml
@@ -41,9 +41,9 @@
                    <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
                    <Button Style="{StaticResource ImportBtn}" x:Name="importBtn" Click="Button_Click"/>
                </StackPanel>
                <TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" 
                       FontSize="{StaticResource TitleFontSize}" Text="DIO监控"/>
                       FontSize="{StaticResource TitleFontSize}" Text="{DynamicResource DIO.Title}"/>
            </DockPanel>
            <Border Grid.Row="1" Style="{StaticResource CardBoarder}" Padding="0">
@@ -61,24 +61,25 @@
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Label Grid.Row="0" Grid.Column="0" Content="DI名称"
                    <Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource DIO.di.Name}"
                       FontSize="{StaticResource ContentFontSize}"/>
                    <ComboBox Grid.Row="0" Grid.Column="1" x:Name="diName" 
                          IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
                    <Button Style="{StaticResource PrimaryButton}" Grid.Row="0" Grid.Column="2" 
                        x:Name="diSelect" Click="Button_Click"
                        >DI查询</Button>
                        Content="{DynamicResource DIO.di.Query}"/>
                    <Button Style="{StaticResource PrimaryButton}" Grid.Row="0" Grid.Column="3"
                        x:Name="diReset" Click="Button_Click">DI重置</Button>
                        x:Name="diReset" Click="Button_Click"
                            Content="{DynamicResource DIO.di.Reset}"/>
                    <Label Grid.Row="1" Grid.Column="0" Content="DI编号"
                    <Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource DIO.di.Code}"
       FontSize="{StaticResource ContentFontSize}"/>
                    <ComboBox Grid.Row="1" Grid.Column="1" x:Name="diCode" 
                          IsEditable="True"
                          Style="{StaticResource FormComboxStyle}"/>
                    <Label Grid.Row="2" Grid.Column="0" Content="DI分组"
                    <Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource DIO.di.Group}"
       FontSize="{StaticResource ContentFontSize}"/>
                    <ComboBox Grid.Row="2" Grid.Column="1" x:Name="diGroup" 
                          IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
@@ -97,13 +98,6 @@
                            </Style>
                        </DataGrid.RowStyle>
                        <DataGrid.Columns>
                            <!--<DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>-->
                            <DataGridTemplateColumn Header="#" CanUserResize="False">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
@@ -112,30 +106,29 @@
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Code}" Header="编号" />
                            <DataGridTextColumn Width="*" Binding="{Binding Name}" Header="名称" />
                            <DataGridTextColumn Width="*" Binding="{Binding Type}" Header="类型" />
                            <DataGridTextColumn Width="*" Binding="{Binding Value}" Header="DI值" />
                            <!--<DataGridTemplateColumn Header="操作" Width="100" IsReadOnly="True" CanUserResize="False">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <Button x:Name="editBtn" Style="{StaticResource RowLink}"
            Margin="0,0,10,0"
            Click="Button_Click"
            DataContext="{Binding }">编辑</Button>
                                            <Button x:Name="delBtn" Style="{StaticResource DangerLinkButton}"
            DataContext="{Binding }"
            Click="Button_Click">删除</Button>
                                        </StackPanel>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>-->
                            <DataGridTextColumn Width="*" Binding="{Binding Code}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.Code}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Name}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.Name}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Type}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.Type}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Value}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.di.Value}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </Grid>
            </Border>
            <Border Grid.Row="1" Grid.Column="1" Style="{StaticResource CardBoarder}" Padding="0">
@@ -153,23 +146,22 @@
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Label Grid.Row="0" Grid.Column="0" Content="DO名称"
                    <Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource DIO.do.Name}"
                   FontSize="{StaticResource ContentFontSize}"/>
                    <ComboBox Grid.Row="0" Grid.Column="1" x:Name="doName"
                          IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
                    <Button Style="{StaticResource PrimaryButton}" Grid.Row="0" Grid.Column="2"
                        x:Name="doSelect" Click="Button_Click">DO查询</Button>
                        x:Name="doSelect" Click="Button_Click" Content="{DynamicResource DIO.do.Query}"/>
                    <Button Style="{StaticResource PrimaryButton}" Grid.Row="0" Grid.Column="3"
                        x:Name="doReset" Click="Button_Click"
                        >DO重置</Button>
                        x:Name="doReset" Click="Button_Click" Content="{DynamicResource DIO.do.Reset}"/>
                    <Label Grid.Row="1" Grid.Column="0" Content="DO编号"
                    <Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource DIO.do.Code}"
   FontSize="{StaticResource ContentFontSize}"/>
                    <ComboBox Grid.Row="1" Grid.Column="1" x:Name="doCode"
                          IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
                    <Label Grid.Row="2" Grid.Column="0" Content="DO分组"
                    <Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource DIO.do.Group}"
   FontSize="{StaticResource ContentFontSize}"/>
                    <ComboBox Grid.Row="2" Grid.Column="1" x:Name="doGroup"
                          IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
@@ -187,13 +179,6 @@
                            </Style>
                        </DataGrid.RowStyle>
                        <DataGrid.Columns>
                            <!--<DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>-->
                            <DataGridTemplateColumn Header="#" CanUserResize="False">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
@@ -202,25 +187,26 @@
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Code}" Header="编号" />
                            <DataGridTextColumn Width="*" Binding="{Binding Name}" Header="名称" />
                            <DataGridTextColumn Width="*" Binding="{Binding Type}" Header="类型" />
                            <DataGridTextColumn Width="*" Binding="{Binding Value}" Header="DO值" />
                            <!--<DataGridTemplateColumn Header="操作" Width="100" IsReadOnly="True" CanUserResize="False">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <Button x:Name="editBtn" Style="{StaticResource RowLink}"
        Margin="0,0,10,0"
        Click="Button_Click"
        DataContext="{Binding }">编辑</Button>
                                            <Button x:Name="delBtn" Style="{StaticResource DangerLinkButton}"
        DataContext="{Binding }"
        Click="Button_Click">删除</Button>
                                        </StackPanel>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>-->
                            <DataGridTextColumn Width="*" Binding="{Binding Code}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.Code}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Name}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.Name}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Type}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.Type}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                            <DataGridTextColumn Width="*" Binding="{Binding Value}">
                                <DataGridTextColumn.Header>
                                    <TextBlock Text="{DynamicResource DIO.do.Value}"/>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </Grid>
HMI.IOMonitor/IOMonitor.xaml.cs
@@ -290,12 +290,12 @@
        {
            IPManageModal modal = new IPManageModal(log)
            {
                Title = "新增",
                Title = this.lang("App.Add"),
                Owner = Window.GetWindow(this),
            };
            if (modal.Open(-1, new IPManage(), IPManages, SettingFilePath) == true)
            {
                this.Success("新增成功");
                this.Success(this.lang("App.AddSuccess"));
            }
        }
@@ -305,8 +305,8 @@
            OpenFileDialog dialog = new OpenFileDialog();
            ////该值确定是否可以选择多个文件
            dialog.Multiselect = false;
            dialog.Title = "请选择文件";
            dialog.Filter = "execl文件(*.xlsx;*.xls)|*.xlsx;*.xls";
            dialog.Title = this.lang("App.SelectFile");
            dialog.Filter = "execl(*.xlsx;*.xls)|*.xlsx;*.xls";
            if (dialog.ShowDialog() == true)
            {
                MonitorTimer.Enabled = false;
@@ -371,7 +371,7 @@
                catch (Exception ex)
                {
                    log.Error("Import Failed.", ex);
                    MsgBoxHelper.Error(this, $"导入失败!{ex.Message}");
                    MsgBoxHelper.Error(this, $"{this.lang("App.ImportFailed")}: {ex.Message}");
                }
            }
        }
@@ -452,7 +452,7 @@
            catch (Exception ex)
            {
                log.Error("Active Execute Failed.", ex);
                MsgBoxHelper.ErrorMessage(this, $"插件激活失败!{ex.Message}");
                MsgBoxHelper.ErrorMessage(this, $"{this.lang("DIO.ActivateFailed")}: {ex.Message}");
            }
            return null;
        }
HMI.IOMonitor/IPManageModal.xaml
@@ -20,13 +20,13 @@
            Style="{StaticResource ModalWindow}">
    <Grid Margin="10">
        <StackPanel x:Name="formPanel">
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
  Header="I点读取标签" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource DIO.ITag}"
                dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
                <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="iTag"/>
            </pu:FormGroup>
            <pu:FormGroup dp:FormGroupHelper.IsRequired="True"
  Header="Q点读取标签" GroupName="MyFormGroup">
            <pu:FormGroup Header="{DynamicResource DIO.OTag}"
                          dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
                <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="qTag"/>
            </pu:FormGroup>
        </StackPanel>
HMI.IOMonitor/IPManageModal.xaml.cs
@@ -56,7 +56,7 @@
                catch (Exception ex)
                {
                    log.Error("IPManage Form Submit Failed.", ex);
                    ToastHelper.Error(this, $"未知异常!{ex.Message}");
                    ToastHelper.Error(this, $"Error: {ex.Message}");
                    e.Cancel = true;
                    return;
                }
HMI.LogViewer/HMI.LogViewer.csproj
@@ -126,7 +126,7 @@
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.MenuManage/HMI.MenuManage.csproj
@@ -195,4 +195,8 @@
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.MenuManage/MenuManage.xaml.cs
@@ -71,12 +71,12 @@
                    List<string> ids = Model.DataSource.Where(x => x.Selected).Select(x => x.Id).ToList();
                    if (ids == null || ids.Count <= 0)
                    {
                        ToastHelper.Warning(Window.GetWindow(this), LangUtil.Get("HMI.Menu.NoDeleteData"));
                        ToastHelper.Warning(Window.GetWindow(this), LangUtil.Get("HMI.NoDeleteData"));
                        return;
                    }
                    var res = MsgBoxHelper.WarnMessage(Window.GetWindow(this),
                        string.Format(LangUtil.Get("HMI.Menu.MakeSureDeletes"), ids.Count));
                        string.Format(LangUtil.Get("HMI.MakeSureDeletes"), ids.Count));
                    if (res == MessageBoxResult.OK)
                    {
                        Model.DeleteMenuByIds(ids);
@@ -118,7 +118,7 @@
                {
                    var data = (MenuData)((Button)sender).DataContext;
                    var res = MsgBoxHelper.WarnMessage(Window.GetWindow(this),
                        string.Format(LangUtil.Get("HMI.Menu.MakeSureDeleteSingle"), data.Name));
                        string.Format(LangUtil.Get("HMI.MakeSureDeleteSingle"), data.Name));
                    if (res == MessageBoxResult.OK)
                    {
                        Model.DeleteMenuById(data.Id);
HMI.MenuManage/Modal/MenuModal.xaml.cs
@@ -202,7 +202,7 @@
            //    string FileName = openFileDialog.FileName;
            //    if (!FileName.StartsWith(BasePath))
            //    {
            //        Panuon.WPF.UI.Toast.Show(this, "请将图标移动至程序Icon目录下!", ToastPosition.Top);
            //       (this, "请将图标移动至程序Icon目录下!", ToastPosition.Top);
            //    }
            //    else
            //    {
HMI.MenuManage/Modal/RoleModal.xaml.cs
@@ -3,6 +3,7 @@
using HMI.MenuManage.Entity;
using HMI.MenuManage.Util;
using HMI.UI.DpUtil;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
using System.Collections.ObjectModel;
@@ -60,7 +61,7 @@
                }
                catch (Exception ex)
                {
                    Panuon.WPF.UI.Toast.Show(this, "Error!", ToastPosition.Top);
                    ToastHelper.Error(this, $"Error!{ex.Message}");
                    e.Cancel = true;
                    return;
                }
HMI.MenuManage/Modal/UserModal.xaml.cs
@@ -2,6 +2,7 @@
using HMI.MenuManage.Entity;
using HMI.MenuManage.Util;
using HMI.UI.DpUtil;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
using System.Collections.ObjectModel;
@@ -56,7 +57,7 @@
                }
                catch (Exception ex)
                {
                    Panuon.WPF.UI.Toast.Show(this, "Error!", ToastPosition.Top);
                    ToastHelper.Error(this, $"Error!{ex.Message}");
                    e.Cancel = true;
                    return;
                }
HMI.MenuManage/RoleManage.xaml.cs
@@ -147,7 +147,7 @@
                    catch (Exception ex)
                    {
                        log.Error("Delete Role Failed.", ex);
                        Toast.Show((WindowX)Window.GetWindow(this), LangUtil.Get("App.DeleteFailed"), ToastPosition.Top);
                        ToastHelper.Error((WindowX)Window.GetWindow(this), LangUtil.Get("App.DeleteFailed"));
                    }
                }
                else if (btn.Name == "saveMenuBtn")
@@ -155,12 +155,12 @@
                    try
                    {
                        Model.SaveRelData(Model.SelectedValue);
                        Toast.Show((WindowX)Window.GetWindow(this), LangUtil.Get("App.SaveSuccess"), ToastPosition.Top);
                        ToastHelper.Success((WindowX)Window.GetWindow(this), LangUtil.Get("App.SaveSuccess"));
                    }
                    catch (Exception ex)
                    {
                        log.Error("Save Role-Menu Failed.", ex);
                        Toast.Show((WindowX)Window.GetWindow(this), LangUtil.Get("App.SaveFailed"), ToastPosition.Top);
                        ToastHelper.Error((WindowX)Window.GetWindow(this), LangUtil.Get("App.SaveFailed"));
                    }
                }
            }
HMI.ParameterManage/HMI.ParameterManage.csproj
@@ -142,7 +142,7 @@
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.ParameterManage/Model/XmlModel.cs
@@ -69,7 +69,7 @@
            var temp = Products.FirstOrDefault(p => p.Name == name);
            if (temp != null && temp != SelectedProduct)
            {
                msg = "产品名称不能重复";
                msg = this.lang("App.MustBeUnique", this.lang("Pm.Product.Name"));
                return false;
            }
            return true;
@@ -83,7 +83,7 @@
            var temp = Parameters.FirstOrDefault(p => p.Name == name);
            if (temp != null && temp != SelectedParameter)
            {
                msg = "参数名称不能重复";
                msg = this.lang("App.MustBeUnique", this.lang("Pm.Product.Name"));
                return false;
            }
            return true;
HMI.ParameterManage/ParameterManage.xaml
@@ -33,7 +33,7 @@
                        <Button Style="{StaticResource DelBtn}" x:Name="delBatchBtn" Click="Button_Click"/>
                    </StackPanel>
                    <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" 
VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品列表"/>
VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource Pm.Product.Title}"/>
                </DockPanel>
@@ -56,16 +56,24 @@
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding Name}" Header="产品名称" />
                        <DataGridTemplateColumn Header="操作" Width="100" IsReadOnly="True" CanUserResize="False">
                        <DataGridTextColumn Width="*" Binding="{Binding Name}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Pm.Product.Name}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
                            <DataGridTemplateColumn.Header>
                                <TextBlock Text="{DynamicResource App.Opt}"/>
                            </DataGridTemplateColumn.Header>
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
                                        <Button x:Name="editProductBtn" Style="{StaticResource RowLink}"  DataContext="{Binding }"
                    Click="Button_Click">编辑</Button>
                                        <Button x:Name="delProductBtn" Style="{StaticResource DangerLinkButton}"
                                        <Button x:Name="editProductBtn" Style="{StaticResource EditLink}"  DataContext="{Binding }"
                    Click="Button_Click"/>
                                        <Button x:Name="delProductBtn" Style="{StaticResource DeleteLink}"
                    DataContext="{Binding }"
                    Click="Button_Click">删除</Button>
                    Click="Button_Click"/>
                                    </StackPanel>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
@@ -88,7 +96,7 @@
                        <Button Style="{StaticResource DelBtn}" x:Name="deleteBatchParameterBtn" Click="Button_Click"/>
                    </StackPanel>
                    <TextBlock DockPanel.Dock="Left" FontSize="{StaticResource TitleFontSize}" 
VerticalAlignment="Center" HorizontalAlignment="Left" Text="产品参数"/>
VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource Pm.Parameter.Title}"/>
                </DockPanel>
@@ -108,21 +116,44 @@
                        <DataGridTextColumn Header="#" Binding="{Binding Converter={StaticResource rowNumber},
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"
        CanUserResize="False"/>
                        <DataGridTextColumn Width="*" Binding="{Binding Name}" Header="名称" />
                        <DataGridTextColumn Width="*" Binding="{Binding Value}" Header="值" />
                        <DataGridTextColumn Width="*" Binding="{Binding Unit}" Header="单位" />
                        <DataGridTextColumn Width="*" Binding="{Binding Description}" Header="描述" />
                        <DataGridTextColumn Width="*" Binding="{Binding PGroup}" Header="分组" />
                        <DataGridTemplateColumn Header="操作" Width="100" IsReadOnly="True" CanUserResize="False">
                        <DataGridTextColumn Width="*" Binding="{Binding Name}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Pm.Parameter.Name}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding Value}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Pm.Parameter.Value}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding Unit}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Pm.Parameter.Unit}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding Description}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Pm.Parameter.Desc}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTextColumn Width="*" Binding="{Binding PGroup}">
                            <DataGridTextColumn.Header>
                                <TextBlock Text="{DynamicResource Pm.Parameter.Group}"/>
                            </DataGridTextColumn.Header>
                        </DataGridTextColumn>
                        <DataGridTemplateColumn Width="100" IsReadOnly="True" CanUserResize="False">
                            <DataGridTemplateColumn.Header>
                                <TextBlock Text="{DynamicResource App.Opt}"/>
                            </DataGridTemplateColumn.Header>
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <Button x:Name="editParameterBtn" Style="{StaticResource RowLink}" Margin="0,0,10,0"
                                        <Button x:Name="editParameterBtn" Style="{StaticResource EditLink}" Margin="0,0,10,0"
          DataContext="{Binding }"
          Click="Button_Click">编辑</Button>
                                        <Button x:Name="delParameterBtn" Style="{StaticResource DangerLinkButton}"
          Click="Button_Click"/>
                                        <Button x:Name="delParameterBtn" Style="{StaticResource DeleteLink}"
          DataContext="{Binding }"
          Click="Button_Click">删除</Button>
          Click="Button_Click"/>
                                    </StackPanel>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
HMI.ParameterManage/ParameterManage.xaml.cs
@@ -1,13 +1,11 @@
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using HMI.Base;
using HMI.Base;
using HMI.Core.Util;
using HMI.ParameterManage.Entity;
using HMI.ParameterManage.Model;
using HMI.UI.Util;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace HMI.ParameterManage
{
@@ -45,6 +43,9 @@
                case "addBtn":
                    OpenProductDialog(null);
                    break;
                case "refreshBtn":
                    Model.LoadProducts();
                    break;
                case "editProductBtn":
                    OpenProductDialog((ProductData)btn.DataContext);
                    break;
@@ -80,7 +81,7 @@
        {
            var win = new ProductModal(Model)
            {
                Title = data == null ? "新增产品" : "编辑产品",
                Title = data == null ? this.lang("Pm.Product.Add") : this.lang("Pm.Product.Edit"),
                Owner = Window.GetWindow(this),
            };
            if (win.Open(data ?? new ProductData()) == true)
@@ -93,12 +94,12 @@
        {
            if (Model.SelectedProduct == null)
            {
                ToastHelper.Warning(Window.GetWindow(this), "请先选择一项产品");
                ToastHelper.Warning(Window.GetWindow(this), this.lang("Pm.PleaseSelectProduct"));
                return;
            }
            var win = new ParameterModal(Model)
            {
                Title = data == null ? "新增参数" : "编辑参数",
                Title = data == null ? this.lang("Pm.Parameter.Add") : this.lang("Pm.Parameter.Edit"),
                Owner = Window.GetWindow(this),
            };
            if (win.Open(data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }) == true)
@@ -109,7 +110,7 @@
        private void TryDeleteProduct(ProductData data)
        {
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除产品[{data.Name}]吗?该操作无法撤销")
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeleteSingle", data.Name))
                == MessageBoxResult.OK)
            {
                Model.DeleteProduct(data);
@@ -122,10 +123,10 @@
            var temp = Model.Products.Where(p => p.IsSelected).Count();
            if (temp <= 0)
            {
                this.Warning("请选择要删除的产品");
                this.Warning(this.lang("HMI.NoDeleteData"));
                return;
            }
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除选中的[{temp}]条产品吗?该操作无法撤销")
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeletes", temp))
                == MessageBoxResult.OK)
            {
                Model.DeleteProducts();
@@ -135,7 +136,7 @@
        private void TryDeleteParameter(ParameterData data)
        {
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除参数[{data.Name}]吗?该操作无法撤销") == MessageBoxResult.OK)
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeleteSingle", data.Name)) == MessageBoxResult.OK)
            {
                Model.DeleteParameter(data);
                Model.LoadParameters();
@@ -147,10 +148,10 @@
            var temp = Model.Parameters.Where(p => p.IsSelected).Count();
            if (temp <= 0)
            {
                this.Warning("请选择要删除的参数");
                this.Warning(this.lang("HMI.NoDeleteData"));
                return;
            }
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), $"确定要删除选中的[{temp}]条参数吗?该操作无法撤销")
            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), this.lang("HMI.MakeSureDeletes", temp))
                == MessageBoxResult.OK)
            {
                Model.DeleteParameters();
HMI.ParameterManage/ParameterModal.xaml
@@ -19,35 +19,41 @@
            "{Binding Converter={StaticResource lc},ConverterParameter='App.Save'}">
    <Grid Margin="10">
        <StackPanel x:Name="formPanel">
            <pu:FormGroup x:Name="FgProductName" dp:FormGroupHelper.IsRequired="True"
                          Header="产品名称" GroupName="MyFormGroup">
            <pu:FormGroup x:Name="FgProductName"
                          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.IsRequired="True"
            <pu:FormGroup x:Name="FgName"
                          dp:FormGroupHelper.ValidateMethod="ValidateName"
                              Header="参数名称" GroupName="MyFormGroup">
                          Header="{DynamicResource Pm.Parameter.Name}"
                          dp:FormGroupHelper.IsRequired="True"  GroupName="MyFormGroup">
                <TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" />
            </pu:FormGroup>
            <pu:FormGroup x:Name="FgValue" Style="{StaticResource RequiredInputFormGroupStyle}" 
                          dp:FormGroupHelper.IsRequired="True"
                  Header="参数值" GroupName="MyFormGroup">
                          Header="{DynamicResource Pm.Parameter.Value}"
dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
                <TextBox x:Name="TbValue" Style="{StaticResource EditorTextBoxStyle}" />
            </pu:FormGroup>
            <pu:FormGroup x:Name="FgUnit" Style="{StaticResource InputFormGroupStyle}" 
      Header="单位" GroupName="MyFormGroup">
      Header="{DynamicResource Pm.Parameter.Unit}"
dp:FormGroupHelper.IsRequired="False" GroupName="MyFormGroup">
                <TextBox x:Name="TbUnit" Style="{StaticResource EditorTextBoxStyle}" />
            </pu:FormGroup>
            <pu:FormGroup x:Name="FgDescription" Style="{StaticResource InputFormGroupStyle}" 
Header="描述" GroupName="MyFormGroup">
Header="{DynamicResource Pm.Parameter.Desc}"
dp:FormGroupHelper.IsRequired="False" GroupName="MyFormGroup">
                <TextBox x:Name="TbDescription" Style="{StaticResource MultilineEditorTextBoxStyle}" />
            </pu:FormGroup>
            <pu:FormGroup x:Name="FgPGroup" Style="{StaticResource InputFormGroupStyle}" 
Header="组" GroupName="MyFormGroup">
Header="{DynamicResource Pm.Parameter.Group}"
dp:FormGroupHelper.IsRequired="False" GroupName="MyFormGroup">
                <TextBox x:Name="TbPGroup" Style="{StaticResource EditorTextBoxStyle}" />
            </pu:FormGroup>
        </StackPanel>
HMI.ParameterManage/ParameterModal.xaml.cs
@@ -2,6 +2,7 @@
using HMI.ParameterManage.Entity;
using HMI.ParameterManage.Model;
using HMI.UI.DpUtil;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
using System.ComponentModel;
@@ -51,7 +52,7 @@
                }
                catch (Exception ex)
                {
                    Panuon.WPF.UI.Toast.Show(this, "Error!", ToastPosition.Top);
                    ToastHelper.Error(this, $"Error: {ex.Message}");
                    e.Cancel = true;
                    return;
                }
HMI.ParameterManage/ParameterSetting.xaml
New file
@@ -0,0 +1,98 @@
<hb:PluginControl x:Class="HMI.ParameterManage.ParameterSetting"
             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.ParameterManage"
             xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
             xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
             xmlns:pw="https://opensource.panuon.com/wpf"
             xmlns:pu="https://opensource.panuon.com/wpf-ui"
             xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
             xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
             mc:Ignorable="d"
             Padding="10"
             Loaded="UserControl_Loaded"
             Background="{StaticResource WorkspaceBackground}"
             d:DesignHeight="450" d:DesignWidth="800">
    <Border Style="{StaticResource CardBoarder}">
        <Grid dp:GridHelper.Space="10" Cursor="">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <TextBlock FontSize="{StaticResource TitleFontSize}"
                       VerticalAlignment="Center" HorizontalAlignment="Left" Text="{DynamicResource Pm.Setting.Title}"/>
            <DockPanel Grid.Row="1" Cursor="">
                <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
                    <Button Style="{StaticResource AddBtn}"
                            x:Name="addBtn" Click="Button_Click"/>
                    <Button Style="{StaticResource RfhBtn}"
                            x:Name="refreshBtn" Click="Button_Click"/>
                    <Button x:Name="exportBtn"
                            Style="{StaticResource ExportBtn}" Click="Button_Click"/>
                    <Button x:Name="importBtn"
                            Style="{StaticResource ImportBtn}" Click="Button_Click"/>
                </StackPanel>
                <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left">
                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource HMI.Line}"/>
                    <ComboBox Style="{StaticResource FormComboxStyle}" x:Name="CbLine"/>
                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="{DynamicResource HMI.Station}"/>
                    <ComboBox Style="{StaticResource FormComboxStyle}" x:Name="CbStation"/>
                </StackPanel>
            </DockPanel>
            <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}">
                <DataGrid.RowStyle>
                    <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding type}" Value="warn">
                                <Setter Property="Background" Value="{StaticResource WarningColor}"/>
                                <Setter Property="Foreground" Value="Black"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding type}" Value="error">
                                <Setter Property="Background" Value="{StaticResource DangerColor}"/>
                                <Setter Property="Foreground" Value="Black"/>
                            </DataTrigger>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Background" Value="Transparent"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="Transparent"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </DataGrid.RowStyle>
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Header="#" CanUserResize="False">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Converter={StaticResource rowNumber},
    RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Width="*" Binding="{Binding type}" Header="级别" />
                    <DataGridTextColumn Width="*" Binding="{Binding time}" Header="时间" />
                    <DataGridTextColumn Width="*" Binding="{Binding source}" Header="来源" />
                    <DataGridTextColumn Width="*" Binding="{Binding text}" Header="文本" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Border>
</hb:PluginControl>
HMI.ParameterManage/ParameterSetting.xaml.cs
New file
@@ -0,0 +1,37 @@
using HMI.Base;
using HMI.Core.Util;
using HMI.UI.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace HMI.ParameterManage
{
    /// <summary>
    /// UserControl1.xaml 的交互逻辑
    /// </summary>
    public partial class ParameterSetting : PluginControl
    {
        public ParameterSetting()
        {
            this.DataContext = this;
            InitializeComponent();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var btn = ((Button)sender);
        }
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            Loaded -= UserControl_Loaded;
        }
    }
}
HMI.ParameterManage/ProductModal.xaml
@@ -16,31 +16,11 @@
            BorderBrush="#3E3E45"
            BorderThickness="1"
            Foreground="Black"
            pu:WindowXCaption.Background="{StaticResource PrimaryColor}"
            pu:WindowXModalDialog.ButtonStyle="{StaticResource ModalButton}"
            pu:WindowXCaption.Foreground="#FFF"
            pu:WindowXCaption.Buttons="Close"
            pu:WindowXModalDialog.Buttons="OKCancel"
            pu:WindowXModalDialog.CancelButtonContent="取消"
            pu:WindowXModalDialog.OKButtonContent="保存"
            pu:WindowXModalDialog.ButtonPanelMargin="0,30,10,10">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <pu:StyleDictionary Includes="TreeView" />
                <ResourceDictionary Source="/HMI.UI;component/Style/PanuonResource.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Resources/Font/Font.xaml"/>
                <ResourceDictionary Source="/HMI.UI;component/Style/Colors.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <uic:PathImageConverter x:Key="path2Image"/>
            <uic:DataGridRowNumberConverter x:Key="rowNumber"/>
        </ResourceDictionary>
    </Window.Resources>
            Style="{StaticResource ModalWindow}">
    <Grid Margin="10">
        <StackPanel x:Name="formPanel">
            <pu:FormGroup x:Name="FgName" Style="{StaticResource RequiredInputFormGroupStyle}" 
                              Header="产品名称" GroupName="MyFormGroup"
                              Header="{DynamicResource Pm.Product.Name}" GroupName="MyFormGroup"
                          dp:FormGroupHelper.IsRequired="True"
                          dp:FormGroupHelper.ValidateMethod="ValidateName"
                          >
@@ -48,12 +28,12 @@
            </pu:FormGroup>
            <pu:FormGroup x:Name="FgIsMaster" Style="{StaticResource InputFormGroupStyle}" 
                          Header="是否样件" GroupName="MyFormGroup">
                          Header="{DynamicResource Pm.Product.IsSample}" GroupName="MyFormGroup">
                <CheckBox x:Name="TbIsMaster"  />
            </pu:FormGroup>
            <pu:FormGroup x:Name="FgParentId" Style="{StaticResource InputFormGroupStyle}" 
                  Header="继承" GroupName="MyFormGroup">
                  Header="{DynamicResource Pm.Product.Extend}" GroupName="MyFormGroup">
                <TextBox x:Name="TbParentId" Style="{StaticResource EditorTextBoxStyle}" />
            </pu:FormGroup>
        </StackPanel>
HMI.ParameterManage/ProductModal.xaml.cs
@@ -15,6 +15,7 @@
using HMI.UI;
using HMI.ParameterManage.Model;
using HMI.UI.DpUtil;
using HMI.UI.Util;
namespace HMI.ParameterManage
{
@@ -62,7 +63,7 @@
                }
                catch (Exception ex)
                {
                    Panuon.WPF.UI.Toast.Show(this, "Error!", ToastPosition.Top);
                    ToastHelper.Error(this, $"Error: {ex.Message}");
                    e.Cancel = true;
                    return;
                }
HMI.ParameterManage/Util/ParameterManager.cs
@@ -10,6 +10,7 @@
        public static List<ProductData> GetProducts()
        {
            string path = Path.Combine(ParameterManage.FileFolder, "Product.setting");
            if (!File.Exists(path)) return new List<ProductData>();
            List<ProductData> datas = XmlHelper.DeserializeFromXml<List<ProductData>>(path);
            return datas;
        }
@@ -17,6 +18,7 @@
        public static List<ParameterData> GetParametersByProductName(string productName)
        {
            string path = Path.Combine(ParameterManage.FileFolder, "Parameter", $"Parameter_{productName}.setting");
            if (!File.Exists(path)) return new List<ParameterData>();
            List<ParameterData> datas = XmlHelper.DeserializeFromXml<List<ParameterData>>(path);
            return datas;
        }
HMI.SettingControl/HMI.SettingControl.csproj
@@ -133,7 +133,7 @@
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
HMI.UI/DpUtil/DataGridTextColumnHelper.cs
New file
@@ -0,0 +1,28 @@
using System.Windows.Controls;
using System.Windows;
namespace HMI.UI.DpUtil
{
    public class DataGridColumnHelper
    {
        public static object GetBindHeader(DataGridColumn obj)
        {
            return obj.GetValue(BindHeaderProperty);
        }
        public static void SetBindHeader(DataGridColumn obj, object value)
        {
            obj.SetValue(BindHeaderProperty, value);
        }
        public static readonly DependencyProperty BindHeaderProperty =
            DependencyProperty.Register("BindHeader", typeof(object), typeof(DataGridColumn),
                new PropertyMetadata(null, OnBindHeaderChanged));
        private static void OnBindHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.Property != BindHeaderProperty) return;
            if (!(d is DataGridColumn column)) return;
            column.Header = e.NewValue;
        }
    }
}
HMI.UI/DpUtil/FormGroupHelper.cs
@@ -89,7 +89,7 @@
                return elementCollection.Count > 0 ? GetValidateValue(elementCollection[0]) : null;
            if (content is TextBox tb) return tb.Text;
            if (content is CheckBox cb) return cb.IsChecked;
            if (content is ComboBox cBox) return cBox.SelectedValue;
            if (content is ComboBox cBox) return cBox.SelectedItem ?? cBox.SelectedValue ?? cBox.Text;
            if (content is Panel panel) return GetValidateValue(panel.Children);
            if (content is NumberInput numberInput) return numberInput.Value;
HMI.UI/HMI.UI.csproj
@@ -84,6 +84,7 @@
    <Compile Include="Converter\DataGridRowNumberConverter.cs" />
    <Compile Include="Converter\PathImageConverter.cs" />
    <Compile Include="DpUtil\DataGridHelper.cs" />
    <Compile Include="DpUtil\DataGridTextColumnHelper.cs" />
    <Compile Include="DpUtil\FormGroupHelper.cs" />
    <Compile Include="DpUtil\GridHelper.cs" />
    <Compile Include="DpUtil\StackPanelHelper.cs" />
@@ -103,7 +104,6 @@
    <Resource Include="Resources\Font\Font.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Resource>
    <Page Include="MaskWindow.xaml">
      <SubType>Designer</SubType>
@@ -162,9 +162,7 @@
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <Resource Include="Resources\Font\iconfont.json" />
    <Resource Include="Resources\Font\iconfont.ttf">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Resource>
    <Resource Include="Resources\Font\iconfont.ttf" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Resources\Icon\xinzeng_1.png" />
HMI.UI/Resources/Font/iconfont.json
@@ -6,6 +6,20 @@
  "description": "",
  "glyphs": [
    {
      "icon_id": "12939974",
      "name": "编辑",
      "font_class": "bianji1",
      "unicode": "e643",
      "unicode_decimal": 58947
    },
    {
      "icon_id": "6537207",
      "name": "编辑",
      "font_class": "bianji",
      "unicode": "e678",
      "unicode_decimal": 59000
    },
    {
      "icon_id": "3868271",
      "name": "测试申请",
      "font_class": "ceshishenqing",
HMI.UI/Resources/Font/iconfont.ttf
Binary files differ
HMI.UI/Style/FormStyle.xaml
@@ -50,6 +50,7 @@
    <Style x:Key="SearchButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="pu:ButtonHelper.CornerRadius" Value="0" />
        <Setter Property="Width" Value="30" />
        <Setter Property="Background" Value="{StaticResource VerBar}" />
        <Setter Property="Foreground" Value="{StaticResource PrimaryColorContract}" />
        <Setter Property="FontFamily" Value="{StaticResource iconfont}" />
@@ -108,8 +109,7 @@
                
            </Style>
        </Style.Resources>
        <Setter Property="HeaderWidth" Value="70" />
        <Setter Property="HeaderHeight" Value="35" />
        <Setter Property="HeaderWidth" Value="Auto" />
        <Setter Property="Orientation" Value="Horizontal" />
        <Setter Property="Margin" Value="0,10,0,0" />
    </Style>
@@ -151,7 +151,7 @@
        <Setter Property="ItemsHoverBackground" Value="{StaticResource SecondPrimaryColor}"/>
        <Setter Property="ItemsHoverForeground" Value="{StaticResource SecondPrimaryColorContract}"/>
        <Setter Property="TextStringFormat" Value="yyyy-MM-dd HH:mm:ss"/>
        <Setter Property="Width" Value="180"/>
        <Setter Property="MinWidth" Value="180"/>
        <Setter Property="Mode" Value="DateTime"/>
        <Setter Property="SelectedDateTime" Value="{x:Null}"/>
    </Style>
HMI.UI/Style/PanuonResource.xaml
@@ -53,6 +53,11 @@
        <Setter Property="Content" Value="{DynamicResource App.Add}"/>
    </Style>
    <Style x:Key="EditBtn" TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
        <Setter Property="pu:ButtonHelper.Icon" Value="&#xe643;"/>
        <Setter Property="Content" Value="{DynamicResource App.Edit}"/>
    </Style>
    <Style x:Key="RfhBtn" TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
        <Setter Property="pu:ButtonHelper.Icon" Value="&#xe631;"/>
        <Setter Property="Content" Value="{DynamicResource App.Refresh}"/>
@@ -198,7 +203,7 @@
        <Setter Property="SelectionMode" Value="Single"/>
        <Setter Property="RowStyle" Value="{StaticResource DefaultDataGridRow}"/>
        <Setter Property="AlternationCount" Value="2"></Setter>
        <Setter Property="Foreground" Value="#878787"/>
        <Setter Property="Foreground" Value="#3a3a3a"/>
        <Setter Property="HorizontalGridLinesBrush" Value="{StaticResource TableBoarder}"/>
        <Setter Property="VerticalGridLinesBrush" Value="{StaticResource TableBoarder}"/>
        <Setter Property="BorderBrush" Value="{StaticResource TableBoarder}" />
HMI.UI/Util/MsgBoxHelper.cs
@@ -1,6 +1,7 @@
using Panuon.WPF.UI;
using System.Windows;
using Panuon.WPF.UI.Configurations;
using HMI.Core.Util;
namespace HMI.UI.Util
{
@@ -9,11 +10,12 @@
        #region Warn
        public static MessageBoxResult WarnMessage(Window owner,
            string message,
            string caption = "警告",
            string caption = null,
            MessageBoxButton button = MessageBoxButton.OKCancel,
            MessageBoxIcon icon = MessageBoxIcon.Warning,
            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
        {
            caption = caption ?? LangUtil.Get("App.Warn");
            var setting = Application.Current.FindResource("MsgBoxWarn") as MessageBoxXSetting;
            return ShowMessage(owner, message, caption, button, icon, defaultButton, setting, countdown);
        }
@@ -22,22 +24,24 @@
        #region Error
        public static MessageBoxResult ErrorMessage(DependencyObject owner,
            string message,
            string caption = "错误",
            string caption = null,
            MessageBoxButton button = MessageBoxButton.OKCancel,
            MessageBoxIcon icon = MessageBoxIcon.Error,
            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
        {
            caption = caption ?? LangUtil.Get("App.Error");
            var setting = Application.Current.FindResource("MsgBoxError") as MessageBoxXSetting;
            return ShowMessage(owner, message, caption, button, icon, defaultButton, setting, countdown);
        }
        public static MessageBoxResult Error(DependencyObject owner,
            string message,
            string caption = "错误",
            string caption = null,
            MessageBoxButton button = MessageBoxButton.OK,
            MessageBoxIcon icon = MessageBoxIcon.Error,
            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
        {
            caption = caption ?? LangUtil.Get("App.Error");
            var setting = Application.Current.FindResource("MsgBoxError") as MessageBoxXSetting;
            return ShowMessage(owner, message, caption, button, icon, defaultButton, setting, countdown);
        }
@@ -46,11 +50,12 @@
        #region Info
        public static MessageBoxResult InfoMessage(Window owner,
            string message,
            string caption = "提示",
            string caption = null,
            MessageBoxButton button = MessageBoxButton.OKCancel,
            MessageBoxIcon icon = MessageBoxIcon.Info,
            DefaultButton defaultButton = DefaultButton.Unset, int? countdown = null)
        {
            caption = caption ?? LangUtil.Get("App.Info");
            var setting = Application.Current.FindResource("MsgBoxInfo") as MessageBoxXSetting;
            return ShowMessage(owner, message, caption, button, icon, defaultButton, setting, countdown);
        }
Libs/CommonLibs.dll
Binary files differ
Libs/ConfigManage.dll
Binary files differ
Libs/DatabaseHelper.dll.config
File was deleted
Libs/DatabaseHelper.xml
File was deleted
Libs/FTPTool.dll
Binary files differ
Libs/FactoryControl.dll
Binary files differ
Libs/FactoryControlX.dll
Binary files differ
Libs/FactoryControlX.xml
File was deleted
Libs/GetMD5Value.dll
Binary files differ
Libs/HMI.Framework.Logger.dll
Binary files differ
Libs/ICSharpCode.SharpZipLib.dll
Binary files differ
Libs/KeyGenDlls.dll
Binary files differ
Libs/KeyboardControl.dll
Binary files differ
Libs/KeyboardControl.xml
File was deleted
Libs/LSMSInterface.dll
Binary files differ
Libs/LSMSInterface.xml
File was deleted
Libs/LTMES.dll
Binary files differ
Libs/LTSCADA.dll
Binary files differ
Libs/LTSCADAApi.dll
Binary files differ
Libs/LTSqlHelper.dll
Binary files differ
Libs/LTSqlHelper.dll.config
File was deleted
Libs/LV2CSharp.dll
Binary files differ
Libs/LV2CSharp.xml
File was deleted
Libs/LampHelper.dll
Binary files differ
Libs/MenuHelper.dll
Binary files differ
Libs/Microsoft.Practices.Unity.Configuration.dll
Binary files differ
Libs/Microsoft.Practices.Unity.RegistrationByConvention.dll
Binary files differ
Libs/Microsoft.Practices.Unity.dll
Binary files differ
Libs/NPOI.OOXML.dll
Binary files differ
Libs/NPOI.OpenXml4Net.dll
Binary files differ
Libs/NPOI.OpenXmlFormats.dll
Binary files differ
Libs/NPOI.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.API.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.API.xml
File was deleted
Libs/NationalInstruments.TestStand.Interop.AdapterAPI.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.AdapterAPI.xml
File was deleted
Libs/NationalInstruments.TestStand.Interop.SequenceAnalyzer.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.UI.AxControls.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.UI.Support.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.UI.Support.xml
File was deleted
Libs/NationalInstruments.TestStand.Interop.UI.dll
Binary files differ
Libs/NationalInstruments.TestStand.Interop.UI.xml
File was deleted
Libs/NationalInstruments.TestStand.Utility.dll
Binary files differ
Libs/NationalInstruments.TestStand.Utility.xml
File was deleted
Libs/Newtonsoft.Json.dll
Binary files differ
Libs/Newtonsoft.Json.xml
File was deleted
Libs/OfficeNpoiHelper.dll
Binary files differ
Libs/OfficeNpoiHelper.xml
File was deleted
Libs/ParameterHelper.dll
Binary files differ
Libs/PathHelper.dll
Binary files differ
Libs/PictureHelper.dll
Binary files differ
Libs/Plugin.Keygen.dll
Binary files differ
Libs/Plugin.dll
Binary files differ
Libs/SuperSocket.Common.XML
File was deleted
Libs/SuperSocket.Common.dll
Binary files differ
Libs/SuperSocket.Facility.XML
File was deleted
Libs/SuperSocket.Facility.dll
Binary files differ
Libs/SuperSocket.SocketBase.XML
File was deleted
Libs/SuperSocket.SocketBase.dll
Binary files differ
Libs/SuperSocket.SocketEngine.XML
File was deleted
Libs/SuperSocket.SocketEngine.dll
Binary files differ
Libs/SupersocketCommon.dll
Binary files differ
Libs/System.Data.SQLite.dll.config
File was deleted
Libs/System.Data.SQLite.xml
File was deleted
Libs/System.Runtime.Serialization.dll
Binary files differ
Libs/SystemSetting.dll
Binary files differ
Libs/UserInfo.dll
Binary files differ
Libs/UserInfo.dll.config
File was deleted
Libs/UserInfo.xml
File was deleted
Libs/WcfServer.dll
Binary files differ
Libs/WcfServer.dll.config
File was deleted
Libs/WcfServer.xml
File was deleted
Libs/WcfServiceContract.dll
Binary files differ
Libs/WcfServiceContract.xml
File was deleted
Libs/languageHelper.dll
Binary files differ
Libs/languageHelper.dll.config
File was deleted
Libs/log4net.dll
Binary files differ
Libs/mscorlib.dll
Binary files differ
Libs/stdole.dll
Binary files differ
Plugin.TestResult/ChartWindow.xaml.cs
@@ -1,4 +1,5 @@
using Panuon.WPF.UI;
using HMI.Core.Util;
using Panuon.WPF.UI;
using System.Windows;
namespace Plugin.TestResult_WPF
@@ -17,7 +18,7 @@
        public ChartWindow(string title)
        {
            this.title = $"{title}详细曲线";
            this.title = $"{title}{this.lang("Tr.DetailChart")}";
            this.DataContext = this;
            InitializeComponent();
        }
Plugin.TestResult/DataTable.xaml
@@ -40,8 +40,7 @@
                   VerticalContentAlignment="Stretch" Background="Transparent" Content="{Binding title}"/>
            <local:InfoTable x:Name="infoTable" Grid.Row="0" Grid.Column="1"
               FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl}, 
            Converter={StaticResource FontSizeConverter}, ConverterParameter='15,940'}"
                             ></local:InfoTable>
            Converter={StaticResource FontSizeConverter}, ConverterParameter='15,940'}"></local:InfoTable>
        </Grid>
        <UniformGrid x:Name="mainGrid" Grid.Row="1" Columns="6" dp:UniformGridHelper.InnerBorder="1"
@@ -84,6 +83,8 @@
            </StatusBarItem>
        </StatusBar>
        <Button Grid.Row="4" Click="SetStationGlobal_Click" Style="{StaticResource SuccessButton}">启动</Button>
        <Button Grid.Row="4" Click="SetStationGlobal_Click" Style="{StaticResource SuccessButton}"
                Content="{DynamicResource App.Start}"
                />
    </Grid>
</UserControl>
Plugin.TestResult/DataTable.xaml.cs
@@ -1,11 +1,9 @@
using Plugin.TestResult_WPF.Model;
using HMI.Core.Util;
using Plugin.TestResult_WPF.Model;
using SuperSocket.SocketBase.Protocol;
using System;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
@@ -55,7 +53,7 @@
            set { RaiseAndSetIfchanged(ref tcpServerStatus, value); }
        }
        private string tcpServerInfo = "未启动";
        private string tcpServerInfo = LangUtil.Get("App.NotStarted");
        public string TcpServerInfo
        {
@@ -208,20 +206,20 @@
                    tcpServer.NewRequestReceived += TcpServer_NewRequestReceived;
                    if (!tcpServer.Setup(config.PortStart + index))
                    {
                        ChangeTcpServerStatus("ERROR", "服务设置异常");
                        ChangeTcpServerStatus("ERROR", this.lang("Tr.TcpServer.SettingFailed"));
                        return;
                    }
                    if (!tcpServer.Start())
                    {
                        ChangeTcpServerStatus("ERROR", "服务启动异常");
                        ChangeTcpServerStatus("ERROR", this.lang("Tr.TcpServer.StartFailed"));
                        return;
                    }
                    ChangeTcpServerStatus("RUNNING", "服务运行中");
                    ChangeTcpServerStatus("RUNNING", this.lang("Tr.TcpServer.Running"));
                }
            }
            catch (Exception ex)
            {
                ChangeTcpServerStatus("ERROR", $"服务异常:{ex.Message}");
                ChangeTcpServerStatus("ERROR", $"{ex.Message}");
                tcpServer?.Stop();
                tcpServer = null;
            }
Plugin.TestResult/InfoTable.xaml
@@ -38,9 +38,9 @@
            <ColumnDefinition Width="1.5*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0">温度</Label>
        <Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource Tr.Temperature}"/>
        <Label Grid.Row="0" Grid.Column="1" Background="Yellow" Content="{Binding temperatureStr}"/>
        <Label Grid.Row="0" Grid.Column="2">状态</Label>
        <Label Grid.Row="0" Grid.Column="2" Content="{DynamicResource Tr.Status}"/>
        <Label Grid.Row="0" Grid.Column="3" Content="{Binding statusStr}">
            <Label.Style>
                <Style TargetType="Label">
@@ -75,14 +75,14 @@
                </Style>
            </Label.Style>
        </Label>
        <Label Grid.Row="0" Grid.Column="4">老化数量</Label>
        <Label Grid.Row="0" Grid.Column="4" Content="{DynamicResource Tr.Count}"/>
        <Label Grid.Row="0" Grid.Column="5" Background="Yellow" Content="{Binding countStr}"/>
        <Label Grid.Row="1" Grid.Column="0">开始时间</Label>
        <Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource Tr.StartTime}"/>
        <Label Grid.Row="1" Grid.Column="1" Background="Yellow" Content="{Binding startTimeStr}"/>
        <Label Grid.Row="1" Grid.Column="2">已老化时间</Label>
        <Label Grid.Row="1" Grid.Column="2" Content="{DynamicResource Tr.ElapsedTime}"/>
        <Label Grid.Row="1" Grid.Column="3" Background="Yellow" Content="{Binding consumeTimeStr}"/>
        <Label Grid.Row="1" Grid.Column="4">预计结束时间</Label>
        <Label Grid.Row="1" Grid.Column="4" Content="{DynamicResource Tr.EstimatedEndTime}"/>
        <Label Grid.Row="1" Grid.Column="5" Background="Yellow" Content="{Binding endTimeStr}"/>
    </Grid>
</UserControl>
Plugin.TestResult/InfoWindow.xaml
@@ -13,7 +13,7 @@
        xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
        xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
        InteropOwnersMask="False"
            Topmost="False"
        Topmost="False"
        pu:WindowXModalDialog.Buttons="{x:Null}"
        Title="{Binding title}" Height="500" Width="800">
    <DataGrid ItemsSource="{Binding dataSource}"
@@ -29,32 +29,32 @@
            </DataGridTemplateColumn>
            <DataGridTextColumn Width="*" Binding="{Binding step}">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding Converter={StaticResource lc},ConverterParameter='Ts.TestName'}"/>
                    <TextBlock Text="{DynamicResource Test.Name}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*" Binding="{Binding value}">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding Converter={StaticResource lc},ConverterParameter='Ts.TestValue'}"/>
                    <TextBlock Text="{DynamicResource Test.Value}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*" Binding="{Binding result}">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding Converter={StaticResource lc},ConverterParameter='Ts.TestResult'}"/>
                    <TextBlock Text="{DynamicResource Test.Result}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*" Binding="{Binding range}">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding Converter={StaticResource lc},ConverterParameter='Test.Range'}"/>
                    <TextBlock Text="{DynamicResource Test.Range}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*" Binding="{Binding condition}">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding Converter={StaticResource lc},ConverterParameter='Test.Condition'}"/>
                    <TextBlock Text="{DynamicResource Test.Condition}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="*" Binding="{Binding updateTime}">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding Converter={StaticResource lc},ConverterParameter='Test.UpdateTime'}"/>
                    <TextBlock Text="{DynamicResource Test.UpdateTime}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
        </DataGrid.Columns>
Plugin.TestResult/OpenTK.dll.config
File was deleted
Plugin.TestResult/Plugin.TestResult.csproj
@@ -275,14 +275,11 @@
    <None Include="app.config" />
    <None Include="Config\log4net.config" />
    <None Include="Config\log4net.unix.config" />
    <None Include="OpenTK.dll.config" />
    <None Include="packages.config" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <None Include="supersocket.cmd" />
    <None Include="supersocket.sh" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Resource\checkInFailed2.png" />
@@ -340,7 +337,7 @@
  <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" />
  <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
</Project>
Plugin.TestResult/Scanner.xaml
@@ -44,19 +44,19 @@
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" Padding="0"
               Content="{Binding Converter={StaticResource lc},ConverterParameter='Tr.PleaseScanSnr'}"
               Content="{DynamicResource Tr.PleaseScanSnr}"
               Margin="0,0,0,20"
               />
        <StackPanel Grid.Row="1">
            <pu:FormGroup 
                dp:FormGroupHelper.IsRequired="True"
                Header="{Binding Converter={StaticResource lc},ConverterParameter='Tr.PositionSnr'}">
                Header="{DynamicResource Tr.PositionSnr}">
                <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="positionText" TextWrapping="NoWrap"/>
            </pu:FormGroup>
            <pu:FormGroup 
                dp:FormGroupHelper.IsRequired="True"
                Header="{Binding Converter={StaticResource lc},ConverterParameter='Tr.ProductSnr'}">
                Header="{DynamicResource Tr.ProductSnr}">
                <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="snrText" TextWrapping="NoWrap"/>
            </pu:FormGroup>
        </StackPanel>
@@ -65,9 +65,9 @@
                    dp:StackPanelHelper.ChildSpace="50"
                    HorizontalAlignment="Center" Grid.Row="2">
            <Button Click="Con_Click" 
                    Content="{Binding Converter={StaticResource lc},ConverterParameter='Tr.ContinueScan'}"/>
                    Content="{DynamicResource Tr.ContinueScan}"/>
            <Button Click="Ok_Click" 
                    Content="{Binding Converter={StaticResource lc},ConverterParameter='Tr.FinishScan'}"/>
                    Content="{DynamicResource Tr.FinishScan}"/>
        </StackPanel>
    </Grid>
</pu:WindowX>
Plugin.TestResult/Scanner.xaml.cs
@@ -1,4 +1,5 @@
using HMI.UI.Util;
using HMI.Core.Util;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
using System.ComponentModel;
@@ -59,7 +60,7 @@
        {
            string comStr = "";
            if (serialPort != null) return;
            if (this.title == "一区扫码")
            if (this.Tag == "Zone1")
            {
                comStr = "COM1";
            }
@@ -93,7 +94,8 @@
            }
            catch (Exception ex)
            {
                MsgBoxHelper.Error(this, $"初始化扫码枪失败!{ex.StackTrace}");
                ViewControl.Logger.Error("Init Scan Gun Failed.", ex);
                MsgBoxHelper.Error(this, $"{this.lang("Tr.InitGunFailed")}: {ex.StackTrace}");
            }
        }
@@ -123,7 +125,8 @@
            }
            catch (Exception ex)
            {
                MessageBox.Show($"获取扫码枪数据失败!{ex.StackTrace}");
                ViewControl.Logger.Error("Get Scan Gun Data Failed.", ex);
                MessageBox.Show($"{this.lang("Tr.GetGunData")}: {ex.StackTrace}");
            }
        }
@@ -134,19 +137,20 @@
                string position = positionText.Text, snr = snrText.Text;
                if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
                {
                    MessageBox.Show("请输入储位条码和产品条码");
                    ToastHelper.Warning(this, this.lang("Tr.PleaseInputSnrs"));
                    return;
                }
                try
                {
                    FinishBarcode.Invoke(this, new BarcodeEventArg(title, position, snr));
                    FinishBarcode.Invoke(this, new BarcodeEventArg(Tag.ToString(), position, snr));
                    //positionText.Text = "";
                    //snrText.Text = "";
                    positionText.Focus();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    ViewControl.Logger.Error("Con_Click Failed.", ex);
                    ToastHelper.Warning(this, ex.Message);
                }
            });
        }
@@ -156,17 +160,18 @@
            string position = positionText.Text, snr = snrText.Text;
            if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
            {
                MessageBox.Show("请输入储位条码和产品条码");
                ToastHelper.Warning(this, this.lang("Tr.PleaseInputSnrs"));
                return;
            }
            try
            {
                FinishBarcode.Invoke(this, new BarcodeEventArg(title, position, snr));
                FinishBarcode.Invoke(this, new BarcodeEventArg(Tag.ToString(), position, snr));
                this.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                ViewControl.Logger.Error("Con_Click Failed.", ex);
                ToastHelper.Warning(this, ex.Message);
            }
        }
Plugin.TestResult/SingleCell.xaml
@@ -13,9 +13,9 @@
        <local:FontSizeConverter x:Key="FontSizeConverter"/>
    </UserControl.Resources>
    <UserControl.ToolTip>
    <!--<UserControl.ToolTip>
        <ToolTip Padding="5" BorderThickness="1" BorderBrush="Black" Background="Yellow" Content="{Binding tooltipContent}"/>
    </UserControl.ToolTip>
    </UserControl.ToolTip>-->
    <UserControl.Style>
        <Style TargetType="UserControl">
Plugin.TestResult/TestResultView.xaml.cs
@@ -1,4 +1,6 @@
using NationalInstruments.TestStand.Interop.API;
using HMI.Core.Util;
using HMI.UI.Util;
using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using NationalInstruments.TestStand.Utility;
using Plugin.TestResult_WPF.Constant;
@@ -164,7 +166,8 @@
            }
            catch (Exception ex)
            {
                throw new Exception("初始化TS引擎失败:" + ex.Message);
                ViewControl.Logger.Error("InitTestStandEngine Failed.", ex);
                throw new Exception($"{this.lang("Ts.InitTestStandEngineFail")}: {ex.Message}");
            }
        }
@@ -179,7 +182,8 @@
            }
            catch (Exception ex)
            {
                throw new Exception("启动测试序列失败:" + ex.Message);
                ViewControl.Logger.Error("StartTestSequence Failed.", ex);
                throw new Exception($"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}");
            }
        }
@@ -198,7 +202,8 @@
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
                ViewControl.Logger.Error("StopTest Failed.", ex);
                throw new Exception($"{this.lang("Ts.StopTestSequenceFailed")}: {ex.Message}");
            }
        }
@@ -216,7 +221,8 @@
            }
            catch (Exception ex)
            {
                MessageBox.Show("释放测试序列失败:" + ex.Message);
                MsgBoxHelper.Error(Window.GetWindow(this),
                    $"{this.lang("Ts.ReleaseSequenceFileFail")}: {ex.Message}");
            }
        }
@@ -360,7 +366,7 @@
            }
            catch (Exception ex)
            {
                ViewControl.Logger.Warn("TestStand Event Error.", ex);
            }
        }
Plugin.TestResult/ViewControl.xaml
@@ -39,11 +39,11 @@
        </Grid.ColumnDefinitions>
        <local:TestResultView x:Name="testResultView" Grid.Column="0" Loaded="testResultView_Loaded" />
        <StackPanel Grid.Column="1" Background="#FFF">
            <GroupBox Header="产品信息">
            <GroupBox Header="{DynamicResource Tr.ProductInfo}">
                <ComboBox x:Name="modelSelect" Style="{StaticResource FormComboxStyle}"
                          SelectionChanged="modelSelect_SelectionChanged"></ComboBox>
            </GroupBox>
            <GroupBox Header="生产统计">
            <GroupBox Header="{DynamicResource Tr.Status}">
                <StackPanel>
                    <Label HorizontalContentAlignment="Center" HorizontalAlignment="Stretch">
                        <Label.Style>
@@ -54,12 +54,12 @@
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding mesStatus}" Value="true">
                                        <Setter Property="Background" Value="Green"/>
                                        <Setter Property="Content" Value="MES开"/>
                                        <Setter Property="Content" Value="{DynamicResource Tr.MES_OPEN}"/>
                                        <Setter Property="Foreground" Value="White"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding mesStatus}" Value="false">
                                        <Setter Property="Background" Value="Red"/>
                                        <Setter Property="Content" Value="MES关"/>
                                        <Setter Property="Content" Value="{DynamicResource Tr.MES_CLOSE}"/>
                                        <Setter Property="Foreground" Value="White"/>
                                    </DataTrigger>
                                </Style.Triggers>
@@ -94,25 +94,17 @@
            </GroupBox>
            <GroupBox Header="操作">
                <StackPanel dp:StackPanelHelper.ChildSpace="20">
                    <Button x:Name="btnStart" Click="Start_Click" Style="{StaticResource SuccessButton}">
                        <Button.Content>启动</Button.Content>
                    </Button>
                    <Button x:Name="btnStart" Click="Start_Click" Style="{StaticResource SuccessButton}"
                            Content="{DynamicResource App.Start}"/>
                    <Button x:Name="btnStop" Click="Stop_Click" Style="{StaticResource DangerButton}">
                        <Button.Content>停止</Button.Content>
                    </Button>
                    <Button x:Name="btnStop" Click="Stop_Click" Style="{StaticResource DangerButton}"
                            Content="{DynamicResource App.Stop}"/>
                    <Button x:Name="btnScan1" Click="Scan_Click_1" Style="{StaticResource PrimaryButton}">
                        <Button.Content>一区扫码</Button.Content>
                    </Button>
                    <Button x:Name="btnScan1" Click="Scan_Click_1" Style="{StaticResource PrimaryButton}"
                            Content="{DynamicResource Tr.Zone1Scan}"/>
                    <Button x:Name="btnScan2" Click="Scan_Click_2" Style="{StaticResource PrimaryButton}">
                        <Button.Content>二区扫码</Button.Content>
                    </Button>
                    <!-- <Button Content="计数清零"/>
                    <Button Content="扫码"/>
                    <Button Content="一区手动"/>
                    <Button Content="二区手动"/>-->
                    <Button x:Name="btnScan2" Click="Scan_Click_2" Style="{StaticResource PrimaryButton}"
                            Content="{DynamicResource Tr.Zone2Scan}"/>
                </StackPanel>
            </GroupBox>
        </StackPanel>
Plugin.TestResult/ViewControl.xaml.cs
@@ -1,6 +1,9 @@
using HMI.Base;
using HMI.Core.Util;
using HMI.ParameterManage.Entity;
using HMI.ParameterManage.Util;
using HMI.UI.Util;
using log4net;
using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using Plugin.TestResult_WPF.Model;
@@ -33,6 +36,8 @@
        /// </summary>
        private SequenceContext SequenceContext = null;
        public static ILog Logger { get; private set; }
        private bool _mesStatus;
@@ -50,7 +55,11 @@
            set => Set(ref _produceStatus, value);
        }
        public override void SetLogger(ILog logger)
        {
            base.SetLogger(logger);
            Logger = logger;
        }
        public ViewControl()
        {
@@ -160,7 +169,9 @@
            }
            catch (Exception ex)
            {
                MessageBox.Show("启动测试失败!" + ex.Message);
                log.Error("Start_Click Failed.", ex);
                MsgBoxHelper.Error(Window.GetWindow(this),
                    $"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}");
            }
        }
@@ -175,7 +186,9 @@
            }
            catch (Exception ex)
            {
                MessageBox.Show("停止测试失败!" + ex.Message);
                log.Error("Stop_Click Failed.", ex);
                MsgBoxHelper.Error(Window.GetWindow(this),
                    $"{this.lang("Ts.StopTestSequenceFailed")}: {ex.Message}");
            }
        }
@@ -183,7 +196,10 @@
        {
            if (scannerWindow1 == null)
            {
                scannerWindow1 = new Scanner("一区扫码");
                scannerWindow1 = new Scanner(this.lang("Tr.Zone1Scan"))
                {
                    Tag = "Zone1"
                };
                scannerWindow1.FinishBarcode += ScannerWindow_FinishBarcode;
                //scannerWindow1.Owner = Window.GetWindow(this);
                scannerWindow1.Closed += ScannerWindow1_Closed;
@@ -199,7 +215,10 @@
        {
            if (scannerWindow2 == null)
            {
                scannerWindow2 = new Scanner("二区扫码");
                scannerWindow2 = new Scanner(this.lang("Tr.Zone2Scan"))
                {
                    Tag = "Zone2"
                };
                scannerWindow2.FinishBarcode += ScannerWindow_FinishBarcode;
                scannerWindow2.Owner = Window.GetWindow(this);
                scannerWindow2.Closed += ScannerWindow2_Closed;
@@ -221,14 +240,14 @@
            if (this.SequenceContext == null) return;
            CellInfo cellInfo = codeParser.GetCellInfoByCode(e.positionCode);
            string paramName = e.name == "一区扫码" ? "StationState.StartScanner_A" : "StationState.StartScanner_B";
            string paramName = e.name == "Zone1" ? "StationState.StartScanner_A" : "StationState.StartScanner_B";
            testResultView.engine.Globals.SetValBoolean(paramName, 0, true);
            string positionCode = e.positionCode, snrCode = e.snrCode;
            //需要增加条码校验功能
            //将读到的条码写入到SN中
            int dutNo = Convert.ToInt16(positionCode.Split('-')[2]) - 1;
            string LookupStr = e.name == "一区扫码" ? $"StationState.SN[{dutNo}]" : $"StationState.SN[{(dutNo + 54)}]";
            string LookupStr = e.name == "Zone1" ? $"StationState.SN[{dutNo}]" : $"StationState.SN[{(dutNo + 54)}]";
            //this.SequenceContext.StationGlobals.SetValString(LookupStr, 0, snrCode);
            //string code = this.SequenceContext.StationGlobals.GetValString(LookupStr, 0);
@@ -251,6 +270,6 @@
        {
        }
    }
}
Plugin.TestResult/supersocket.cmd
File was deleted
Plugin.TestResult/supersocket.sh
File was deleted
Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -199,8 +199,8 @@
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetPath)" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetFileName)"
copy /Y "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)\Plugin\$(TargetName).pdb"</PostBuildEvent>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
  <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
Plugin.TsExecution/SingleControl.xaml
@@ -161,11 +161,24 @@
                        <TextBlock Text="{DynamicResource Test.LimitUp}"/>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>
                <DataGridTextColumn Width="*" Binding="{Binding Result}">
                    <DataGridTextColumn.Header>
                <DataGridTemplateColumn Width="*">
                    <DataGridTemplateColumn.Header>
                        <TextBlock Text="{DynamicResource Test.Result}"/>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>
                    </DataGridTemplateColumn.Header>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="text" VerticalAlignment="Center" Text="{Binding Result}"/>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding Result}" Value="Passed">
                                    <Setter TargetName="text" Property="Foreground" Value="Green"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Result}" Value="Failed">
                                    <Setter TargetName="text" Property="Foreground" Value="Red"/>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
Plugin.TsExecution/SingleControl.xaml.cs
@@ -243,7 +243,7 @@
            TotalNum = PassNum + FailNum;
            if (TotalNum != 0)
            {
                PassRate = (PassNum / TotalNum) * 100;
                PassRate = (PassNum / TotalNum);
            }
            else
            {
Plugin.TsExecution/TsExecution.xaml
@@ -51,19 +51,19 @@
            <GroupBox Grid.Row="1">
                <StackPanel>
                    <pu:FormGroup Header="{DynamicResource Ts.Total}">
                    <pu:FormGroup Header="{DynamicResource Ts.Total}" GroupName="Number">
                        <TextBox Style="{StaticResource EditorTextBoxStyle}"  IsReadOnly="True"
                 x:Name="TbTotal"/>
                    </pu:FormGroup>
                    <pu:FormGroup Header="{DynamicResource Ts.Pass}">
                    <pu:FormGroup Header="{DynamicResource Ts.Pass}" GroupName="Number">
                        <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
                 x:Name="TbPass"/>
                    </pu:FormGroup>
                    <pu:FormGroup Header="{DynamicResource Ts.Fail}">
                    <pu:FormGroup Header="{DynamicResource Ts.Fail}" GroupName="Number">
                        <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
                 x:Name="TbFail"/>
                    </pu:FormGroup>
                    <pu:FormGroup Header="{DynamicResource Ts.PassRate}">
                    <pu:FormGroup Header="{DynamicResource Ts.PassRate}" GroupName="Number">
                        <TextBox Style="{StaticResource EditorTextBoxStyle}" IsReadOnly="True"
                 x:Name="TbPassRate"/>
                    </pu:FormGroup>
WPFProject/3rds/3rds Libs.txt
New file
@@ -0,0 +1 @@

WPFProject/App.config
@@ -5,7 +5,7 @@
    </startup>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="Libs;ThirdParty;Plugin;" />
            <probing privatePath="Libs;ThirdParty;Plugin;3rds;" />
            <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" />
WPFProject/App.xaml.cs
@@ -3,9 +3,7 @@
using log4net;
using Panuon.WPF.UI;
using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;
using WPFProject.Utils;
namespace WPFProject
@@ -26,12 +24,9 @@
        {
            var ex = e.ExceptionObject as Exception;
            log.Error("UnhandledException.", ex);
            Dispatcher.Invoke(() =>
            {
                MsgBoxHelper.ErrorMessage(Current.MainWindow, $"发生未知异常!程序即将关闭\r\n{ex?.Message}",
                    "错误", MessageBoxButton.OK,
            MsgBoxHelper.ErrorMessage(Current.MainWindow, this.lang("App.AppUnhandledException",ex.Message),
                    this.lang("App.Error"), MessageBoxButton.OK,
                    MessageBoxIcon.Error, DefaultButton.YesOK, 5);
            });
        }
        private void Application_Startup(object sender, StartupEventArgs e)
@@ -41,17 +36,6 @@
            LoadingWindow window = new LoadingWindow();
            //Login window = new Login();
            window.Show();
        }
        private void LoadLang()
        {
            string path = "Lang/zh-CN/app.xaml";
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                var dict = (ResourceDictionary)XamlReader.Load(fs);
                Application.Current.Resources.MergedDictionaries.Add(dict);
            }
        }
    }
}
WPFProject/Config/Database/database.db
Binary files differ
WPFProject/Config/Put Your Config Here.txt
New file
@@ -0,0 +1,6 @@
IF "$(ConfigurationName)"=="Release" robocopy $(TargetDir) $(TargetDir)..\ $(TargetFileName) $(TargetFileName).config log4net.config /MOV /E /S /IS /IT
robocopy "$(TargetDir)Plugin" "$(TargetDir)..\Plugin" /MOVE /E /IS /IT
robocopy "$(TargetDir)Icon" "$(TargetDir)..\Icon" /MOVE /E /IS /IT
robocopy "$(TargetDir)Lang" "$(TargetDir)..\Lang" /MOVE /E /IS /IT
robocopy "$(TargetDir)Config" "$(TargetDir)..\Config" /MOVE /E /IS /IT
robocopy "$(TargetDir)Libs" "$(TargetDir)..\Libs" /MOVE /E /IS /IT
WPFProject/Config/log4net.config
WPFProject/Icon/b1.jpg
WPFProject/Icon/b2.jpg
WPFProject/Icon/b3.jpg
WPFProject/Icon/b4.jpg
WPFProject/Icon/pic1.png
WPFProject/Icon/t1.png
WPFProject/Icon/t2.png
WPFProject/Icon/t3.png
WPFProject/Icon/t4.png
WPFProject/JingCeLogo2.ico
WPFProject/Lang/en-US/AlarmInfoManage.json
New file
@@ -0,0 +1,15 @@
{
  "Alm.Title": "Alarm Info",
  "Alm.Source": "Source",
  "Alm.Code": "Code",
  "Alm.Info": "Info",
  "Alm.Time": "Time",
  "Alm.OnlySupportXlsm": "Only .xlsm can be supported",
  "Alm.RowImportFailed": "Import failed in row: {0}",
  "Alm.DbAddress": "DB Address",
  "Alm.StartAddress": "Start Address",
  "Alm.DbLength": "Length",
  "Alm.DbBlockAlarm": "DB Block Alarm",
  "Alm.TagAlarm": "Tag Alarm"
}
WPFProject/Lang/en-US/DataViewer.json
New file
@@ -0,0 +1,20 @@
{
  "Dv.Title": "Data viewer",
  "Dv.Datasource.Name": "Name",
  "Dv.Datasource.File": "Source",
  "Dv.Datasource.Table": "Table",
  "Dv.Datasource.Fields": "Fields",
  "Dv.Datasource.FieldName": "Field",
  "Dv.Datasource.Desc": "Description",
  "Dv.Datasource.TimeField": "Time Field",
  "Dv.Advanced": "Advanced",
  "Dv.SelectItem": "Datasource",
  "Dv.Field": "Field",
  "Dv.Condition": "Condition",
  "Dv.Value": "Value",
  "Dv.SelectDatasourceFirst": "Please select datasource",
  "Dv.AddDatasource": "New Datasource",
  "Dv.EditDatasource": "Edit Datasource",
  "Dv.QueryCantBeEmpty": "Please edit your select condition",
  "Dv.SelectDbFile": "Select .db file"
}
WPFProject/Lang/en-US/IOMonitor.json
New file
@@ -0,0 +1,27 @@
{
  "DIO.Title": "DIO",
  "DIO.Code": "Code",
  "DIO.Name": "Name",
  "DIO.Type": "Type",
  "DIO.di.Name": "DI Name",
  "DIO.di.Value": "DI Value",
  "DIO.di.Query": "DI Query",
  "DIO.di.Reset": "DI Reset",
  "DIO.di.Code": "DI Code",
  "DIO.di.Group": "DI Group",
  "DIO.do.Name": "DO Name",
  "DIO.do.Value": "DO Code",
  "DIO.do.Query": "DO Query",
  "DIO.do.Reset": "DO Reset",
  "DIO.do.Code": "DO Code",
  "DIO.do.Group": "DO Group",
  "DIO.ActivateFailed": "Activate failed",
  "DIO.ITag": "ITag",
  "DIO.OTag": "OTag"
}
WPFProject/Lang/en-US/ParamManage.json
New file
@@ -0,0 +1,18 @@
{
  "Pm.Product.Title": "Products",
  "Pm.Product.Add": "New product",
  "Pm.Product.Edit": "Edit product",
  "Pm.Product.Name": "Product name",
  "Pm.Product.IsSample": "Is sample",
  "Pm.Product.Extend": "Extend",
  "Pm.Parameter.Title": "Product parameters",
  "Pm.Parameter.Name": "Name",
  "Pm.Parameter.Value": "Value",
  "Pm.Parameter.Unit": "Unit",
  "Pm.Parameter.Desc": "Description",
  "Pm.Parameter.Group": "Group",
  "Pm.Parameter.Add": "New parameter",
  "Pm.Parameter.Edit": "Edit parameter",
  "Pm.PleaseSelectProduct": "Please select a product"
}
WPFProject/Lang/en-US/TestExecution.json
New file
@@ -0,0 +1,22 @@
{
  "Ts.BtnStartSeq": "Start sequence",
  "Ts.BtnStopSeq": "Stop sequence",
  "Ts.BtnClearNum": "Clear number",
  "Ts.BtnIsSample": "Is sample",
  "Ts.BtnNotSample": "Not sample",
  "Ts.SelectProductModel": "Select product model",
  "Ts.Total": "Total",
  "Ts.Pass": "Pass",
  "Ts.Fail": "Fail",
  "Ts.PassRate": "Pass rate",
  "Ts.SampleTestFail": "Sample test failed",
  "Ts.LoadSequenceFail": "Load sequence failed",
  "Ts.StartSequenceFail": "Start sequence failed",
  "Ts.StopSequenceFail": "Stop sequence failed",
  "Ts.MakeSureClearNum": "Are you sure you want to clear the number?",
  "Ts.SequenceIsStarting": "Sequence is starting...",
  "Ts.CurrentSnr": "Current serial",
  "Ts.TimeSpan": "Elapsed time"
}
WPFProject/Lang/en-US/TestResult.json
New file
@@ -0,0 +1,29 @@
{
  "Tr.DetailChart": "Detail chart",
  "Tr.TcpServer.SettingFailed": "Server setup failed",
  "Tr.TcpServer.StartFailed": "Server start failed",
  "Tr.TcpServer.Running": "Server is running",
  "Tr.Temperature": "Temperature",
  "Tr.Status": "Status",
  "Tr.Count": "Count",
  "Tr.StartTime": "Start time",
  "Tr.ElapsedTime": "Elapsed time",
  "Tr.EstimatedEndTime": "Estimated end time",
  "Tr.PleaseScanSnr": "Please scan serials",
  "Tr.PositionSnr": "Position SNR",
  "Tr.ProductSnr": "Product SNR",
  "Tr.ContinueScan": "Continue",
  "Tr.FinishScan": "Complete",
  "Tr.InitGunFailed": "Init scanner failed",
  "Tr.GetGunData": "Receive scanner failed",
  "Tr.PleaseInputSnrs": "Please scan serials",
  "Tr.ProductInfo": "Product info",
  "Tr.MES_CLOSE": "MES is closed",
  "Tr.MES_OPEN": "MES is open",
  "Tr.Zone1Scan": "Scan to zone1",
  "Tr.Zone2Scan": "Scan to zone2"
}
WPFProject/Lang/en-US/app.json
@@ -1,70 +1,139 @@
{
  "App.Login": "Login",
  "App.RememberMe": "RememberMe",
  "App.RememberMe": "Remember me",
  "App.Username": "Username",
  "App.Password": "Password",
  "App.UsernameHolder": "Pleas Intput Username",
  "App.PasswordHolder": "Pleas Intput Password",
  "App.PleaseWait": "Please Wait...",
  "App.UsernameHolder": "Please input username",
  "App.PasswordHolder": "Please input password",
  "App.PleaseWait": "Please wait...",
  "App.LoginFailed": "Login Failed",
  "App.ErrorUsernameOrPassword": "Username or Password is Error",
  "App.ErrorUsernameOrPassword": "Username or password is incorrect",
  "App.IconMustInFolder": "Please put your icon in [Icon] Folder",
  "App.UsercontrolIsLoading": "Program is loading,please wait...",
  "App.UsercontrolIsLoading": "Page is loading, please wait...",
  "App.AppUnhandledException": "Unhandled Exception!Application will close\r\n{0}",
  "App.UnhandledException": "Unhandle Exception",
  "App.Add": "Add",
  "App.AddSuccess": "Add Success",
  "App.AddFailed": "Add Failed",
  "App.Start": "Start",
  "App.NotStarted": "Not Started",
  "App.Stop": "Stop",
  "App.Info": "Info",
  "App.Warn": "Warning",
  "App.Error": "Error",
  "App.Success": "Success",
  "App.LoadFailed": "Load failed",
  "App.Add": "New",
  "App.AddSuccess": "Add success",
  "App.AddFailed": "Add failed",
  "App.Edit": "Edit",
  "App.EditSuccess": "Edit Success",
  "App.EditFailed": "Edit Failed",
  "App.EditSuccess": "Edit success",
  "App.EditFailed": "Edit failed",
  "App.Delete": "Delete",
  "App.DeleteSuccess": "Delete Success",
  "App.DeleteFailed": "Delete Failed",
  "App.DeleteSuccess": "Delete success",
  "App.DeleteFailed": "Delete failed",
  "App.Query": "Query",
  "App.QuerySuccess": "Query success",
  "App.QueryFailed": "Query failed",
  "App.Search": "Search",
  "App.Refresh": "Refresh",
  "App.RefreshSuccess": "Refresh success",
  "App.RefreshFailed": "Refresh failed",
  "App.SelectAll": "Select all",
  "App.AddTo": "Add",
  "App.Reset": "Reset",
  "App.Export": "Export",
  "App.Import": "Import",
  "App.ImportSuccess": "Import success",
  "App.ImportFailed": "Import failed",
  "App.Save": "Save",
  "App.SaveSuccess": "Save Success",
  "App.SaveFailed": "Save Failed",
  "App.SaveSuccess": "Save success",
  "App.SaveFailed": "Save failed",
  "App.Setting": "Setting",
  "App.Cancel": "Cancel",
  "App.Close": "Close",
  "App.Opt": "Opt",
  "App.StartTime": "Start Time",
  "App.EndTime": "End Time",
  "App.ParameterException": "Parameter Except",
  "App.CantBeEmpty": "{0} can't be empty",
  "App.MustBeUnique": "{0} must be unique",
  "App.Granted": "Granted",
  "App.SelectFile": "Select file",
  "App.SelectPic": "Select picture",
  "App.Msg.PluginMustInPluginFolder": "Please put your plugin in [Plugin] Folder",
  "Test.Name": "Name",
  "Test.Unit": "Unit",
  "Test.Value": "Value",
  "Test.LimitDown": "Limit Down",
  "Test.LimitUp": "Limit Up",
  "Test.LimitDown": "Limit down",
  "Test.LimitUp": "Limit up",
  "Test.Result": "Result",
  "Test.Range": "Range",
  "Test.Condition": "Condition",
  "Test.UpdateTime": "Update Time",
  "Ts.UserControlLoadFailed": "TS init failed",
  "Ts.InitTestStandEngineFail": "TS engine init failed",
  "Ts.StartTestSequenceFailed": "Start sequence failed",
  "Ts.StopTestSequenceFailed": "Stop sequence failed",
  "Ts.ReleaseSequenceFileFail": "Release sequence failed",
  "App.Continue": "Continue",
  "App.IsLoadingMenu": "{0} is loading ...",
  "App.MenuLoadSuccess": "{0} is loaded!",
  "App.MenuLoadFailed": "{0} load failed: {1} {2}",
  "App.MenuCount": "There are {0} menus is loading...",
  "HMI.NoDeleteData": "Please select items you want to delete",
  "HMI.MakeSureDeleteSingle": "Are you sure you want to delete [{0}]? It can't be revoked!",
  "HMI.MakeSureDeletes": "Are you sure you want to delete [{0}] items? It can't be revoked!",
  "HMI.MakeSureDeleteThis": "Are you sure you want to delete this? It can't be revoked!",
  "HMI.Menu": "Menu",
  "HMI.Menu.Add": "Add Menu",
  "HMI.Menu.Edit": "Edit Menu",
  "HMI.Menu.Title": "Menu List",
  "HMI.Menu.TreeTitle": "Menu Strach",
  "HMI.Menu.Code": "Menu Code",
  "HMI.Menu.Name": "Menu Name",
  "HMI.Menu.Add": "New menu",
  "HMI.Menu.Edit": "Edit menu",
  "HMI.Menu.Title": "Menu list",
  "HMI.Menu.TreeTitle": "Menu structure",
  "HMI.Menu.Code": "Code",
  "HMI.Menu.Name": "Name",
  "HMI.Menu.Level": "Level",
  "HMI.Menu.Icon": "Icon",
  "HMI.Menu.Type": "Type",
  "HMI.Menu.ParentCode": "Parent Code",
  "HMI.Menu.ParentName": "Parent Name",
  "HMI.Menu.DllPath": "Dll Path",
  "HMI.Menu.ClassName": "Class Name",
  "HMI.Menu.ParentCode": "Previous menu code",
  "HMI.Menu.ParentName": "Previous menu",
  "HMI.Menu.DllPath": "Dll path",
  "HMI.Menu.ClassName": "Class name",
  "HMI.Menu.NoDeleteData": "请选择要删除的菜单",
  "HMI.Menu.MakeSureDeleteSingle": "确定删除菜单[{0}]吗?该操作不可逆!",
  "HMI.Menu.MakeSureDeletes": "确定删除选中的[{0}]条菜单吗?该操作不可逆!"
  "HMI.User": "User",
  "HMI.User.Title": "User list",
  "HMI.User.RealName": "Name",
  "HMI.User.Account": "Username",
  "HMI.User.Password": "Password",
  "HMI.User.Role": "User role",
  "HMI.User.Add": "New user",
  "HMI.User.Edit": "Edit user",
  "HMI.Role": "Role",
  "HMI.Role.Title": "Role list",
  "HMI.Role.Code": "Code",
  "HMI.Role.Name": "Name",
  "HMI.Role.Permission": "Permission",
  "HMI.Role.Add": "New role",
  "HMI.Role.Edit": "Edit role"
}
WPFProject/Lang/en-US/setting.json
@@ -3,7 +3,7 @@
  "Setting.Title": "Title",
  "Setting.Lang": "Language",
  "Setting.PlcIp": "PLC IP",
  "Setting.PlcEnabled": "Is Enabled",
  "Setting.BasicSetting": "Basic Setting",
  "Setting.PlcSetting": "PLC Setting"
  "Setting.PlcEnabled": "Enabled",
  "Setting.BasicSetting": "Basic setting",
  "Setting.PlcSetting": "PLC setting"
}
WPFProject/Lang/en-US/ts.json
File was deleted
WPFProject/Lang/zh-CN/AlarmInfoManage.json
New file
@@ -0,0 +1,15 @@
{
  "Alm.Title": "报警信息列表",
  "Alm.Source": "来源",
  "Alm.Code": "编号",
  "Alm.Info": "信息",
  "Alm.Time": "时间",
  "Alm.OnlySupportXlsm": "仅支持xlsm格式文件",
  "Alm.RowImportFailed": "第{0}行导入异常",
  "Alm.DbAddress": "Db地址",
  "Alm.StartAddress": "起始地址",
  "Alm.DbLength": "长度",
  "Alm.DbBlockAlarm": "DB块报警",
  "Alm.TagAlarm": "标志位报警"
}
WPFProject/Lang/zh-CN/DataViewer.json
New file
@@ -0,0 +1,20 @@
{
  "Dv.Title": "数据查询",
  "Dv.Datasource.Name": "名称",
  "Dv.Datasource.File": "源文件",
  "Dv.Datasource.Table": "表名",
  "Dv.Datasource.Fields": "字段设置",
  "Dv.Datasource.FieldName": "字段名",
  "Dv.Datasource.Desc": "描述",
  "Dv.Datasource.TimeField": "映射时间",
  "Dv.Advanced": "高级查询",
  "Dv.SelectItem": "数据源",
  "Dv.Field": "字段",
  "Dv.Condition": "条件",
  "Dv.Value": "值",
  "Dv.SelectDatasourceFirst": "请先选择数据源",
  "Dv.AddDatasource": "新增数据源",
  "Dv.EditDatasource": "编辑数据源",
  "Dv.QueryCantBeEmpty": "请先设置查询条件",
  "Dv.SelectDbFile": "选择数据库文件"
}
WPFProject/Lang/zh-CN/IOMonitor.json
New file
@@ -0,0 +1,27 @@
{
  "DIO.Title": "DIO监控",
  "DIO.Code": "编号",
  "DIO.Name": "名称",
  "DIO.Type": "类型",
  "DIO.di.Name": "DI名称",
  "DIO.di.Value": "DI值",
  "DIO.di.Query": "DI查询",
  "DIO.di.Reset": "DI重置",
  "DIO.di.Code": "DI编号",
  "DIO.di.Group": "DI分组",
  "DIO.do.Name": "DO名称",
  "DIO.do.Value": "DO值",
  "DIO.do.Query": "DO查询",
  "DIO.do.Reset": "DO重置",
  "DIO.do.Code": "DO编号",
  "DIO.do.Group": "DO分组",
  "DIO.ActivateFailed": "初始化异常",
  "DIO.ITag": "I点读取标签",
  "DIO.OTag": "O点读取标签"
}
WPFProject/Lang/zh-CN/ParamManage.json
New file
@@ -0,0 +1,21 @@
{
  "Pm.Product.Title": "产品列表",
  "Pm.Product.Add": "新增产品",
  "Pm.Product.Edit": "编辑产品",
  "Pm.Product.Name": "产品名称",
  "Pm.Product.IsSample": "是否样件",
  "Pm.Product.Extend": "继承",
  "Pm.Parameter.Title": "产品参数",
  "Pm.Parameter.Name": "名称",
  "Pm.Parameter.Value": "值",
  "Pm.Parameter.Unit": "单位",
  "Pm.Parameter.Desc": "描述",
  "Pm.Parameter.Group": "分组",
  "Pm.Parameter.Add": "新增参数",
  "Pm.Parameter.Edit": "编辑参数",
  "Pm.PleaseSelectProduct": "请先选择一项产品",
  "Pm.Setting.Title":"参数管理"
}
WPFProject/Lang/zh-CN/TestExecution.json
File was renamed from WPFProject/Lang/zh-CN/ts.json
@@ -10,14 +10,12 @@
  "Ts.Pass": "良品数",
  "Ts.Fail": "不良品数",
  "Ts.PassRate": "良品率",
  "Ts.UserControlLoadFailed": "TS初始化失败",
  "Ts.InitTestStandEngineFail": "初始化TS引擎失败",
  "Ts.SampleTestFail": "样件测试启动失败",
  "Ts.LoadSequenceFail": "加载测试序列失败",
  "Ts.StartSequenceFail": "启动测试序列失败",
  "Ts.StopSequenceFail": "停止测试序列失败",
  "Ts.MakeSureClearNum": "确定要清空计数吗?",
  "Ts.ReleaseSequenceFileFail": "释放序列文件失败",
  "Ts.SequenceIsStarting": "正在启动测试序列...",
  "Ts.CurrentSnr": "当前序列号",
  "Ts.TimeSpan": "测试耗时"
WPFProject/Lang/zh-CN/TestResult.json
New file
@@ -0,0 +1,29 @@
{
  "Tr.DetailChart": "详细曲线",
  "Tr.TcpServer.SettingFailed": "服务设置异常",
  "Tr.TcpServer.StartFailed": "服务启动异常",
  "Tr.TcpServer.Running": "服务运行中",
  "Tr.Temperature": "温度",
  "Tr.Status": "状态",
  "Tr.Count": "老化数量",
  "Tr.StartTime": "开始时间",
  "Tr.ElapsedTime": "已老化时间",
  "Tr.EstimatedEndTime": "预计结束时间",
  "Tr.PleaseScanSnr": "请依次扫取下列条码",
  "Tr.PositionSnr": "储位条码",
  "Tr.ProductSnr": "产品条码",
  "Tr.ContinueScan": "继续扫描",
  "Tr.FinishScan": "完成扫描",
  "Tr.InitGunFailed": "初始化扫码枪失败",
  "Tr.GetGunData": "获取扫码枪数据失败",
  "Tr.PleaseInputSnrs": "请输入储位条码和产品条码",
  "Tr.ProductInfo": "产品信息",
  "Tr.MES_CLOSE": "MES关",
  "Tr.MES_OPEN": "MES开",
  "Tr.Zone1Scan": "一区扫码",
  "Tr.Zone2Scan": "二区扫码"
}
WPFProject/Lang/zh-CN/app.json
@@ -11,6 +11,20 @@
  "App.IconMustInFolder": "请将图标移动至程序Icon目录下",
  "App.UsercontrolIsLoading": "页面加载中,请稍后...",
  "App.AppUnhandledException": "发生未知异常!程序即将关闭\r\n{0}",
  "App.UnhandledException": "未知异常",
  "App.Start": "启动",
  "App.NotStarted": "未启动",
  "App.Stop": "停止",
  "App.Info": "提示",
  "App.Warn": "警告",
  "App.Error": "错误",
  "App.Success": "成功",
  "App.LoadFailed": "加载失败",
  "App.Add": "新增",
  "App.AddSuccess": "新增成功",
@@ -25,15 +39,23 @@
  "App.DeleteFailed": "删除失败",
  "App.Query": "查询",
  "App.QuerySuccess": "查询成功",
  "App.QueryFailed": "查询失败",
  "App.Search": "搜索",
  "App.Refresh": "刷新",
  "App.RefreshSuccess": "刷新成功",
  "App.RefreshFailed": "刷新失败",
  "App.SelectAll": "全选",
  "App.AddTo": "添加",
  "App.Reset": "重置",
  "App.Export": "导出",
  "App.Import": "导入",
  "App.ImportSuccess": "导入成功",
  "App.ImportFailed": "导入失败",
  "App.Save": "保存",
  "App.SaveSuccess": "保存成功",
@@ -44,6 +66,10 @@
  "App.Close": "关闭",
  "App.Opt": "操作",
  "App.StartTime": "开始时间",
  "App.EndTime": "结束时间",
  "App.ParameterException": "参数异常",
  "App.CantBeEmpty": "{0}不能为空",
  "App.MustBeUnique": "{0}不能重复",
  "App.Granted": "授予",
@@ -61,17 +87,23 @@
  "Test.Condition": "测试条件",
  "Test.UpdateTime": "更新时间",
  "Ts.UserControlLoadFailed": "TS初始化失败",
  "Ts.InitTestStandEngineFail": "初始化TS引擎失败",
  "Ts.StartTestSequenceFailed": "启动测试序列失败",
  "Ts.StopTestSequenceFailed": "停止测试序列失败",
  "Ts.ReleaseSequenceFileFail": "释放序列文件失败",
  "App.Continue": "继续",
  "App.IsLoadingMenu": "正在加载{0}...",
  "App.MenuLoadSuccess": "{0}加载完成!",
  "App.MenuLoadFailed": "{0}加载失败: {1} {2}",
  "App.MenuCount": "共有{0}条菜单待加载...",
  "Tr.PleaseScanSnr": "请依次扫取下列条码",
  "Tr.PositionSnr": "储位条码",
  "Tr.ProductSnr": "产品条码",
  "Tr.ContinueScan": "继续扫描",
  "Tr.FinishScan": "完成扫描",
  "HMI.NoDeleteData": "请选择要删除的数据",
  "HMI.MakeSureDeleteSingle": "确定删除数据[{0}]吗?该操作不可逆!",
  "HMI.MakeSureDeletes": "确定删除选中的[{0}]条数据吗?该操作不可逆!",
  "HMI.MakeSureDeleteThis": "确定要删除该项吗?该操作不可逆!",
  "HMI.Menu": "菜单",
  "HMI.Menu.Add": "新增菜单",
@@ -88,10 +120,6 @@
  "HMI.Menu.DllPath": "Dll路径",
  "HMI.Menu.ClassName": "类名",
  "HMI.Menu.NoDeleteData": "请选择要删除的菜单",
  "HMI.Menu.MakeSureDeleteSingle": "确定删除菜单[{0}]吗?该操作不可逆!",
  "HMI.Menu.MakeSureDeletes": "确定删除选中的[{0}]条菜单吗?该操作不可逆!",
  "HMI.User": "用户",
  "HMI.User.Title": "用户列表",
  "HMI.User.RealName": "用户名称",
@@ -107,5 +135,8 @@
  "HMI.Role.Name": "角色名称",
  "HMI.Role.Permission": "权限",
  "HMI.Role.Add": "新增角色",
  "HMI.Role.Edit": "编辑角色"
  "HMI.Role.Edit": "编辑角色",
  "HMI.Line": "产线",
  "HMI.Station": "工站",
}
WPFProject/Libs/SQLite.Interop.dll
Binary files differ
WPFProject/LoadingWindow.xaml
@@ -6,6 +6,7 @@
        xmlns:local="clr-namespace:WPFProject"
        xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
        xmlns:purs="clr-namespace:Panuon.WPF.UI.Resources;assembly=Panuon.WPF.UI"
        xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
        mc:Ignorable="d"
        Height="420"
        Width="600"
@@ -15,16 +16,109 @@
        ContentRendered="WindowX_ContentRendered"
            WindowStartupLocation="CenterScreen"
        Loaded="Window_Loaded">
    <Window.Resources>
        <!--<Style x:Key="CarouselStyle"
        TargetType="pu:Carousel">
            <Setter Property="Animation"
             Value="Flow,Fade" />
            <Setter Property="AnimationEasing"
             Value="CubicOut" />
            <Setter Property="IndicatorVisibility"
             Value="Visible" />
            <Setter Property="IndicatorPaginationStyle">
                <Setter.Value>
                    <Style TargetType="pu:Pagination"
                    BasedOn="{StaticResource {x:Static pu:Carousel.IndicatorPaginationStyleKey}}">
                        <Setter Property="ItemsWidth"
                         Value="NaN" />
                        <Setter Property="ItemsHeight"
                         Value="NaN" />
                        <Setter Property="ItemsBackground"
                         Value="Transparent" />
                        <Setter Property="ItemsForeground"
                         Value="#55000000" />
                        <Setter Property="ItemsSelectedBackground"
                         Value="{x:Null}" />
                        <Setter Property="ItemsSelectedForeground"
                         Value="#C62F2F" />
                        <Setter Property="ItemContainerStyle">
                            <Setter.Value>
                                <Style TargetType="pu:PaginationItem">
                                    <Setter Property="Cursor"
                                     Value="Hand" />
                                    <Setter Property="ContentTemplate">
                                        <Setter.Value>
                                            <DataTemplate>
                                                <TextBlock Text="&#xe954;"
                                                    FontFamily="{StaticResource PanuonIconFont}"
                                                    FontSize="16" />
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Setter.Value>
            </Setter>
        </Style>-->
    </Window.Resources>
    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <!--TextBox x:Name="Console" IsReadOnly="True" Text="{Binding ConsoleText}"/>-->
        <RichTextBox x:Name="Console" IsReadOnly="True" Padding="0" VerticalScrollBarVisibility="Auto"
        <Image Height="25"
       Stretch="Uniform"
   HorizontalAlignment="Left"
   Source="/Resources/JingCeLogo.png"
               Margin="0,0,0,10"
   RenderOptions.BitmapScalingMode="HighQuality" />
        <!--<pu:Carousel
             AutoPlayDuration="0:0:2"
             Height="300"
             TextBlock.FontSize="40"
             TextBlock.TextAlignment="Center">
            <Border Background="#FAFAFA">
                <TextBlock Text="Page 1"
                   VerticalAlignment="Center" />
            </Border>
            <Border Background="#FAFAFA">
                <TextBlock Text="Page 2"
                   VerticalAlignment="Center" />
            </Border>
            <Border Background="#FAFAFA">
                <TextBlock Text="Page 3"
                   VerticalAlignment="Center" />
            </Border>
            <Border Background="#FAFAFA">
                <TextBlock Text="Page 4"
                   VerticalAlignment="Center" />
            </Border>
            <Border Background="#FAFAFA">
                <TextBlock Text="Page 5"
                   VerticalAlignment="Center" />
            </Border>
        </pu:Carousel>-->
        <ProgressBar Grid.Row="1" x:Name="processBar" Minimum="0" Maximum="100" Height="20" Margin="0,0,0,10"
                     Visibility="Visible"/>
        <RichTextBox Grid.Row="2" x:Name="Console" IsReadOnly="True" Padding="0" VerticalScrollBarVisibility="Auto"
                     VerticalContentAlignment="Top"
                     HorizontalContentAlignment="Left"
                     />
        <Button Grid.Row="1" Style="{StaticResource PrimaryButton}" Content="下一步" Click="Button_Click"/>
                     Margin="0,0,0,10"
                     Visibility="Visible"
                     HorizontalContentAlignment="Left"/>
        <Button Grid.Row="3" Style="{StaticResource PrimaryButton}"
                x:Name="BtnNext" Visibility="Collapsed"
                Content="{DynamicResource App.Continue}" Click="Button_Click"/>
    </Grid>
</pu:WindowX>
WPFProject/LoadingWindow.xaml.cs
@@ -1,9 +1,11 @@
using HMI.Base;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace WPFProject
{
@@ -13,12 +15,35 @@
    public partial class LoadingWindow : WindowX
    {
        private string consoleText = "";
        private string message = "";
        public string ConsoleText
        public string Message
        {
            get { return consoleText; }
            set { Set(ref consoleText, value); }
            get { return message; }
            set { Set(ref message, value); }
        }
        private bool HasErr = false;
        private bool showConsole = false;
        public bool ShowConsole
        {
            get => showConsole;
            set
            {
                Set(ref showConsole, value);
                NotifyOfPropertyChange("ConsoleVisiable");
                NotifyOfPropertyChange("BarVisiable");
            }
        }
        public Visibility ConsoleVisiable {
            get => showConsole ? Visibility.Visible : Visibility.Collapsed;
        }
        public Visibility BarVisiable
        {
            get => showConsole ? Visibility.Collapsed : Visibility.Visible;
        }
        public LoadingWindow()
@@ -29,11 +54,30 @@
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
        }
        private void Loader_LoadMessageAppend(object sender, string e)
        private void Loader_LoadMessageAppend(object sender, LoadMsg msg)
        {
            Add(e);
            switch (msg.Type)
            {
                case LoadMsgType.INIT:
                    total = msg.NumData;
                    Add(msg.Message, null);
                    break;
                case LoadMsgType.LOADING:
                    HasErr = msg.Result == false;
                    if (msg.Result != null)
                    {
                        processBar.Value = ++finished / total * 100;
                    }
                    Add(msg.Message, msg.Result);
                    break;
                case LoadMsgType.FINISHED:
                    LoadFinished();
                    break;
                default:
                    break;
            }
        }
@@ -44,11 +88,13 @@
            this.Close();
        }
        private double total;
        private double finished;
        private void WindowX_ContentRendered(object sender, System.EventArgs e)
        {
            PluginLoader loader = PluginLoader.GetLoader();
            loader.LoadMessageAppend += Loader_LoadMessageAppend;
            loader.Loaded += Loader_Loaded;
            Task.Run(() =>
            {
                loader.LoadMenuAndPlugin(Dispatcher);
@@ -56,28 +102,38 @@
            });
        }
        private void Loader_Loaded(object sender, EventArgs e)
        private void LoadFinished()
        {
            Dispatcher.Invoke(() =>
            if (!HasErr)
            {
                Button_Click(null, null);
            });
            }
            else
            {
                WindowXCaption.SetButtons(this, CaptionButtons.Close);
                ShowConsole = true;
                BtnNext.Visibility = Visibility.Visible;
                MsgBoxHelper.Error(this, "加载出错,请确认");
            }
        }
        public void Add(string text)
        public void Add(string text, bool? result)
        {
            string t = string.Format("{0:G}", DateTime.Now);
            Message = text;
            string time = string.Format("{0:G}", DateTime.Now);
            Run run = new Run();
            run.Text = t + " 信息:" + text;
            //run.Foreground = new Brush();
            string type = result != false ? "Info" : "Warn";
            run.Text = $"{time} {type} {text}";
            run.Foreground = result == null ? Brushes.Black : (result == true ? Brushes.Green : Brushes.Red);
            Paragraph paragraph = new Paragraph(run) {
                LineHeight =1
            Paragraph paragraph = new Paragraph(run)
            {
                LineHeight = 1
            };
            //rtxtLog.Document.Blocks.InsertAfter(); ;
            //插入到最前面
            Console.Document.Blocks.InsertAfter(Console.Document.Blocks.LastBlock, paragraph);
            //也可以插入到最后面
            Console.Document.Blocks.InsertAfter(Console.Document.Blocks.LastBlock, paragraph);
            //插入到最前面
            //rtxtLog.Document.Blocks.Add(paragraph);
            // 滚动至最后行
WPFProject/Login.xaml
@@ -8,7 +8,7 @@
            xmlns:purs="clr-namespace:Panuon.WPF.UI.Resources;assembly=Panuon.WPF.UI"
            xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
            mc:Ignorable="d"
            Title="{Binding Converter={StaticResource lc},ConverterParameter='App.Login'}"
            Title="{DynamicResource App.Login}"
            pu:WindowXCaption.Foreground="#FFF"
            Height="420"
            Width="380"
@@ -49,8 +49,7 @@
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Converter={StaticResource lc},
                                        ConverterParameter='App.PleaseWait'}" />
                                    <TextBlock Text="{DynamicResource App.PleaseWait}" />
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
@@ -111,28 +110,28 @@
                <TextBox x:Name="TbAccount" Style="{StaticResource EditorTextBoxStyle}"
         Background="White"
         pu:TextBoxHelper.InputLimit="UpperCaseLetters,LowerCaseLetters,Digit"
         pu:TextBoxHelper.Watermark="{Binding Converter={StaticResource lc},ConverterParameter='App.Username'}"/>
         pu:TextBoxHelper.Watermark="{DynamicResource App.Username}"/>
            </pu:FormGroup>
            <pu:FormGroup x:Name="FrmPassword" HeaderPadding="0,0,0,10"
          dp:FormGroupHelper.IsRequired="True"
          MinMessageHeight="22">
                <PasswordBox x:Name="PwdPassword" VerticalContentAlignment="Center" 
                             Style="{StaticResource SignInPasswordBoxStyle}" 
                             pu:PasswordBoxHelper.Watermark="{Binding Converter={StaticResource lc},ConverterParameter='App.Password'}"/>
                             pu:PasswordBoxHelper.Watermark="{DynamicResource App.Password}"/>
            </pu:FormGroup>
        </StackPanel>
        <pu:Switch Grid.Row="3"
               HorizontalAlignment="Right"
               Margin="0,25,0,0"
                   Cursor="Hand"
               Foreground="{StaticResource PrimaryColorContract}"
               Style="{StaticResource RememberMeSwitchStyle}"
               Content="{Binding Converter={StaticResource lc},ConverterParameter='App.RememberMe'}" />
               Content="{DynamicResource App.RememberMe}" />
        <Button Grid.Row="4"
            Margin="0,20,0,0"
            Height="40"
            Content="{Binding Converter={StaticResource lc},ConverterParameter='App.Login'}"
            Content="{DynamicResource App.Login}"
            Style="{StaticResource SignInButtonStyle}" x:Name="BtnLogin" Click="Button_Click">
        </Button>
    </Grid>
WPFProject/PanuonWindow.xaml.cs
@@ -1,14 +1,10 @@
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI.Util;
using Panuon.WPF.UI;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using WPFProject.Utils;
namespace WPFProject
{
WPFProject/Properties/AssemblyInfo.cs
@@ -55,4 +55,4 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
[assembly: XmlConfigurator(ConfigFile = "Config/log4net.config", Watch = true)]
WPFProject/Properties/app.manifest
New file
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC 清单选项
             如果想要更改 Windows 用户帐户控制级别,请使用
             以下节点之一替换 requestedExecutionLevel 节点。
        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
            指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
            如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
            元素。
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
      <applicationRequestMinimum>
        <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
        <defaultAssemblyRequest permissionSetReference="Custom" />
      </applicationRequestMinimum>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
           Windows 版本的列表。取消评论适当的元素,
           Windows 将自动选择最兼容的环境。 -->
      <!-- Windows Vista -->
      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
      <!-- Windows 7 -->
      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
      <!-- Windows 8 -->
      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
      <!-- Windows 8.1 -->
      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
      <!-- Windows 10 -->
      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
    </application>
  </compatibility>
  <!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
       自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
       选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
       在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
       将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
  <!--
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
      <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
  </application>
  -->
  <!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
  <!--
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>
  -->
</assembly>
WPFProject/TextFile1.txt
New file
@@ -0,0 +1,13 @@
move /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
move /y "$(TargeDir)HMI.Base.dll" $(TargeDir)Libs\HMI.Base.dll"
move /y "$(TargeDir)HMI.UI.dll" $(TargeDir)Libs\HMI.UI.dll"
move /y "$(TargeDir)HMI.AlarmInfoManage.dll" $(TargeDir)Plugin\HMI.AlarmInfoManage.dll"
move /y "$(TargeDir)HMI.DataViewer.dll" $(TargeDir)Plugin\HMI.DataViewer.dll"
move /y "$(TargeDir)HMI.IOMonitor.dll" $(TargeDir)Plugin\HMI.IOMonitor.dll"
move /y "$(TargeDir)HMI.LogViewer.dll" $(TargeDir)Plugin\HMI.LogViewer.dll"
move /y "$(TargeDir)HMI.MenuManage.dll" $(TargeDir)Plugin\HMI.MenuManage.dll"
move /y "$(TargeDir)HMI.ParameterManage.dll" $(TargeDir)Plugin\HMI.ParameterManage.dll"
move /y "$(TargeDir)HMI.SettingControl.dll" $(TargeDir)Plugin\HMI.SettingControl.dll"
move /y "$(TargeDir)Plugin.TestResult.dll" $(TargeDir)Plugin\Plugin.TestResult.dll"
move /y "$(TargeDir)Plugin.TsExecution.dll" $(TargeDir)Plugin\Plugin.TsExecution.dll"
WPFProject/WPFProject.csproj
@@ -7,7 +7,7 @@
    <ProjectGuid>{D47D2314-5DD5-4899-ADF9-15ED057289D3}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <RootNamespace>WPFProject</RootNamespace>
    <AssemblyName>WPFProject</AssemblyName>
    <AssemblyName>TestPlatform</AssemblyName>
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
@@ -15,6 +15,24 @@
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
    <LangVersion>latest</LangVersion>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <PublishUrl>C:\Output\</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <ApplicationRevision>1</ApplicationRevision>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
    <UseApplicationTrust>false</UseApplicationTrust>
    <PublishWizardCompleted>true</PublishWizardCompleted>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
@@ -49,11 +67,35 @@
    <OutputPath>bin\x64\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
    <DebugType>pdbonly</DebugType>
    <DebugType>none</DebugType>
    <PlatformTarget>x64</PlatformTarget>
    <LangVersion>latest</LangVersion>
    <ErrorReport>prompt</ErrorReport>
    <Prefer32Bit>true</Prefer32Bit>
    <WarningLevel>4</WarningLevel>
    <DocumentationFile>
    </DocumentationFile>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>JingCeLogo2.ico</ApplicationIcon>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestCertificateThumbprint>EEB12C457268F9D6367680E983B284A2555FF73A</ManifestCertificateThumbprint>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestKeyFile>WPFProject_TemporaryKey.pfx</ManifestKeyFile>
  </PropertyGroup>
  <PropertyGroup>
    <GenerateManifests>false</GenerateManifests>
  </PropertyGroup>
  <PropertyGroup>
    <SignManifests>true</SignManifests>
  </PropertyGroup>
  <PropertyGroup>
    <TargetZone>LocalIntranet</TargetZone>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationManifest>Properties\app.manifest</ApplicationManifest>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="AIStudio.Wpf.Controls, Version=1.2.2.0, Culture=neutral, processorArchitecture=MSIL">
@@ -330,21 +372,36 @@
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <Content Include="3rds\3rds Libs.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Config\Put Your Config Here.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="x64\SQLite.Interop.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Resource Include="Icon\b1.jpg" />
    <Resource Include="Icon\b2.jpg" />
    <Resource Include="Icon\b3.jpg" />
    <Resource Include="Icon\b4.jpg" />
    <Content Include="Icon\JingCeLogo.png">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Icon\JingCeLogo2.png">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Resource Include="TextFile1.txt" />
    <Resource Include="JingCeLogo2.ico" />
    <Resource Include="Icon\t1.png" />
    <Resource Include="Icon\t2.png" />
    <Resource Include="Icon\t3.png" />
    <Resource Include="Icon\t4.png" />
    <Content Include="Plugin\Here put your plugins.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Resource Include="Resources\Background.png">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Resource>
    <Resource Include="Resources\JingCeLogo.png">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Resource>
    <Resource Include="Resources\Background.png" />
    <Resource Include="Resources\JingCeLogo.png" />
    <EmbeddedResource Include="Forms\Form1.resx">
      <DependentUpon>Form1.cs</DependentUpon>
    </EmbeddedResource>
@@ -352,31 +409,65 @@
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <Content Include="Libs\SQLite.Interop.dll">
    <Content Include="Libs\x64\SQLite.Interop.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="log4net.config">
    <Content Include="Config\log4net.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\app.json">
    <Content Include="Lang\zh-CN\App.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\zh-CN\app.json">
    <Content Include="Lang\zh-CN\TestExecution.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\ts.json">
    <Content Include="Lang\zh-CN\Setting.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\zh-CN\ts.json">
    <Content Include="Config\Database\database.db">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\zh-CN\DataViewer.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\zh-CN\setting.json">
    <Content Include="Lang\zh-CN\ParamManage.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\setting.json">
    <Content Include="Lang\zh-CN\IOMonitor.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\zh-CN\AlarmInfoManage.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\zh-CN\TestResult.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\AlarmInfoManage.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\App.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\DataViewer.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\IOMonitor.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\ParamManage.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\Setting.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\TestExecution.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Lang\en-US\TestResult.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <None Include="packages.config" />
    <None Include="Properties\app.manifest" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -384,9 +475,6 @@
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
  </ItemGroup>
  <ItemGroup>
    <WCFMetadata Include="Connected Services\" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\HMI.AlermInfoManage\HMI.AlarmInfoManage.csproj">
@@ -444,12 +532,51 @@
    </Content>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Config\" />
    <BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
      <Visible>False</Visible>
      <ProductName>Microsoft .NET Framework 4.7.2 %28x86 和 x64%29</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>copy /Y "$(TargetDir)HMI.MenuManage.dll" "$(TargetDir)\Plugin\HMI.MenuManage.dll"
copy /Y "$(TargetDir)HMI.MenuManage.pdb" "$(TargetDir)\Plugin\HMI.MenuManage.pdb"</PostBuildEvent>
    <PostBuildEvent>move /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
move /y "$(TargeDir)HMI.Base.dll" $(TargeDir)Libs\HMI.Base.dll"
move /y "$(TargeDir)HMI.UI.dll" $(TargeDir)Libs\HMI.UI.dll"
move /y "$(TargeDir)HMI.AlarmInfoManage.dll" $(TargeDir)Plugin\HMI.AlarmInfoManage.dll"
move /y "$(TargeDir)HMI.DataViewer.dll" $(TargeDir)Plugin\HMI.DataViewer.dll"
move /y "$(TargeDir)HMI.IOMonitor.dll" $(TargeDir)Plugin\HMI.IOMonitor.dll"
move /y "$(TargeDir)HMI.LogViewer.dll" $(TargeDir)Plugin\HMI.LogViewer.dll"
move /y "$(TargeDir)HMI.MenuManage.dll" $(TargeDir)Plugin\HMI.MenuManage.dll"
move /y "$(TargeDir)HMI.ParameterManage.dll" $(TargeDir)Plugin\HMI.ParameterManage.dll"
move /y "$(TargeDir)HMI.SettingControl.dll" $(TargeDir)Plugin\HMI.SettingControl.dll"
move /y "$(TargeDir)Plugin.TestResult.dll" $(TargeDir)Plugin\Plugin.TestResult.dll"
move /y "$(TargeDir)Plugin.TsExecution.dll" $(TargeDir)Plugin\Plugin.TsExecution.dll"
setlocal enabledelayedexpansion
set "source_folder=$(TargetDir)"
set "destination_folder=$(TargetDir)3rds"
if not exist "%25destination_folder%25" mkdir "%25destination_folder%25"
for /d %25%25D in ("%25source_folder%25\*") do (
    if /I not "%25%25~nxD"=="Config" if /I not "%25%25~nxD"=="Icon" if /I not "%25%25~nxD"=="Lang" if /I not "%25%25~nxD"=="Libs" if /I not "%25%25~nxD"=="Log" if /I not "%25%25~nxD"=="Plugin" (
        move "%25%25D" "%25destination_folder%25"
    )
)
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" (
        move "%25%25F" "%25destination_folder%25"
    )
)</PostBuildEvent>
  </PropertyGroup>
  <ProjectExtensions>
    <VisualStudio>