Bläddra i källkod

20260110001 增加新工程-带语言切换的界面

向羽 孟 3 månader sedan
förälder
incheckning
dcacbf039d
73 ändrade filer med 8932 tillägg och 0 borttagningar
  1. 14 0
      CCDCount.sln
  2. 21 0
      TestWork.DLL/PLCManagementClass.cs
  3. BIN
      WpfSwitchLanguage/23s6k-ono7l-001.ico
  4. 25 0
      WpfSwitchLanguage/App.config
  5. 8 0
      WpfSwitchLanguage/App.xaml
  6. 63 0
      WpfSwitchLanguage/App.xaml.cs
  7. BIN
      WpfSwitchLanguage/FromImage/23s6k-ono7l-001.ico
  8. BIN
      WpfSwitchLanguage/FromImage/PLC信息管理.png
  9. BIN
      WpfSwitchLanguage/FromImage/PLC信息管理_白.png
  10. BIN
      WpfSwitchLanguage/FromImage/export.png
  11. BIN
      WpfSwitchLanguage/FromImage/mmexport1752891278116.jpg
  12. BIN
      WpfSwitchLanguage/FromImage/print.png
  13. BIN
      WpfSwitchLanguage/FromImage/中断.png
  14. BIN
      WpfSwitchLanguage/FromImage/刷新.png
  15. BIN
      WpfSwitchLanguage/FromImage/审计信息审计_白.png
  16. BIN
      WpfSwitchLanguage/FromImage/操作_白.png
  17. BIN
      WpfSwitchLanguage/FromImage/故障.png
  18. BIN
      WpfSwitchLanguage/FromImage/故障_白.png
  19. BIN
      WpfSwitchLanguage/FromImage/数据.png
  20. BIN
      WpfSwitchLanguage/FromImage/数据_白.png
  21. BIN
      WpfSwitchLanguage/FromImage/暂停.png
  22. BIN
      WpfSwitchLanguage/FromImage/用户修改.png
  23. BIN
      WpfSwitchLanguage/FromImage/用户删除.png
  24. BIN
      WpfSwitchLanguage/FromImage/用户增加.png
  25. BIN
      WpfSwitchLanguage/FromImage/用户管理.png
  26. BIN
      WpfSwitchLanguage/FromImage/用户管理_白.png
  27. BIN
      WpfSwitchLanguage/FromImage/相机小_灰.png
  28. BIN
      WpfSwitchLanguage/FromImage/相机小_白.png
  29. BIN
      WpfSwitchLanguage/FromImage/相机小_黑.png
  30. BIN
      WpfSwitchLanguage/FromImage/菜单_灰.png
  31. BIN
      WpfSwitchLanguage/FromImage/菜单_白.png
  32. BIN
      WpfSwitchLanguage/FromImage/设置.png
  33. BIN
      WpfSwitchLanguage/FromImage/设置_白.png
  34. BIN
      WpfSwitchLanguage/FromImage/运行.png
  35. BIN
      WpfSwitchLanguage/FromImage/退出.png
  36. BIN
      WpfSwitchLanguage/FromImage/退出_灰.png
  37. BIN
      WpfSwitchLanguage/FromImage/退出_白.png
  38. BIN
      WpfSwitchLanguage/FromImage/键盘_白.png
  39. 1179 0
      WpfSwitchLanguage/PlcMessageShowBindingClass.cs
  40. 52 0
      WpfSwitchLanguage/Properties/AssemblyInfo.cs
  41. 73 0
      WpfSwitchLanguage/Properties/Resources.Designer.cs
  42. 124 0
      WpfSwitchLanguage/Properties/Resources.resx
  43. 30 0
      WpfSwitchLanguage/Properties/Settings.Designer.cs
  44. 7 0
      WpfSwitchLanguage/Properties/Settings.settings
  45. 1013 0
      WpfSwitchLanguage/ShowBindingClass.cs
  46. 59 0
      WpfSwitchLanguage/WpfFrom/AddUserWindow.xaml
  47. 74 0
      WpfSwitchLanguage/WpfFrom/AddUserWindow.xaml.cs
  48. 79 0
      WpfSwitchLanguage/WpfFrom/ChangeUserWindow.xaml
  49. 108 0
      WpfSwitchLanguage/WpfFrom/ChangeUserWindow.xaml.cs
  50. 104 0
      WpfSwitchLanguage/WpfFrom/MainWindow.xaml
  51. 654 0
      WpfSwitchLanguage/WpfFrom/MainWindow.xaml.cs
  52. 18 0
      WpfSwitchLanguage/WpfFrom/SplashWindow.xaml
  53. 27 0
      WpfSwitchLanguage/WpfFrom/SplashWindow.xaml.cs
  54. 68 0
      WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml
  55. 78 0
      WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml.cs
  56. 81 0
      WpfSwitchLanguage/WpfPage/AuditTrailPage.xaml
  57. 955 0
      WpfSwitchLanguage/WpfPage/AuditTrailPage.xaml.cs
  58. 71 0
      WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml
  59. 319 0
      WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml.cs
  60. 463 0
      WpfSwitchLanguage/WpfPage/MainPage.xaml
  61. 533 0
      WpfSwitchLanguage/WpfPage/MainPage.xaml.cs
  62. 23 0
      WpfSwitchLanguage/WpfPage/MessagePage.xaml
  63. 29 0
      WpfSwitchLanguage/WpfPage/MessagePage.xaml.cs
  64. 47 0
      WpfSwitchLanguage/WpfPage/PlcOperationPage.xaml
  65. 247 0
      WpfSwitchLanguage/WpfPage/PlcOperationPage.xaml.cs
  66. 319 0
      WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml
  67. 1058 0
      WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml.cs
  68. 116 0
      WpfSwitchLanguage/WpfPage/SettingPage.xaml
  69. 244 0
      WpfSwitchLanguage/WpfPage/SettingPage.xaml.cs
  70. 51 0
      WpfSwitchLanguage/WpfPage/UserManagementPage.xaml
  71. 81 0
      WpfSwitchLanguage/WpfPage/UserManagementPage.xaml.cs
  72. 338 0
      WpfSwitchLanguage/WpfSwitchLanguage.csproj
  73. 79 0
      WpfSwitchLanguage/app.manifest

+ 14 - 0
CCDCount.sln

@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCDCount.MODEL", "TestWork.
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCDCountWpf", "CCDCountWpf\CCDCountWpf.csproj", "{DCCBE504-5801-442E-A406-4A7099D46553}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfSwitchLanguage", "WpfSwitchLanguage\WpfSwitchLanguage.csproj", "{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -55,6 +57,18 @@ Global
 		{DCCBE504-5801-442E-A406-4A7099D46553}.Release|x64.Build.0 = Release|Any CPU
 		{DCCBE504-5801-442E-A406-4A7099D46553}.Release|x86.ActiveCfg = Release|x86
 		{DCCBE504-5801-442E-A406-4A7099D46553}.Release|x86.Build.0 = Release|x86
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Debug|x64.Build.0 = Debug|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Debug|x86.ActiveCfg = Debug|x86
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Debug|x86.Build.0 = Debug|x86
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Release|x64.ActiveCfg = Release|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Release|x64.Build.0 = Release|Any CPU
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Release|x86.ActiveCfg = Release|x86
+		{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 21 - 0
TestWork.DLL/PLCManagementClass.cs

@@ -1,7 +1,9 @@
 using CCDCount.DLL.AlarmTools;
 using CCDCount.DLL.Tools;
 using CCDCount.MODEL.PlcModel;
+using iTextSharp.text;
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Remoting.Messaging;
 using System.Security.Cryptography;
@@ -969,6 +971,14 @@ namespace CCDCount.DLL
             return result;
         }
 
+        public int BottingSpeed { 
+            get
+            {
+                return BottTimeList[BottTimeList.Count - 1].bottnum - (BottTimeList.Where(o => (DateTime.Now - o.BootTime).TotalSeconds > 1).Max(o => o.bottnum));
+            }
+        }
+        List<(int bottnum, DateTime BootTime)> BottTimeList = new List<(int, DateTime)>();
+
         public bool ReadBottingCount(out ushort Count)
         {
             bool result = false;
@@ -981,6 +991,17 @@ namespace CCDCount.DLL
             {
                 Count = 0;
             }
+            for (int i = BottTimeList.Count-1;i>0;i--)
+            {
+                if ((DateTime.Now - BottTimeList[i].BootTime).TotalSeconds>2)
+                {
+                    BottTimeList.Remove(BottTimeList[i]);
+                }
+            }
+            if(result)
+            {
+                BottTimeList.Add((Count, DateTime.Now));
+            }
             return result;
         }
 

BIN
WpfSwitchLanguage/23s6k-ono7l-001.ico


+ 25 - 0
WpfSwitchLanguage/App.config

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <configSections>
+    
+    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+  </configSections>
+  <startup>
+    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
+  </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+  <entityFramework>
+    <providers>
+      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
+    </providers>
+  </entityFramework>
+  
+</configuration>

+ 8 - 0
WpfSwitchLanguage/App.xaml

@@ -0,0 +1,8 @@
+<Application x:Class="CCDCountWpf.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:CCDCountWpf" StartupUri="/WpfFrom/UserLoginWindow.xaml">
+    <Application.Resources>
+         
+    </Application.Resources>
+</Application>

+ 63 - 0
WpfSwitchLanguage/App.xaml.cs

@@ -0,0 +1,63 @@
+using CCDCount.DLL;
+using CCDCount.DLL.SqlDataClass;
+using CCDCount.MODEL.SqlDataModel;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Threading;
+
+namespace CCDCountWpf
+{
+    public static class MessageBus
+    {
+        //public static List<MainThreadClass> MainThreadS = new List<MainThreadClass>();
+
+        public static MainThreadClass NowSettingLoadMainThread = null;
+
+        public static CameraClass CameraClass = new CameraClass();
+
+        public static UserMessSqliteDataClass UserMessageClass = new UserMessSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\UserData\\UserMessage.db");
+
+        public static UserMesDataModelClass NowLoginUserMessage = null;
+
+
+        public static string NowLoadCammeraSN = string.Empty;
+    }
+    public static class ShowMessageBus
+    {
+        public static ShowBindingClass ShowBinding = new ShowBindingClass();
+    }
+
+    public static class PlcSettingMessageBus
+    {
+        public static PLCManagementClass pLCManagement = null;
+
+        public static PlcMessageShowBindingClass PlcMessageShowBindage = new PlcMessageShowBindingClass();
+    }
+    /// <summary>
+    /// App.xaml 的交互逻辑
+    /// </summary>
+    public partial class App : Application
+    {
+        protected override void OnStartup(StartupEventArgs e)
+        {
+            base.OnStartup(e);
+
+            // 处理 UI 线程异常
+            this.DispatcherUnhandledException += (sender, args) =>
+            {
+                if (args.Exception is System.InvalidCastException &&
+                    args.Exception.Message.Contains("Microsoft.Web.WebView2"))
+                {
+                    // 忽略 WebView2 相关的 COM 异常
+                    args.Handled = true;
+                }
+            };
+        }
+    }
+}

BIN
WpfSwitchLanguage/FromImage/23s6k-ono7l-001.ico


BIN
WpfSwitchLanguage/FromImage/PLC信息管理.png


BIN
WpfSwitchLanguage/FromImage/PLC信息管理_白.png


BIN
WpfSwitchLanguage/FromImage/export.png


BIN
WpfSwitchLanguage/FromImage/mmexport1752891278116.jpg


BIN
WpfSwitchLanguage/FromImage/print.png


BIN
WpfSwitchLanguage/FromImage/中断.png


BIN
WpfSwitchLanguage/FromImage/刷新.png


BIN
WpfSwitchLanguage/FromImage/审计信息审计_白.png


BIN
WpfSwitchLanguage/FromImage/操作_白.png


BIN
WpfSwitchLanguage/FromImage/故障.png


BIN
WpfSwitchLanguage/FromImage/故障_白.png


BIN
WpfSwitchLanguage/FromImage/数据.png


BIN
WpfSwitchLanguage/FromImage/数据_白.png


BIN
WpfSwitchLanguage/FromImage/暂停.png


BIN
WpfSwitchLanguage/FromImage/用户修改.png


BIN
WpfSwitchLanguage/FromImage/用户删除.png


BIN
WpfSwitchLanguage/FromImage/用户增加.png


BIN
WpfSwitchLanguage/FromImage/用户管理.png


BIN
WpfSwitchLanguage/FromImage/用户管理_白.png


BIN
WpfSwitchLanguage/FromImage/相机小_灰.png


BIN
WpfSwitchLanguage/FromImage/相机小_白.png


BIN
WpfSwitchLanguage/FromImage/相机小_黑.png


BIN
WpfSwitchLanguage/FromImage/菜单_灰.png


BIN
WpfSwitchLanguage/FromImage/菜单_白.png


BIN
WpfSwitchLanguage/FromImage/设置.png


BIN
WpfSwitchLanguage/FromImage/设置_白.png


BIN
WpfSwitchLanguage/FromImage/运行.png


BIN
WpfSwitchLanguage/FromImage/退出.png


BIN
WpfSwitchLanguage/FromImage/退出_灰.png


BIN
WpfSwitchLanguage/FromImage/退出_白.png


BIN
WpfSwitchLanguage/FromImage/键盘_白.png


+ 1179 - 0
WpfSwitchLanguage/PlcMessageShowBindingClass.cs

@@ -0,0 +1,1179 @@
+using CCDCount.DLL;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CCDCountWpf
+{
+    public class PlcMessageShowBindingClass : INotifyPropertyChanged
+    {
+        /// <summary>
+        /// 使能完成
+        /// </summary>
+        private bool enableCompletion;
+        public bool EnableCompletion
+        {
+            get { return enableCompletion; }
+            set
+            {
+                enableCompletion = value;
+                OnPropertyChanged("EnableCompletion");
+            }
+        }
+
+        /// <summary>
+        /// 速度运行
+        /// </summary>
+        private bool speedRunning;
+        public bool SpeedRunning
+        {
+            get { return speedRunning; }
+            set
+            {
+                speedRunning = value;
+                OnPropertyChanged("SpeedRunning");
+            }
+        }
+
+        /// <summary>
+        /// 允许数据交换
+        /// </summary>
+        private bool allowsDataExchange;
+        public bool AllowsDataExchange
+        {
+            get { return allowsDataExchange; }
+            set
+            {
+                allowsDataExchange = value;
+                OnPropertyChanged("AllowsDataExchange");
+            }
+        }
+
+        /// <summary>
+        /// 暂停数据交换
+        /// </summary>
+        private bool pauseDataExchange;
+        public bool PauseDataExchange
+        {
+            get { return pauseDataExchange; }
+            set
+            {
+                pauseDataExchange = value;
+                OnPropertyChanged("PauseDataExchange");
+            }
+        }
+
+        /// <summary>
+        /// 缓存计数延迟完成
+        /// </summary>
+        private bool cacheCountDelayed;
+        public bool CacheCountDelayed
+        {
+            get { return cacheCountDelayed; }
+            set
+            {
+                cacheCountDelayed = value;
+                OnPropertyChanged("CacheCountDelayed");
+            }
+        }
+
+        /// <summary>
+        /// 使能
+        /// </summary>
+        private bool enable;
+        public bool Enable
+        {
+            get { return enable; }
+            set
+            {
+                enable = value;
+                OnPropertyChanged("Enable");
+            }
+        }
+
+        /// <summary>
+        /// 罐装模式
+        /// </summary>
+        private ushort fillingModel;
+        public ushort FillingModel
+        {
+            get { return fillingModel; }
+            set
+            {
+                ushort oldValue = fillingModel;
+                if (PlcSettingMessageBus.pLCManagement.WriteFillingMode(value))
+                {
+                    fillingModel = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装模式从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("FillingModel");
+            }
+        }
+
+        /// <summary>
+        /// 传送带速度
+        /// </summary>
+        private ushort beltsSpeed;
+        public ushort BeltsSpeed
+        {
+            get { return beltsSpeed; }
+            set
+            {
+                ushort oldValue = beltsSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteBeltsSpeed(value))
+                {
+                    beltsSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"传送带速度从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("BeltsSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装料筒震台高速值
+        /// </summary>
+        private ushort shakeTable1H_FillingSpeed;
+        public ushort ShakeTable1H_FillingSpeed
+        {
+            get { return shakeTable1H_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1H_FillingSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable1H_FillingSpeed(value))
+                {
+                    shakeTable1H_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装料筒震台高速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1H_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装过滤震台高速值
+        /// </summary>
+        private ushort shakeTable2H_FillingSpeed;
+        public ushort ShakeTable2H_FillingSpeed
+        {
+            get { return shakeTable2H_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2H_FillingSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable2H_FillingSpeed(value))
+                {
+                    shakeTable2H_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装过滤震台高速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2H_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装计数震台高速值
+        /// </summary>
+        private ushort shakeTable3H_FillingSpeed;
+        public ushort ShakeTable3H_FillingSpeed
+        {
+            get { return shakeTable3H_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3H_FillingSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable3H_FillingSpeed(value))
+                {
+                    shakeTable3H_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装计数震台高速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3H_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装料筒震台减速值
+        /// </summary>
+        private ushort shakeTable1M_FillingSpeed;
+        public ushort ShakeTable1M_FillingSpeed
+        {
+            get { return shakeTable1M_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1M_FillingSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable1M_FillingSpeed(value))
+                {
+                    shakeTable1M_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装料筒震台减速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1M_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装过滤震台减速值
+        /// </summary>
+        private ushort shakeTable2M_FillingSpeed;
+        public ushort ShakeTable2M_FillingSpeed
+        {
+            get { return shakeTable2M_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2M_FillingSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable2M_FillingSpeed(value))
+                {
+                    shakeTable2M_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装过滤震台减速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2M_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装计数震台减速值
+        /// </summary>
+        private ushort shakeTable3M_FillingSpeed;
+        public ushort ShakeTable3M_FillingSpeed
+        {
+            get { return shakeTable3M_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3M_FillingSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable3M_FillingSpeed(value))
+                {
+                    shakeTable3M_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装计数震台减速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3M_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装料筒震台低速值
+        /// </summary>
+        private ushort shakeTable1L_FillingSpeed;
+        public ushort ShakeTable1L_FillingSpeed
+        {
+            get { return shakeTable1L_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1L_FillingSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable1L_FillingSpeed(value))
+                {
+                    shakeTable1L_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装料筒震台低速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1L_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装过滤震台低速值
+        /// </summary>
+        private ushort shakeTable2L_FillingSpeed;
+        public ushort ShakeTable2L_FillingSpeed
+        {
+            get { return shakeTable2L_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2L_FillingSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable2L_FillingSpeed(value))
+                {
+                    shakeTable2L_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装过滤震台低速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2L_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 罐装计数震台减速值
+        /// </summary>
+        private ushort shakeTable3L_FillingSpeed;
+        public ushort ShakeTable3L_FillingSpeed
+        {
+            get { return shakeTable3L_FillingSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3L_FillingSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable3L_FillingSpeed(value))
+                {
+                    shakeTable3L_FillingSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装计数震台低速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3L_FillingSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存料筒震台高速值
+        /// </summary>
+        private ushort shakeTable1H_CacheSpeed;
+        public ushort ShakeTable1H_CacheSpeed
+        {
+            get { return shakeTable1H_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1H_CacheSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable1H_CacheSpeed(value))
+                {
+                    shakeTable1H_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存料筒震台高速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1H_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存过滤震台高速值
+        /// </summary>
+        private ushort shakeTable2H_CacheSpeed;
+        public ushort ShakeTable2H_CacheSpeed
+        {
+            get { return shakeTable2H_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2H_CacheSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable2H_CacheSpeed(value))
+                {
+                    shakeTable2H_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存过滤震台高速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2H_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存计数震台高速值
+        /// </summary>
+        private ushort shakeTable3H_CacheSpeed;
+        public ushort ShakeTable3H_CacheSpeed
+        {
+            get { return shakeTable3H_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3H_CacheSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable3H_CacheSpeed(value))
+                {
+                    shakeTable3H_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存计数震台高速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3H_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存料筒震台减速值
+        /// </summary>
+        private ushort shakeTable1M_CacheSpeed;
+        public ushort ShakeTable1M_CacheSpeed
+        {
+            get { return shakeTable1M_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1M_CacheSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable1M_CacheSpeed(value))
+                {
+                    shakeTable1M_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存料筒震台减速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1M_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存过滤震台减速值
+        /// </summary>
+        private ushort shakeTable2M_CacheSpeed;
+        public ushort ShakeTable2M_CacheSpeed
+        {
+            get { return shakeTable2M_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2M_CacheSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable2M_CacheSpeed(value))
+                {
+                    shakeTable2M_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存过滤震台减速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2M_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存计数震台减速值
+        /// </summary>
+        private ushort shakeTable3M_CacheSpeed;
+        public ushort ShakeTable3M_CacheSpeed
+        {
+            get { return shakeTable3M_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3M_CacheSpeed;
+                if(PlcSettingMessageBus.pLCManagement.WriteShakeTable3M_CacheSpeed(value))
+                {
+                    shakeTable3M_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存计数震台减速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3M_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存料筒震台减速值
+        /// </summary>
+        private ushort shakeTable1L_CacheSpeed;
+        public ushort ShakeTable1L_CacheSpeed
+        {
+            get { return shakeTable1L_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1L_CacheSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable1L_CacheSpeed(value))
+                {
+                    shakeTable1L_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存料筒震台低速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1L_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存过滤震台减速值
+        /// </summary>
+        private ushort shakeTable2L_CacheSpeed;
+        public ushort ShakeTable2L_CacheSpeed
+        {
+            get { return shakeTable2L_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2L_CacheSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable2L_CacheSpeed(value))
+                {
+                    shakeTable2L_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存过滤震台低速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2L_CacheSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存计数震台低速值
+        /// </summary>
+        private ushort shakeTable3L_CacheSpeed;
+        public ushort ShakeTable3L_CacheSpeed
+        {
+            get { return shakeTable3L_CacheSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3L_CacheSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable3L_CacheSpeed(value))
+                {
+                    shakeTable3L_CacheSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存计数震台低速值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3L_CacheSpeed");
+            }
+        }
+
+
+        /// <summary>
+        /// 罐装高速区间
+        /// </summary>
+        private ushort fillingH_SpeedRatio;
+        public ushort FillingH_SpeedRatio
+        {
+            get { return fillingH_SpeedRatio; }
+            set
+            {
+                ushort oldValue = fillingH_SpeedRatio;
+                if (PlcSettingMessageBus.pLCManagement.WriteFillingH_SpeedRatio(value))
+                {
+                    fillingH_SpeedRatio = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装高速区间值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("FillingH_SpeedRatio");
+            }
+        }
+
+        /// <summary>
+        /// 罐装减速区间
+        /// </summary>
+        private ushort fillingM_SpeedRatio;
+        public ushort FillingM_SpeedRatio
+        {
+            get { return fillingM_SpeedRatio; }
+            set
+            {
+                ushort oldValue = fillingM_SpeedRatio;
+                if (PlcSettingMessageBus.pLCManagement.WriteFillingM_SpeedRatio(value))
+                {
+                    fillingM_SpeedRatio = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装减速区间值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("FillingM_SpeedRatio");
+            }
+        }
+
+        /// <summary>
+        /// 罐装低速区间
+        /// </summary>
+        private ushort fillingL_SpeedRatio;
+        public ushort FillingL_SpeedRatio
+        {
+            get { return fillingL_SpeedRatio; }
+            set
+            {
+                ushort oldValue = fillingL_SpeedRatio;
+                if (PlcSettingMessageBus.pLCManagement.WriteFillingL_SpeedRatio(value))
+                {
+                    fillingL_SpeedRatio = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"罐装低速区间值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("FillingL_SpeedRatio");
+            }
+        }
+
+        /// <summary>
+        /// 缓存高速区间
+        /// </summary>
+        private ushort cacheH_SpeedRatio;
+        public ushort CacheH_SpeedRatio
+        {
+            get { return cacheH_SpeedRatio; }
+            set
+            {
+                ushort oldValue = cacheH_SpeedRatio;
+                if (PlcSettingMessageBus.pLCManagement.WriteCacheH_SpeedRatio(value))
+                {
+                    cacheH_SpeedRatio = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存高速区间值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("CacheH_SpeedRatio");
+            }
+        }
+
+        /// <summary>
+        /// 缓存减速区间
+        /// </summary>
+        private ushort cacheM_SpeedRatio;
+        public ushort CacheM_SpeedRatio
+        {
+            get { return cacheM_SpeedRatio; }
+            set
+            {
+                ushort oldValue = cacheM_SpeedRatio;
+                if (PlcSettingMessageBus.pLCManagement.WriteCacheM_SpeedRatio(value))
+                {
+                    cacheM_SpeedRatio = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存减速区间值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("CacheM_SpeedRatio");
+            }
+        }
+
+        /// <summary>
+        /// 缓存低速区间
+        /// </summary>
+        private ushort cacheL_SpeedRatio;
+        public ushort CacheL_SpeedRatio
+        {
+            get { return cacheL_SpeedRatio; }
+            set
+            {
+                ushort oldValue = cacheL_SpeedRatio;
+                if (PlcSettingMessageBus.pLCManagement.WriteCacheL_SpeedRatio(value))
+                {
+                    cacheL_SpeedRatio = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存低速区间值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("CacheL_SpeedRatio");
+            }
+        }
+
+        /// <summary>
+        /// 传动轴点动速度
+        /// </summary>
+        private double screwJogSpeed;
+        public string ScrewJogSpeed
+        {
+            get { return screwJogSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = screwJogSpeed;
+                    if (PlcSettingMessageBus.pLCManagement.WriteScrewJogSpeed(result))
+                    {
+                        screwJogSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"传动轴点动速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("ScrewJogSpeed");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 进瓶速度
+        /// </summary>
+        private double inBottleSpeed;
+        public string InBottleSpeed
+        {
+            get { return inBottleSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = inBottleSpeed;
+                    if (PlcSettingMessageBus.pLCManagement.WriteInBottleSpeed(result))
+                    {
+                        inBottleSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"传动轴点动速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("InBottleSpeed");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 传动轴绝对定位速度
+        /// </summary>
+        private double bottlePosSpeed;
+        public string BottlePosSpeed
+        {
+            get { return bottlePosSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = bottlePosSpeed;
+                    if (PlcSettingMessageBus.pLCManagement.WriteBottlePosSpeed(result))
+                    {
+                        bottlePosSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"传动轴绝对定位速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("BottlePosSpeed");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 传动轴绝对定位位置
+        /// </summary>
+        private double bottlePosPosition;
+        public string BottlePosPosition
+        {
+            get { return bottlePosPosition.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = bottlePosPosition;
+                    if (PlcSettingMessageBus.pLCManagement.WriteBottlePosPosition(result))
+                    {
+                        bottlePosPosition = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"传动轴绝对定位位置从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("BottlePosPosition");
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// 中转阀打开速度
+        /// </summary>
+        private float fillingValveOpenSpeed;
+        public string FillingValveOpenSpeed
+        {
+            get { return fillingValveOpenSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    float oldValue = fillingValveOpenSpeed;
+                    if (PlcSettingMessageBus.pLCManagement.WriteFillingValveOpenSpeed(result))
+                    {
+                        fillingValveOpenSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀打开速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveOpenSpeed");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 中转阀打开位置
+        /// </summary>
+        private float fillingValveOpenPosition;
+        public string FillingValveOpenPosition
+        {
+            get { return fillingValveOpenPosition.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    float oldValue = fillingValveOpenPosition;
+                    if (PlcSettingMessageBus.pLCManagement.WriteFillingValveOpenPosition(result))
+                    {
+                        fillingValveOpenPosition = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀打开速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveOpenPosition");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 中转阀关闭速度
+        /// </summary>
+        private double fillingValveCloseSpeed;
+        public string FillingValveCloseSpeed
+        {
+            get { return fillingValveCloseSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = fillingValveCloseSpeed;
+                    if(PlcSettingMessageBus.pLCManagement.WriteFillingValveCloseSpeed(result))
+                    {
+                        fillingValveCloseSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀关闭速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveCloseSpeed");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 中转阀关位置
+        /// </summary>
+        private double fillingValveClosePosition;
+        public string FillingValveClosePosition
+        {
+            get { return fillingValveClosePosition.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = fillingValveClosePosition;
+                    if(PlcSettingMessageBus.pLCManagement.WriteFillingValveClosePosition(result))
+                    {
+                        fillingValveClosePosition = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀关位置从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveClosePosition");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 中转阀缓存速度
+        /// </summary>
+        private double fillingValveCacheSpeed;
+        public string FillingValveCacheSpeed
+        {
+            get { return fillingValveCacheSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = fillingValveCacheSpeed;
+                    if (PlcSettingMessageBus.pLCManagement.WriteFillingValveCacheSpeed(result))
+                    {
+                        fillingValveCacheSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀缓存速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveCacheSpeed");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 中转阀缓存位置
+        /// </summary>
+        private double fillingValveCachePosition;
+        public string FillingValveCachePosition
+        {
+            get { return fillingValveCachePosition.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = fillingValveCachePosition;
+                    if (PlcSettingMessageBus.pLCManagement.WriteFillingValveCachePosition(result))
+                    {
+                        fillingValveCachePosition = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀缓存位置从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveCachePosition");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 中转阀缓存位置
+        /// </summary>
+        private double fillingValveJogSpeed;
+        public string FillingValveJogSpeed
+        {
+            get { return fillingValveJogSpeed.ToString("F2"); }
+            set
+            {
+                if (float.TryParse(value, out float result))
+                {
+                    double oldValue = fillingValveJogSpeed;
+                    if (PlcSettingMessageBus.pLCManagement.WriteFillingValveJogSpeed(result))
+                    {
+                        fillingValveJogSpeed = result;
+                        if (oldValue != result)
+                            FaultLog.RecordValueChangeMessage($"中转阀点动速度从{oldValue}修改为{result}");
+                    }
+                    OnPropertyChanged("FillingValveJogSpeed");
+                }
+            }
+        }
+        /// <summary>
+        /// 漏斗下降延时
+        /// </summary>
+        private ushort machineDelayFunneDownTime;
+        public ushort MachineDelayFunneDownTime
+        {
+            get { return machineDelayFunneDownTime; }
+            set
+            {
+                float oldValue = machineDelayFunneDownTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteMachineDelayFunneDownTime(value))
+                {
+                    machineDelayFunneDownTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"漏斗下降延时从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("MachineDelayFunneDownTime");
+            }
+        }
+
+        /// <summary>
+        /// 漏斗上升延时
+        /// </summary>
+        private ushort machineDelayFunneUpTime;
+        public ushort MachineDelayFunneUpTime
+        {
+            get { return machineDelayFunneUpTime; }
+            set
+            {
+                float oldValue = machineDelayFunneUpTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteMachineDelayFunneUpTime(value))
+                {
+                    machineDelayFunneUpTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"漏斗上升延时从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("MachineDelayFunneUpTime");
+            }
+        }
+
+        /// <summary>
+        /// 中转阀打开延时
+        /// </summary>
+        private ushort machineDelayFillingValveOpenTime;
+        public ushort MachineDelayFillingValveOpenTime
+        {
+            get { return machineDelayFillingValveOpenTime; }
+            set
+            {
+                float oldValue = machineDelayFillingValveOpenTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteMachineDelayFillingValveOpenTime(value))
+                {
+                    machineDelayFillingValveOpenTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"中转阀打开延时从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("MachineDelayFillingValveOpenTime");
+            }
+        }
+
+        /// <summary>
+        /// 中转阀打开延时
+        /// </summary>
+        private ushort machineDelayFillingValveCloseTime;
+        public ushort MachineDelayFillingValveCloseTime
+        {
+            get { return machineDelayFillingValveCloseTime; }
+            set
+            {
+                float oldValue = machineDelayFillingValveCloseTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteMachineDelayFillingValveCloseTime(value))
+                {
+                    machineDelayFillingValveCloseTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"中转阀关闭延时从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("MachineDelayFillingValveCloseTime");
+            }
+        }
+
+        /// <summary>
+        /// 进瓶延时
+        /// </summary>
+        private ushort machineDelayInBottleTime;
+        public ushort MachineDelayInBottleTime
+        {
+            get { return machineDelayInBottleTime; }
+            set
+            {
+                float oldValue = machineDelayInBottleTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteMachineDelayInBottleTime(value))
+                {
+                    machineDelayInBottleTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"进瓶延时从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("MachineDelayInBottleTime");
+            }
+        }
+
+        /// <summary>
+        /// 气阀开延时
+        /// </summary>
+        private ushort valveDelytime;
+        public ushort ValveDelytime
+        {
+            get { return valveDelytime; }
+            set
+            {
+                ushort oldValue = valveDelytime;
+                if (PlcSettingMessageBus.pLCManagement.WriteValveDelytime(value))
+                {
+                    valveDelytime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"气阀开延时从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ValveDelytime");
+            }
+        }
+
+        /// <summary>
+        /// 瓶装设定值
+        /// </summary>
+        private ushort bottValueSet;
+        public ushort BottValueSet
+        {
+            get { return bottValueSet; }
+            set
+            {
+                float oldValue = bottValueSet;
+                if (PlcSettingMessageBus.pLCManagement.WriteBottValueSet(value))
+                {
+                    bottValueSet = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"瓶装设定值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("BottValueSet");
+            }
+        }
+
+        /// <summary>
+        /// 缓存停机值
+        /// </summary>
+        private ushort cacheShutdownValue;
+        public ushort CacheShutdownValue
+        {
+            get { return cacheShutdownValue; }
+            set
+            {
+                ushort oldValue = cacheShutdownValue;
+                if (PlcSettingMessageBus.pLCManagement.WriteCacheShutdownValue(value))
+                {
+                    cacheShutdownValue = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存停机值从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("CacheShutdownValue");
+            }
+        }
+
+        /// <summary>
+        /// 缺瓶检测时间
+        /// </summary>
+        private ushort missingDelaytime;
+        public ushort MissingDelaytime
+        {
+            get { return missingDelaytime; }
+            set
+            {
+                ushort oldValue = missingDelaytime;
+                if (PlcSettingMessageBus.pLCManagement.WriteMissingDelaytime(value))
+                {
+                    missingDelaytime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缺瓶检测时间从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("MissingDelaytime");
+            }
+        }
+        /// <summary>
+        /// 堵瓶检测时间
+        /// </summary>
+        private ushort bottleJamDelaytime;
+        public ushort BottleJamDelaytime
+        {
+            get { return bottleJamDelaytime; }
+            set
+            {
+                ushort oldValue = bottleJamDelaytime;
+                if (PlcSettingMessageBus.pLCManagement.WriteBottleJamDelaytime(value))
+                {
+                    bottleJamDelaytime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"堵瓶检测时间从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("BottleJamDelaytime");
+            }
+        }
+
+        /// <summary>
+        /// 剔废气缸延时时间
+        /// </summary>
+        private ushort eliminateCylinderDelayTime;
+        public ushort EliminateCylinderDelayTime
+        {
+            get { return eliminateCylinderDelayTime; }
+            set
+            {
+                ushort oldValue = eliminateCylinderDelayTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteEliminateCylinderDelayTime(value))
+                {
+                    eliminateCylinderDelayTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"剔废气缸延时时间从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("EliminateCylinderDelayTime");
+            }
+        }
+
+        /// <summary>
+        /// 剔废气缸保持时间
+        /// </summary>
+        private ushort eliminateCylinderHoldingTime;
+        public ushort EliminateCylinderHoldingTime
+        {
+            get { return eliminateCylinderHoldingTime; }
+            set
+            {
+                ushort oldValue = eliminateCylinderHoldingTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteEliminateCylinderHoldingTime(value))
+                {
+                    eliminateCylinderHoldingTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"剔废气缸保持时间从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("EliminateCylinderHoldingTime");
+            }
+        }
+
+        /// <summary>
+        /// 料筒震台测试速度
+        /// </summary>
+        private ushort shakeTable1_TestSpeed;
+        public ushort ShakeTable1_TestSpeed
+        {
+            get { return shakeTable1_TestSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable1_TestSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable1_TestSpeed(value))
+                {
+                    shakeTable1_TestSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"料筒震台测试速度从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable1_TestSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 缓存震台测试速度
+        /// </summary>
+        private ushort shakeTable2_TestSpeed;
+        public ushort ShakeTable2_TestSpeed
+        {
+            get { return shakeTable2_TestSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable2_TestSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable2_TestSpeed(value))
+                {
+                    shakeTable2_TestSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"缓存震台测试速度从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable2_TestSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 计数震台测试速度
+        /// </summary>
+        private ushort shakeTable3_TestSpeed;
+        public ushort ShakeTable3_TestSpeed
+        {
+            get { return shakeTable3_TestSpeed; }
+            set
+            {
+                ushort oldValue = shakeTable3_TestSpeed;
+                if (PlcSettingMessageBus.pLCManagement.WriteShakeTable3_TestSpeed(value))
+                {
+                    shakeTable3_TestSpeed = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"计数震台测试速度从{oldValue}修改为{value}");
+                }
+                OnPropertyChanged("ShakeTable3_TestSpeed");
+            }
+        }
+
+        //数据绑定核心实现
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        protected void OnPropertyChanged(string propertyName)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+    }
+}

+ 52 - 0
WpfSwitchLanguage/Properties/AssemblyInfo.cs

@@ -0,0 +1,52 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("CCDCountWpf")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CCDCountWpf")]
+[assembly: AssemblyCopyright("Copyright ©  2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+//若要开始生成可本地化的应用程序,请设置
+//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
+//在 <PropertyGroup> 中。例如,如果你使用的是美国英语。
+//使用的是美国英语,请将 <UICulture> 设置为 en-US。  然后取消
+//对以下 NeutralResourceLanguage 特性的注释。  更新
+//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+                                     //(未在页面中找到资源时使用,
+                                     //或应用程序资源字典中找到时使用)
+    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+                                              //(未在页面中找到资源时使用,
+                                              //、应用程序或任何主题专用资源字典中找到时使用)
+)]
+
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 73 - 0
WpfSwitchLanguage/Properties/Resources.Designer.cs

@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace CCDCountWpf.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   一个强类型的资源类,用于查找本地化的字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   返回此类使用的缓存的 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CCDCountWpf.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   重写当前线程的 CurrentUICulture 属性,对
+        ///   使用此强类型资源类的所有资源查找执行重写。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   查找 System.Byte[] 类型的本地化资源。
+        /// </summary>
+        internal static byte[] Logo {
+            get {
+                object obj = ResourceManager.GetObject("Logo", resourceCulture);
+                return ((byte[])(obj));
+            }
+        }
+    }
+}

+ 124 - 0
WpfSwitchLanguage/Properties/Resources.resx

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="Logo" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\FromImage\mmexport1752891278116.jpg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+</root>

+ 30 - 0
WpfSwitchLanguage/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace CCDCountWpf.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
WpfSwitchLanguage/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 1013 - 0
WpfSwitchLanguage/ShowBindingClass.cs

@@ -0,0 +1,1013 @@
+using CCDCount.DLL;
+using CCDCount.MODEL.ConfigModel;
+using CCDCount.MODEL.SqlDataModel;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Drawing.Text;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace CCDCountWpf
+{
+    public class CameraCoboxItem
+    {
+        public string Name { get; set; }  // 显示的名称
+        public string SNValue { get; set; }  // 对应的编号
+    }
+
+    public class ShowBindingClass : INotifyPropertyChanged
+    {
+        /// <summary>
+        /// 累计数量
+        /// </summary>
+        private string allActiveNum = "0";
+        public string AllActiveNum
+        {
+            get { return allActiveNum; }
+            set
+            {
+                allActiveNum = value;
+                OnPropertyChanged("AllActiveNum");
+            }
+        }
+
+        /// <summary>
+        /// 累计OK
+        /// </summary>
+        private string allOkNum = "0";
+        public string AllOkNum
+        {
+            get { return allOkNum; }
+            set
+            {
+                allOkNum = value;
+                OnPropertyChanged("AllOkNum");
+            }
+        }
+
+        /// <summary>
+        /// 累计NG
+        /// </summary>
+        private string allNgNum = "0";
+        public string AllNgNum
+        {
+            get { return allNgNum; }
+            set
+            {
+                allNgNum = value;
+                OnPropertyChanged("AllNgNum");
+            }
+        }
+
+        /// <summary>
+        /// 数粒速度
+        /// </summary>
+        private string shuLiSpeed = "0";
+        public string ShuLiSpeed
+        {
+            get { return shuLiSpeed; }
+            set
+            {
+                shuLiSpeed = value;
+                OnPropertyChanged("ShuLiSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 数粒速度
+        /// </summary>
+        private string bottingCountSpeed = "0";
+        public string BottingCountSpeed
+        {
+            get { return bottingCountSpeed; }
+            set
+            {
+                bottingCountSpeed = value;
+                OnPropertyChanged("BottingCountSpeed");
+            }
+        }
+
+        /// <summary>
+        /// 内存监控
+        /// </summary>
+        private string ramMonitor = "";
+        public string RamMonitor
+        {
+            get { return ramMonitor; }
+            set
+            {
+                ramMonitor = value;
+                OnPropertyChanged("RamMonitor");
+            }
+        }
+
+        /// <summary>
+        /// CPU监控
+        /// </summary>
+        private string _CPUMonitor = "";
+        public string CPUMonitor
+        {
+            get { return _CPUMonitor; }
+            set
+            {
+                _CPUMonitor = value;
+                OnPropertyChanged("CPUMonitor");
+            }
+        }
+
+        /// <summary>
+        /// 相机运行状态
+        /// </summary>
+        private string camRunStatic = "未运行";
+        public string CamRunStatic
+        {
+            get { return camRunStatic; }
+            set
+            {
+                camRunStatic = value;
+                OnPropertyChanged("CamRunStatic");
+            }
+        }
+
+        /// <summary>
+        /// 历史结果当前图像编号
+        /// </summary>
+        private int historyImageNum = 1;
+        public int HistoryImageNum
+        {
+            get { return historyImageNum; }
+            set
+            {
+                historyImageNum = value;
+                OnPropertyChanged("HistoryImageNum");
+            }
+        }
+
+        /// <summary>
+        /// 历史结果图像数量
+        /// </summary>
+        private int historyImageCount = 0;
+        public int HistoryImageCount
+        {
+            get { return historyImageCount; }
+            set
+            {
+                historyImageCount = value;
+                OnPropertyChanged("HistoryImageCount");
+            }
+        }
+
+        /// <summary>
+        /// 历史结果图像
+        /// </summary>
+        private BitmapImage historyImage;
+        public BitmapImage HistoryImage
+        {
+            get { return historyImage; }
+            set
+            {
+                historyImage = value;
+                OnPropertyChanged("HistoryImage");
+            }
+        }
+
+        /// <summary>
+        /// 结果图像
+        /// </summary>
+        private BitmapImage bitmapImage;
+        public BitmapImage BitmapImage
+        {
+            get { return bitmapImage; }
+            set
+            {
+                bitmapImage = value;
+                OnPropertyChanged("BitmapImage");
+            }
+        }
+
+        /// <summary>
+        /// 结果图像
+        /// </summary>
+        private BitmapImage _DebugImage;
+        public BitmapImage DebugImage
+        {
+            get { return _DebugImage; }
+            set
+            {
+                _DebugImage = value;
+                OnPropertyChanged("DebugImage");
+            }
+        }
+
+        /// <summary>
+        /// 相机运行状态字体颜色
+        /// </summary>
+        private SolidColorBrush cameraStaticColor = Brushes.Red;
+        public SolidColorBrush CameraStaticColor
+        {
+            get { return cameraStaticColor; }
+            set
+            {
+                cameraStaticColor = value;
+                OnPropertyChanged("CameraStaticColor");
+            }
+        }
+
+        /// <summary>
+        /// 配方名称
+        /// </summary>
+        public string FormulationName
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.FormulationName;
+                }
+                return "";
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    string oldValue = MessageBus.NowSettingLoadMainThread.FormulationName;
+                    MessageBus.NowSettingLoadMainThread.FormulationName = value;
+                    MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"配方名称从{ oldValue }修改为{value}");
+                    OnPropertyChanged("FormulationName");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 相机曝光时间
+        /// </summary>
+        public string ExposureTimeValue
+        {
+            get
+            {
+                // 从MessageBus获取最新值(保证读取时同步)
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.cameraConfig.ExposureTimeValue.ToString();
+                }
+                return "";
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null && float.TryParse(value, out float newValue))
+                {
+                    // 同步更新到MessageBus
+                    float oldValue = MessageBus.NowSettingLoadMainThread.cameraConfig.ExposureTimeValue;
+                    MessageBus.NowSettingLoadMainThread.cameraConfig.ExposureTimeValue = newValue;
+                    MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                    MessageBus.NowSettingLoadMainThread.ReLoadCameraConfig();
+                    if (oldValue != newValue)
+                        FaultLog.RecordValueChangeMessage($"相机{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的曝光时间已从{oldValue}修改为{newValue}");
+                    OnPropertyChanged("ExposureTimeValue");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 相机行频
+        /// </summary>
+        public string AcquistionLineRate
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.cameraConfig.AcquistionLineRateValue.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set 
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        float oldValue = MessageBus.NowSettingLoadMainThread.cameraConfig.AcquistionLineRateValue;
+                        MessageBus.NowSettingLoadMainThread.cameraConfig.AcquistionLineRateValue = int.Parse(value);
+                        MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                        MessageBus.NowSettingLoadMainThread.ReLoadCameraConfig();
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"相机{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的行频从{oldValue}修改为{value}");
+                        OnPropertyChanged("AcquistionLineRate");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("AcquistionLineRate-SetError");
+                    }
+                    
+                }
+            }
+        }
+
+        /// <summary>
+        /// 图像宽度
+        /// </summary>
+        public string ImageWidth
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.cameraConfig.Width.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.cameraConfig.Width;
+                        MessageBus.NowSettingLoadMainThread.cameraConfig.Width = int.Parse(value);
+                        MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                        MessageBus.NowSettingLoadMainThread.ReLoadCameraConfig();
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"相机{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的图像宽从{oldValue}修改为{value}");
+                        OnPropertyChanged("ImageWidth");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("ImageWidth-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 相机名称(用户自定义)
+        /// </summary>
+        public string CamUserName
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.cameraConfig.CameraName;
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        string oldValue = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraName == "" ? "null" : MessageBus.NowSettingLoadMainThread.cameraConfig.CameraName;
+                        MessageBus.NowSettingLoadMainThread.cameraConfig.CameraName = value;
+                        MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                        MessageBus.NowSettingLoadMainThread.ReLoadCameraConfig();
+                        if (oldValue != value)
+                            FaultLog.RecordValueChangeMessage($"相机{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的用户自定义名从{oldValue}修改为{value}");
+                        OnPropertyChanged("CamUserName");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("CamUserName-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 图像偏移X
+        /// </summary>
+        public string CamOffsetX
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.cameraConfig.OffsetX.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.cameraConfig.OffsetX;
+                        MessageBus.NowSettingLoadMainThread.cameraConfig.OffsetX = int.Parse(value);
+                        MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                        MessageBus.NowSettingLoadMainThread.ReLoadCameraConfig();
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"相机{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的图像X偏移从{oldValue}修改为{value}");
+                        OnPropertyChanged("CamOffsetX");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("CamOffsetX-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 相机列表
+        /// </summary>
+        public ObservableCollection<CameraCoboxItem> CameraItems { get; } = new ObservableCollection<CameraCoboxItem>();
+
+        public ObservableCollection<string> FormulationItems { get; } = new ObservableCollection<string>();
+
+        public ObservableCollection<string> BatchItems { get; } = new ObservableCollection<string>();
+
+        public ObservableCollection<string> ValueChangeItems { get; } = new ObservableCollection<string>();
+
+        public ObservableCollection<string> ErrorMessItems { get; } = new ObservableCollection<string>();
+
+        /// <summary>
+        /// 当前选择的相机SN
+        /// </summary>
+        public string CameraSNNum
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        string oldValue = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+                        MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum = value;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.CameraSN = value;
+                        MessageBus.NowSettingLoadMainThread.CameraConfigIsChange = true;
+                        FaultLog.RecordValueChangeMessage($"相机{MessageBus.NowSettingLoadMainThread.cameraConfig.CamerNo}的SN从{oldValue}修改为{value}");
+                        OnPropertyChanged("CameraSNNum");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("CameraSNNum-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 预处理阈值
+        /// </summary>
+        public string RegionThreshold
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.RegionThreshold.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.RegionThreshold;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.RegionThreshold = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的预处理阈值从{oldValue}修改为{value}");
+                        OnPropertyChanged("RegionThreshold");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("RegionThreshold-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 数粒通道数
+        /// </summary>
+        public string Channel
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.Channel.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.Channel;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.Channel = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的通道数从{oldValue}修改为{value}");
+                        OnPropertyChanged("Channel");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("Channel-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 噪声滤波阈值
+        /// </summary>
+        public string NoiseFilter
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.NoiseFilter_Threshold.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.NoiseFilter_Threshold;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.NoiseFilter_Threshold = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的噪声滤波阈值从{oldValue}修改为{value}");
+                        OnPropertyChanged("NoiseFilter");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("NoiseFilter-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最小宽
+        /// </summary>
+        public string MIN_OBJECT_WIDTH
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_OBJECT_WIDTH.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_OBJECT_WIDTH;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_OBJECT_WIDTH = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的异常粒最小宽从{oldValue}修改为{value}");
+                        OnPropertyChanged("MIN_OBJECT_WIDTH");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MIN_OBJECT_WIDTH-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最大宽
+        /// </summary>
+        public string MAX_OBJECT_WIDTH
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_OBJECT_WIDTH.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_OBJECT_WIDTH;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_OBJECT_WIDTH = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的异常粒最大宽从{oldValue}修改为{value}");
+                        OnPropertyChanged("MAX_OBJECT_WIDTH");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MAX_OBJECT_WIDTH-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最小高
+        /// </summary>
+        public string MIN_OBJECT_HEIGHT
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_OBJECT_HEIGHT.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_OBJECT_HEIGHT;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_OBJECT_HEIGHT = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的异常粒最小高从{oldValue}修改为{value}");
+                        OnPropertyChanged("MIN_OBJECT_HEIGHT");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MIN_OBJECT_HEIGHT-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最大高
+        /// </summary>
+        public string MAX_OBJECT_HEIGHT
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_OBJECT_HEIGHT.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_OBJECT_HEIGHT;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_OBJECT_HEIGHT = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的异常粒最大高从{oldValue}修改为{value}");
+                        OnPropertyChanged("MAX_OBJECT_HEIGHT");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MAX_OBJECT_HEIGHT-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最长长度
+        /// </summary>
+        public string MAX_OBJECT_LENGTH
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_Object_LENGTH.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_Object_LENGTH;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MAX_Object_LENGTH = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的合格粒最长长度从{oldValue}修改为{value}");
+                        OnPropertyChanged("MAX_Object_LENGTH");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MAX_Object_LENGTH-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最短长度
+        /// </summary>
+        public string MIN_OBJECT_LENGTH
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_Object_LENGTH.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_Object_LENGTH;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MIN_Object_LENGTH = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的合格粒的最短长度从{oldValue}修改为{value}");
+                        OnPropertyChanged("MIN_Object_LENGTH");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MIN_Object_LENGTH-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最小面积
+        /// </summary>
+        public string MinArea
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MinArea.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MinArea;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MinArea = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的异常粒最小面积从{oldValue}修改为{value}");
+                        OnPropertyChanged("MinArea");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MinArea-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 合格粒最大面积
+        /// </summary>
+        public string MaxArea
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MaxArea.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.MaxArea;
+                        MessageBus.NowSettingLoadMainThread.shuLiConfig.MaxArea = int.Parse(value);
+                        if (oldValue != int.Parse(value))
+                            FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的异常粒最大面积从{oldValue}修改为{value}");
+                        OnPropertyChanged("MaxArea");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("MaxArea-SetError");
+                    }
+
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// 异常粒识别码
+        /// </summary>
+        public string PandingCode
+        {
+            get
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    return MessageBus.NowSettingLoadMainThread.shuLiConfig.MaxArea.ToString();
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            set
+            {
+                if (MessageBus.NowSettingLoadMainThread != null)
+                {
+                    try
+                    {
+                        int oldValue = MessageBus.NowSettingLoadMainThread.shuLiConfig.PandingCode;
+                        if(oldValue != int.Parse(value))
+                        {
+                            MessageBus.NowSettingLoadMainThread.shuLiConfig.PandingCode = int.Parse(value);
+                            if (oldValue != int.Parse(value))
+                                FaultLog.RecordValueChangeMessage($"数粒识别{MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum}的判断标准识别码从{oldValue}修改为{value}");
+                        }
+                        OnPropertyChanged("PandingCode");
+                    }
+                    catch (Exception)
+                    {
+                        Console.WriteLine("PandingCode-SetError");
+                    }
+
+                }
+            }
+        }
+
+        /// <summary>
+        /// 错误信息列表
+        /// </summary>
+        private List<ErroeMesDataModelClass> errMessageList = new List<ErroeMesDataModelClass>();
+        public List<ErroeMesDataModelClass> ErrMessageShowList
+        {
+            get { return errMessageList; }
+            set
+            {
+                errMessageList = value;
+                OnPropertyChanged("errMessageList");
+            }
+        }
+
+        private string showErrMessage = "";
+        public string ShowErrMessage
+        {
+            get { return showErrMessage; }
+            set
+            {
+                showErrMessage = value;
+                OnPropertyChanged("showErrMessage");
+            }
+        }
+
+        /// <summary>
+        /// 用户数据信息列表
+        /// </summary>
+        private List<UserMesDataModelClass> userMesDataModels = new List<UserMesDataModelClass>();
+        public List<UserMesDataModelClass> UserMesDataModels
+        {
+            get { return userMesDataModels; }
+            set
+            {
+                userMesDataModels = value;
+                OnPropertyChanged("userMesDataModels");
+            }
+        }
+
+        private string batchNumber = "";
+        public string BatchNumber
+        {
+            get { return batchNumber; }
+            set
+            {
+                batchNumber = value;
+                OnPropertyChanged("BatchNumber");
+            }
+        }
+
+        private int bottingCount;
+        public int BottingCount
+        {
+            get { return bottingCount; }
+            set
+            {
+                bottingCount = value;
+                OnPropertyChanged("BottingCount");
+            }
+        }
+
+        private ushort bottingSpeed;
+        public ushort BottingSpeed
+        {
+            get { return bottingSpeed; }
+            set
+            {
+                bottingSpeed = value;
+                OnPropertyChanged("BottingSpeed");
+            }
+        }
+
+        //数据绑定核心实现
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        protected void OnPropertyChanged(string propertyName)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+    }
+}

+ 59 - 0
WpfSwitchLanguage/WpfFrom/AddUserWindow.xaml

@@ -0,0 +1,59 @@
+<Window x:Class="CCDCountWpf.WpfFrom.AddUserWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CCDCountWpf.WpfFrom"
+        mc:Ignorable="d"
+        Title="AddUserWindow" Height="350" Width="300" ResizeMode="NoResize"
+        WindowStartupLocation="CenterScreen" Icon="/FromImage/mmexport1752891278116.jpg" Loaded="Window_Loaded">
+    <Grid>
+        <Grid Height="60" VerticalAlignment="Top" Background="#B20092FF">
+            <Label Content="添加用户" Margin="0,15,0,0" FontWeight="Bold" FontSize="20" VerticalAlignment="Top" HorizontalAlignment="Center"/>
+        </Grid>
+        <StackPanel Orientation="Vertical" Margin="0,60,0,0">
+            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="19,0,0,0">
+                <Label  Content="用户名:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <TextBox x:Name="UserNameTbx" HorizontalAlignment="Left" Margin="22,15,0,0"  Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"/>
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="19,0,0,0">
+                <Label  Content="密码:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <PasswordBox x:Name="UserPassTbx"  HorizontalAlignment="Left" Margin="41,15,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"  />
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="19,0,0,0">
+                <Label  Content="确认密码:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <PasswordBox x:Name="UserRePassTbx"  HorizontalAlignment="Left" Margin="0,15,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"  />
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="19,0,0,0">
+                <Label  Content="权限:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <ComboBox x:Name="UserLevelCbx" HorizontalAlignment="Left" Margin="41,12,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}" IsReadOnly="True"/>
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
+                <Button x:Name="AddUserBtn" Content="添加" BorderThickness="1" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Width="80" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="AddUserBtn_Click" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+                <Button x:Name="UserCancelBtn" Content="取消" BorderThickness="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="80" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="UserCancelBtn_Click" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+            </StackPanel>
+        </StackPanel>
+    </Grid>
+</Window>

+ 74 - 0
WpfSwitchLanguage/WpfFrom/AddUserWindow.xaml.cs

@@ -0,0 +1,74 @@
+using CCDCount.MODEL.SqlDataModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf.WpfFrom
+{
+    /// <summary>
+    /// AddUserWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class AddUserWindow : Window
+    {
+        public AddUserWindow()
+        {
+            InitializeComponent();
+        }
+
+        private void UserCancelBtn_Click(object sender, RoutedEventArgs e)
+        {
+            this.Close();
+        }
+
+        private void AddUserBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (UserNameTbx.Text == "" || UserPassTbx.Password == "" || UserRePassTbx.Password == "" || UserLevelCbx.SelectedItem == null)
+            {
+                MessageBox.Show("请将信息填写完整");
+                return;
+            }
+            if (ShowMessageBus.ShowBinding.UserMesDataModels.Where(x => x.UserName == UserNameTbx.Text).Count() > 0)
+            {
+                MessageBox.Show("用户名已存在");
+                return;
+            }
+            if (UserPassTbx.Password == UserRePassTbx.Password)
+            {
+                MessageBus.UserMessageClass.InsertUserMessage(new UserMesDataModelClass()
+                {
+                    UserName = UserNameTbx.Text,
+                    PassWord = UserPassTbx.Password,
+                    UserMes = UserLevelCbx.SelectedItem.ToString(),
+                    DateTime = DateTime.Now,
+                    IsDelete = false,
+                    IsAdmin = UserLevelCbx.SelectedItem.ToString() == "管理员" ? true : false
+                });
+            }
+            else
+            {
+                MessageBox.Show("密码不一致");
+                return;
+            }
+            MessageBox.Show("添加成功");
+            ShowMessageBus.ShowBinding.UserMesDataModels = MessageBus.UserMessageClass.GetAllUserMessage();
+            this.Close();
+        }
+
+        private void Window_Loaded(object sender, RoutedEventArgs e)
+        {
+            UserLevelCbx.Items.Add("管理员");
+            UserLevelCbx.Items.Add("普通用户");
+            UserLevelCbx.SelectedIndex = 1;
+        }
+    }
+}

+ 79 - 0
WpfSwitchLanguage/WpfFrom/ChangeUserWindow.xaml

@@ -0,0 +1,79 @@
+<Window x:Class="CCDCountWpf.WpfFrom.ChangeUserWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CCDCountWpf.WpfFrom"
+        mc:Ignorable="d"
+        Title="ChangeUserWindow" Height="430" Width="320" ResizeMode="NoResize"
+        WindowStartupLocation="CenterScreen" Icon="/FromImage/mmexport1752891278116.jpg" Loaded="Window_Loaded">
+    <Grid>
+        <Grid Height="60" VerticalAlignment="Top" Background="#B20092FF">
+            <Label Content="编辑用户" Margin="0,15,0,0" FontWeight="Bold" FontSize="20" VerticalAlignment="Top" HorizontalAlignment="Center"/>
+        </Grid>
+        <StackPanel Orientation="Vertical" Margin="0,60,0,0">
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="30,0,0,0">
+                <Label  Content="ID:" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <TextBox x:Name="UserIDTbx" HorizontalAlignment="Left" Margin="77,15,0,0"  Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}" IsReadOnly="True"/>
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="30,0,0,0">
+                <Label  Content="用户名:" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <TextBox x:Name="UserNameTbx" HorizontalAlignment="Left" Margin="40,15,0,0"  Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"/>
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="30,0,0,0">
+                <Label  Content="旧密码:" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <PasswordBox x:Name="UserOldPassTbx"  HorizontalAlignment="Left" Margin="40,15,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"  />
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="30,0,0,0">
+                <Label  Content="新密码:" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <PasswordBox x:Name="UserNewPassTbx"  HorizontalAlignment="Left" Margin="40,15,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"  />
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="30,0,0,0">
+                <Label  Content="重复新密码:" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <PasswordBox x:Name="UserReNewPassTbx"  HorizontalAlignment="Left" Margin="0,15,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}"  />
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="19,0,0,0">
+                <Label  Content="权限:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                <ComboBox x:Name="UserLevelCbx" HorizontalAlignment="Left" Margin="61,12,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}" IsReadOnly="True"/>
+            </StackPanel>
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
+                <Button x:Name="UserChangeBtn" Content="修改" BorderThickness="1" HorizontalAlignment="Left" Margin="0,10,10,0" VerticalAlignment="Top" Width="80" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="UserChangeBtn_Click" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+                <Button x:Name="UserResetPassBtn" Content="密码重置" BorderThickness="1" HorizontalAlignment="Left" Margin="5,10,5,0" VerticalAlignment="Top" Width="100" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="UserResetPassBtn_Click" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5" 
+                        Background="{TemplateBinding Background}"
+                        BorderBrush="{TemplateBinding BorderBrush}"
+                        BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+                <Button x:Name="UserCancelBtn" Content="取消" BorderThickness="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="80" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="UserCancelBtn_Click" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+            </StackPanel>
+        </StackPanel>
+    </Grid>
+</Window>

+ 108 - 0
WpfSwitchLanguage/WpfFrom/ChangeUserWindow.xaml.cs

@@ -0,0 +1,108 @@
+using CCDCount.MODEL.SqlDataModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf.WpfFrom
+{
+    /// <summary>
+    /// ChangeUserWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class ChangeUserWindow : Window
+    {
+        public UserMesDataModelClass UserMessage = null;
+        public ChangeUserWindow()
+        {
+            InitializeComponent();
+        }
+
+        private void UserCancelBtn_Click(object sender, RoutedEventArgs e)
+        {
+            this.Close();
+        }
+
+        private void UserChangeBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (UserMessage == null) return;
+            if (UserNameTbx.Text == "" || UserOldPassTbx.Password == "" || UserNewPassTbx.Password == "" 
+                || UserReNewPassTbx.Password == "" || UserLevelCbx.SelectedItem == null)
+            {
+                MessageBox.Show("请将信息填写完整");
+                return;
+            }
+            string OldPass = MessageBus.UserMessageClass.HashPassword(UserOldPassTbx.Password);
+            if (OldPass != UserMessage.PassWord)
+            {
+                MessageBox.Show("旧密码输入错误");
+                return;
+            }
+            if (UserReNewPassTbx.Password != UserNewPassTbx.Password)
+            {
+                MessageBox.Show("新密码输入不一致");
+                return;
+            }
+            if(ShowMessageBus.ShowBinding.UserMesDataModels.Where(x => x.UserName == UserNameTbx.Text).Count() > 0)
+            {
+                MessageBox.Show("用户名已存在");
+                return;
+            }
+            UserMesDataModelClass newUserMessage = new UserMesDataModelClass()
+            {
+                Id = UserMessage.Id,
+                UserName = UserNameTbx.Text,
+                PassWord = UserNewPassTbx.Password,
+                IsDelete = UserMessage.IsDelete,
+                IsAdmin = UserLevelCbx.SelectedItem.ToString() == "管理员" ? true : false,
+                UserMes = UserLevelCbx.SelectedItem.ToString()
+            };
+            MessageBus.UserMessageClass.ChangeUserMessage(UserMessage.Id, newUserMessage);
+            ShowMessageBus.ShowBinding.UserMesDataModels = MessageBus.UserMessageClass.GetAllUserMessage();
+            MessageBox.Show("修改成功");
+            this.Close();
+        }
+
+        private void UserResetPassBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(UserMessage == null) return;
+            var confirmResult = MessageBox.Show($"继续执行此操作将会重置用户{UserMessage.UserName}的密码至默认的\"123456\",是否继续执行",
+                                      "执行确认", MessageBoxButton.YesNo);
+            if (confirmResult == MessageBoxResult.No)
+            {
+                return;
+            }
+            MessageBus.UserMessageClass.ResetPassWord(UserMessage.Id);
+            ShowMessageBus.ShowBinding.UserMesDataModels = MessageBus.UserMessageClass.GetAllUserMessage();
+            MessageBox.Show("重置成功");
+            UserMessage = ShowMessageBus.ShowBinding.UserMesDataModels.Where(x => x.Id == UserMessage.Id).FirstOrDefault();
+        }
+
+        private void Window_Loaded(object sender, RoutedEventArgs e)
+        {
+            UserLevelCbx.Items.Clear();
+            if (UserMessage.IsAdmin && UserMessage.Id == 1)
+            {
+                UserLevelCbx.Items.Add("管理员");
+                UserLevelCbx.SelectedIndex = 0;
+                UserNameTbx.Text = UserMessage.UserName;
+                UserNameTbx.IsReadOnly = true;
+            }
+            else
+            {
+                UserLevelCbx.Items.Add("管理员");
+                UserLevelCbx.Items.Add("普通用户");
+                UserLevelCbx.SelectedItem = UserMessage.IsAdmin ? "管理员" : "普通用户";
+            }
+            UserIDTbx.Text = UserMessage.Id.ToString();
+        }
+    }
+}

+ 104 - 0
WpfSwitchLanguage/WpfFrom/MainWindow.xaml

@@ -0,0 +1,104 @@
+<Window x:Class="CCDCountWpf.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CCDCountWpf"
+        mc:Ignorable="d"
+        Title="MainWindow" Height="900" Width="1500" MinWidth="1000" MinHeight="720" Closing="Window_Closing" WindowStartupLocation="CenterScreen" Icon="/FromImage/mmexport1752891278116.jpg" Loaded="Window_Loaded"
+        RenderOptions.BitmapScalingMode="LowQuality" RenderOptions.EdgeMode="Unspecified" TextOptions.TextFormattingMode="Display" TextOptions.TextRenderingMode="Auto">
+    <Grid Background="#B2E0E0E0">
+        <Grid VerticalAlignment="Top" Height="60"  Background="#FF1200D1" Grid.ColumnSpan="2">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="60"/>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="60"/>
+                <ColumnDefinition Width="60"/>
+            </Grid.ColumnDefinitions>
+            <Button x:Name="MenuBtn" Grid.Column="0" HorizontalAlignment="Left" Height="60" Width="60" Click="MenuBtn_Click" Background="{x:Null}">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/菜单_白.png" Width="34" Height="34" />
+                    <TextBlock Text="菜单" FontSize="10" FontWeight="Bold" Margin="0,2,0,0" HorizontalAlignment="Center" Foreground="White" />
+                </StackPanel>
+            </Button>
+            <StackPanel Grid.Column="1" x:Name="HeardPanel" Orientation="Horizontal">
+                <Button x:Name="ExitBtn" HorizontalAlignment="Left" Height="60" Width="60" Click="ExitBtn_Click" Background="{x:Null}">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/退出_白.png" Width="28" Height="28" />
+                        <TextBlock Text="系统退出" FontSize="10" FontWeight="Bold" Margin="0,8,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="MainPageBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="MainPageBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/相机小_白.png" Width="32" Height="32" />
+                        <TextBlock Text="主界面" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="HistoryDataBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="HistoryDataBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/数据_白.png" Width="32" Height="32" />
+                        <TextBlock Text="历史数据" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="SettingBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="SettingBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/设置_白.png" Width="32" Height="32" />
+                        <TextBlock Text="相机设置" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="PlcSettingBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="PlcSettingBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/PLC信息管理_白.png" Width="32" Height="32" />
+                        <TextBlock Text="参数设置" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="PlcOperationBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="PlcOperationBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image Source="/FromImage/操作_白.png" Width="28" Height="34" />
+                        <TextBlock Text="操作测试" FontSize="10" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="ErrorMessageShowBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="ErrorMessageShowBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/故障_白.png" Width="36" Height="36" />
+                        <TextBlock Text="故障页面" FontSize="10" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="AuditTrailShowBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="AuditTrailShowBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/审计信息审计_白.png" Width="36" Height="36" />
+                        <TextBlock Text="审计追踪" FontSize="10" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+                <Button x:Name="UserMessageBtn" HorizontalAlignment="Left" Height="60" Width="60" Background="{x:Null}" Click="UserMessageBtn_Click">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                        <Image  Source="/FromImage/用户管理_白.png" Width="32" Height="32" />
+                        <TextBlock Text="用户管理" FontSize="10" FontWeight="Bold" Margin="0,4,0,0" HorizontalAlignment="Center" Foreground="White" />
+                    </StackPanel>
+                </Button>
+            </StackPanel>
+            <Button Grid.Column="2" x:Name="KeyBoardBtn" Height="60" Background="{x:Null}" Click="KeyBoardBtn_Click">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/键盘_白.png" Width="40" Height="40" />
+                    <TextBlock Text="键盘" FontSize="10" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" Foreground="White" />
+                </StackPanel>
+            </Button>
+            <Image Grid.Column="3" x:Name="LogoImage" Source="/FromImage/mmexport1752891278116.jpg" Margin="0,0,0,0" Height="60" Width="60" HorizontalAlignment="Right" />
+        </Grid>
+        <Frame x:Name="ShowFrame" Margin="0,60,0,55" NavigationUIVisibility="Hidden" Grid.ColumnSpan="2"/>
+        <Grid VerticalAlignment="Bottom" Height="40" Margin="0,0,0,5" Grid.ColumnSpan="2">
+            <Border
+            Background="#FF1200D1" 
+            CornerRadius="8"
+            BorderBrush="Gray"
+            BorderThickness="1"
+            Margin="10,0,10,0" VerticalAlignment="Bottom" Height="40">
+                <StackPanel Orientation="Horizontal">
+                    <Label x:Name="CPUMonitorLab" Content="{Binding CPUMonitor}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Margin="30,8,0,0" Width="80" FontSize="10" FontWeight="Bold" Foreground="White"></Label>
+                    <Label x:Name="RamMonitorLab" Content="{Binding RamMonitor}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Margin="20,8,0,0" Width="120" FontSize="10" FontWeight="Bold" Foreground="White"></Label>
+                </StackPanel>
+            </Border>
+            <Label x:Name="ErrMessageLab" Content="{Binding ShowErrMessage}" HorizontalAlignment="Right" Foreground="Red" Width="400" Height="30" Margin="0,0,30,0" />
+        </Grid>
+    </Grid>
+</Window>

+ 654 - 0
WpfSwitchLanguage/WpfFrom/MainWindow.xaml.cs

@@ -0,0 +1,654 @@
+using CCDCount.DLL;
+using CCDCount.DLL.Tools;
+using CCDCount.MODEL.CameraClass;
+using CCDCount.MODEL.ConfigModel;
+using CCDCount.MODEL.SqlDataModel;
+using LogClass;
+using MvCameraControl;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media.Imaging;
+using System.Xml.Serialization;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar;
+
+namespace CCDCountWpf
+{
+    /// <summary>
+    /// MainWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        #region 变量与实例
+        Uri ShowUri = null;
+        List<SaveConfigModel> Configs = null;
+        bool IsShow = false;
+        SystemMonitor monitor = new SystemMonitor();
+        Stopwatch SystemRunTime = new Stopwatch();
+        long InitRunTime;
+        #endregion
+
+        #region 窗体事件
+        /// <summary>
+        /// 主窗体构造函数
+        /// </summary>
+        public MainWindow()
+        {
+            LOG.log("程序正在加载主界面", 6);
+            InitializeComponent();
+            LOG.log("正在开启系统运行时间程序", 6);
+            //StartSystemRunTime();
+            SetupFullScreen();
+            LOG.log("绑定界面数据中", 6);
+            DataContext = ShowMessageBus.ShowBinding;
+            LOG.log("加载配置参数中", 6);
+            if (File.Exists(".\\Config\\CCDCountConfig.xml"))
+            {
+                Configs = XmlStorage.DeserializeFromXml<List<SaveConfigModel>>(".\\Config\\CCDCountConfig.xml");
+            }
+            LOG.log("初始化引用库", 6);
+            SDKSystem.Initialize();
+            FaultLog.FaultError += ShowErrorMesPage;
+            LOG.log("初始化相机中", 6);
+            InitCameraIdentify();
+            LOG.log("启动界面更新线程中", 6);
+            StartUpdataShowDataThread();
+            LOG.log("相机列表显示", 6);
+            InitCamComboboxValue();
+            LOG.log("初始化PLC参数管理功能", 6);
+            InitPlcManger();
+            LOG.log("更新数据界面参数展示", 6);
+            UpdatePlcPara();
+        }
+
+
+        private void Window_Loaded(object sender, RoutedEventArgs e)
+        {
+            MainPageBtn_Click(null, null);
+        }
+
+        /// <summary>
+        /// 退出按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ExitBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (MessageBox.Show("是否退出程序?", "退出确认", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+            {
+                this.Close();
+            }
+            else
+            {
+                return;
+            }
+        }
+
+        /// <summary>
+        /// 主界面按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void MainPageBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ShowUri = new Uri("WpfPage\\MainPage.xaml", UriKind.Relative);
+            ShowFrame.Navigate(ShowUri);
+        }
+
+        private void SettingBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ShowUri = new Uri("WpfPage\\SettingPage.xaml", UriKind.Relative);
+            ShowFrame.Navigate(ShowUri);
+        }
+
+        private void ErrorMessageShowBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ShowUri = new Uri("WpfPage\\MessagePage.xaml", UriKind.Relative);
+            ShowFrame.Navigate(ShowUri);
+        }
+
+        private void PlcSettingBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                ShowUri = new Uri("WpfPage\\PlcSettingPage.xaml", UriKind.Relative);
+                ShowFrame.Navigate(ShowUri);
+            }
+            else
+            {
+                var MessageResult = MessageBox.Show("尚未连接PLC,是否重连","重连确认",MessageBoxButton.YesNo);
+                if(MessageResult == MessageBoxResult.Yes)
+                {
+                    InitPlcManger();
+                    if (PlcSettingMessageBus.pLCManagement.IsConnect)
+                    {
+                        UpdatePlcPara(); 
+                        ShowUri = new Uri("WpfPage\\PlcSettingPage.xaml", UriKind.Relative);
+                        ShowFrame.Navigate(ShowUri);
+                    }
+                    else
+                    {
+                        MessageBox.Show("连接PLC失败,请检查PLC状态");
+                    }
+                }
+            }
+        }
+
+        private void HistoryDataBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ShowUri = new Uri("WpfPage\\HistoryDataPage.xaml", UriKind.Relative);
+            ShowFrame.Navigate(ShowUri);
+        }
+
+        private void UserMessageBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (MessageBus.NowLoginUserMessage != null)
+            {
+                if (!MessageBus.NowLoginUserMessage.IsAdmin)
+                {
+                    MessageBox.Show("权限不足");
+                }
+                else
+                {
+                    ShowUri = new Uri("WpfPage\\UserManagementPage.xaml", UriKind.Relative);
+                    ShowFrame.Navigate(ShowUri);
+                }
+            }
+            else
+            {
+                MessageBox.Show("请先登录");
+            }
+        }
+
+        /// <summary>
+        /// 窗体关闭事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+        {
+            StopSystemRunTime();
+            SaveConfig();
+            SDKSystem.Finalize();
+            if (MessageBus.NowSettingLoadMainThread != null)
+            {
+                MessageBus.NowSettingLoadMainThread.DisposeCamera();
+            }
+            StopUpdataShowDataThread();
+            FaultLog.FaultError -= ShowErrorMesPage;
+            Environment.Exit(0);
+        }
+        #endregion
+
+        #region 私有方法
+        private void InitCameraIdentify()
+        {
+            if (Configs.Count == 0)
+            {
+                MessageBox.Show("尚未添加相机,请前往配置页面配置相机");
+                return;
+            }
+            if (MessageBus.NowSettingLoadMainThread != null)
+            {
+                MessageBus.NowSettingLoadMainThread.StopMianThread();
+            }
+
+            MessageBus.NowSettingLoadMainThread = (new MainThreadClass(Configs[0].ShuLiConfigClass, Configs[0].CameraConfig));
+
+            MessageBus.NowSettingLoadMainThread.FormulationName = Configs[0].ConfigName;
+            MessageBus.NowSettingLoadMainThread.IsLoadFormulation = Configs[0].IsFormulation;
+            //MessageBus.MainThreadS[i].ConnectModbus("127.0.0.1");
+            MessageBus.NowSettingLoadMainThread.ConnectModbus("192.168.0.88");
+            MessageBus.NowSettingLoadMainThread.LoadCamera();
+        }
+
+        /// <summary>
+        ///  启动更新显示数据线程
+        /// </summary>
+        private  void StartUpdataShowDataThread()
+        {
+            IsShow = true;
+            BitmapImage ThumbnailImage1 = null;
+            const int targetMsPerFrame = 100; // 20FPS=50ms
+            Stopwatch renderSW = new Stopwatch();
+            Stopwatch HeartSW = new Stopwatch();
+            Task.Run(async () =>
+            {
+                while (IsShow)
+                {
+                    renderSW.Restart();
+                    await Task.Run(() =>
+                    {
+                        UpdataShuLiShowData();
+                        UpdateMonitorMessage();
+                        UpdateFaultLogMessage();
+                    });
+                    await Application.Current.Dispatcher.InvokeAsync(() =>
+                    {
+                        if (MessageBus.NowSettingLoadMainThread == null)
+                        {
+                            LOG.log(string.Format("{0}:当前未加载识别流程", "IdentifyCameraForm-StartShowImageThread"));
+                            Thread.Sleep(100);
+                            return;
+                        }
+                        else
+                        {
+                            MessageBus.NowSettingLoadMainThread.GetShowImage(1000, out Bitmap image1);
+                            if (image1 == null)
+                            {
+                                LOG.log(string.Format("{0}:相机一获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
+                                return;
+                            }
+                            ThumbnailImage1 = ConvertToBitmapImage(image1);
+                            ShowMessageBus.ShowBinding.BitmapImage = ThumbnailImage1;
+                        }
+
+                        if (MessageBus.NowSettingLoadMainThread != null)
+                        {
+                            if (MessageBus.NowSettingLoadMainThread.IsDebug)
+                            {
+                                Bitmap Splicebitmap = MessageBus.NowSettingLoadMainThread.GetCamImageOnce();
+                                if (Splicebitmap != null)
+                                {
+                                    ShowMessageBus.ShowBinding.DebugImage = ConvertToBitmapImage(Splicebitmap);
+                                }
+                            }
+                            else
+                            {
+                                if (ThumbnailImage1 != null)
+                                {
+                                    ShowMessageBus.ShowBinding.DebugImage = ThumbnailImage1;
+                                }
+                            }
+                        }
+                    });
+                    //进行精准20帧控制
+                    int elapsed = (int)renderSW.ElapsedMilliseconds;
+                    //Console.WriteLine(elapsed);
+                    if (elapsed < targetMsPerFrame)
+                    {
+                        //Console.WriteLine($"主显示线程休眠,休眠时间:{targetMsPerFrame - elapsed}");
+                        Thread.Sleep(targetMsPerFrame - elapsed);
+                    }
+                    //Thread.Sleep(50);
+                }
+            });
+            Task.Run(async () =>
+            {
+                while (true)
+                {
+                    HeartSW.Restart();
+                    //if (MessageBus.NowSettingLoadMainThread == null) continue;
+                    //    if (MessageBus.NowSettingLoadMainThread.CameraRunStatic && MessageBus.NowSettingLoadMainThread.CameraSendMessageStatic)
+                    //    {
+                    //        PlcSettingMessageBus.pLCManagement.HeartMessage();
+                    //    }
+                    if(PlcSettingMessageBus.pLCManagement!=null)
+                    {
+                        PlcSettingMessageBus.pLCManagement.HeartMessage();
+                    }
+                    HeartSW.Stop();
+                    int elapsed = (int)HeartSW.ElapsedMilliseconds;
+                    if (elapsed < targetMsPerFrame)
+                    {
+                        await Task.Delay(500 - elapsed);
+                    }
+                }
+            });
+        }
+
+        /// <summary>
+        ///  停止更新显示数据线程
+        /// </summary>
+        private void StopUpdataShowDataThread()
+        {
+            IsShow = false;
+        }
+
+        /// <summary>
+        /// 更新数粒显示数据
+        /// </summary>
+        private void UpdataShuLiShowData()
+        {
+            if (MessageBus.NowSettingLoadMainThread == null) return;
+            if (MessageBus.NowSettingLoadMainThread.ShuLiState)
+            {
+                Application.Current.Dispatcher.Invoke(() =>
+                {
+                    ShowMessageBus.ShowBinding.CameraStaticColor = MessageBus.NowSettingLoadMainThread.CameraRunStatic == true
+                        ? System.Windows.Media.Brushes.Green : System.Windows.Media.Brushes.Red;
+                    ShowMessageBus.ShowBinding.CamRunStatic = MessageBus.NowSettingLoadMainThread.CameraRunStatic == true 
+                        ? "运行中" : "未运行";
+                });
+            }
+            else
+            {
+                Application.Current.Dispatcher.Invoke(() =>
+                {
+
+                    ShowMessageBus.ShowBinding.CameraStaticColor = System.Windows.Media.Brushes.Yellow;
+                    ShowMessageBus.ShowBinding.CamRunStatic = "视野遮挡";
+                });
+            }
+            ShowMessageBus.ShowBinding.AllActiveNum = MessageBus.NowSettingLoadMainThread.HistoryActiveNum.ToString();
+            ShowMessageBus.ShowBinding.AllOkNum = MessageBus.NowSettingLoadMainThread.OkHistoryNum.ToString();
+            ShowMessageBus.ShowBinding.AllNgNum = MessageBus.NowSettingLoadMainThread.NgHistoryNum.ToString();
+            ShowMessageBus.ShowBinding.ShuLiSpeed = MessageBus.NowSettingLoadMainThread.GetOneSecondActiveNum().ToString();
+            PlcSettingMessageBus.pLCManagement.ReadBottingCount(out ushort BottingCount);
+            ShowMessageBus.ShowBinding.BottingCountSpeed = PlcSettingMessageBus.pLCManagement.BottingSpeed.ToString();
+            ShowMessageBus.ShowBinding.BottingCount = BottingCount;
+        }
+
+        /// <summary>
+        /// 更新监控信息
+        /// </summary>
+        private void UpdateMonitorMessage()
+        {
+            ShowMessageBus.ShowBinding.RamMonitor = monitor.GetAvailableMemory() > 1024 ? $"可用内存: {monitor.GetAvailableMemory() / 1024:0.00}GB" : $"可用内存: {monitor.GetAvailableMemory()}MB";
+            ShowMessageBus.ShowBinding.CPUMonitor = $"CPU: {monitor.GetCpuUsage():0.00}%";
+        }
+
+        /// <summary>
+        /// 更新故障日志信息
+        /// </summary>
+        private void UpdateFaultLogMessage()
+        {
+            ShowMessageBus.ShowBinding.ErrMessageShowList = FaultLog.GetAllErrMessage();
+        }
+
+        // Bitmap 转 BitmapImage 的辅助方法
+        private BitmapImage ConvertToBitmapImage(Bitmap bitmap)
+        {
+            using (MemoryStream memory = new MemoryStream())
+            {
+                bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
+                memory.Position = 0;
+                var bitmapImage = new BitmapImage();
+                bitmapImage.BeginInit();
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+                bitmapImage.DecodePixelWidth = 1200; // 设置目标分辨率宽度
+                bitmapImage.DecodePixelHeight = 600; // 保持宽高比
+                bitmapImage.StreamSource = memory;
+                bitmapImage.EndInit();
+                return bitmapImage;
+            }
+        }
+
+        /// <summary>
+        /// 初始化相机选择框
+        /// </summary>
+        private void InitCamComboboxValue()
+        {
+            MessageBus.CameraClass.GetCameraList(out List<CameraInfoClass> CameraInfoList);
+            if (CameraInfoList.Count > 0)
+            {
+                ShowMessageBus.ShowBinding.CameraItems.Clear();
+                ShowMessageBus.ShowBinding.CameraItems.Add(new CameraCoboxItem() { Name = "请选择相机", SNValue = "" });
+                foreach (var item in CameraInfoList)
+                {
+                    ShowMessageBus.ShowBinding.CameraItems.Add(new CameraCoboxItem()
+                    {
+                        Name = item.DeviceName + "_" + item.DeviceSN,
+                        SNValue = item.DeviceSN
+                    });
+                }
+            }
+        }
+
+        /// <summary>
+        /// FaultLog的报警回调方法
+        /// </summary>
+        /// <param name="e"></param>
+        private void ShowErrorMesPage(ErrorMesDataEventModelClass e)
+        {
+            ShowMessageBus.ShowBinding.ShowErrMessage = e.ErrorMesData.Message;
+            //MessageBox.Show(e.ErrorMesData.Message);
+        }
+
+        /// <summary>
+        /// 保存配置
+        /// </summary>
+        private void SaveConfig()
+        {
+            List<SaveConfigModel> SaveConfig = new List<SaveConfigModel>();
+            if (MessageBus.NowSettingLoadMainThread == null)
+            {
+                return;
+            }
+            SaveConfig.Add(new SaveConfigModel()
+            {
+                CameraConfig = MessageBus.NowSettingLoadMainThread.cameraConfig,
+                ShuLiConfigClass = MessageBus.NowSettingLoadMainThread.shuLiConfig,
+                IsFormulation = MessageBus.NowSettingLoadMainThread.IsLoadFormulation,
+                ConfigName = MessageBus.NowSettingLoadMainThread.FormulationName
+            });
+            if (!Directory.Exists(".\\Config\\")) Directory.CreateDirectory(".\\Config\\");
+            {
+                XmlStorage.SerializeToXml(SaveConfig, ".\\Config\\CCDCountConfig.xml");
+            }
+        }
+
+        /// <summary>
+        /// 初始化PLC管理(包括PLC的数据信息更新线程)
+        /// </summary>
+        public void InitPlcManger()
+        {
+            //PlcSettingMessageBus.pLCManagement = new PLCManagementClass("127.0.0.1");
+            PlcSettingMessageBus.pLCManagement = new PLCManagementClass("192.168.0.88");
+        }
+
+        private void UpdatePlcPara()
+        {
+            var ParaValue = PlcSettingMessageBus.pLCManagement.ReadAllPara();
+            if (ParaValue == null) return;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingModel =
+                ParaValue.FillingMode;
+            PlcSettingMessageBus.PlcMessageShowBindage.BeltsSpeed =
+                ParaValue.BeltsSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed =
+                ParaValue.ShakeTable1H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed =
+                ParaValue.ShakeTable2H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed =
+                ParaValue.ShakeTable3H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed =
+                ParaValue.ShakeTable1M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed =
+                ParaValue.ShakeTable2M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed =
+                ParaValue.ShakeTable3M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed =
+                ParaValue.ShakeTable1L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed =
+                ParaValue.ShakeTable2L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed =
+                ParaValue.ShakeTable3L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed =
+                ParaValue.ShakeTable1H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed =
+                ParaValue.ShakeTable2H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed =
+                ParaValue.ShakeTable3H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed =
+                ParaValue.ShakeTable1M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed =
+                ParaValue.ShakeTable2M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed =
+                ParaValue.ShakeTable3M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed =
+                ParaValue.ShakeTable1L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed =
+                ParaValue.ShakeTable2L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed =
+                ParaValue.ShakeTable3L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio =
+                ParaValue.FillingH_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio =
+                ParaValue.FillingM_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio =
+                ParaValue.FillingL_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio =
+                ParaValue.CacheH_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio =
+                ParaValue.CacheM_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio =
+                ParaValue.CacheL_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed =
+                ParaValue.ScrewJogSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.InBottleSpeed =
+                ParaValue.InBottleSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.BottlePosSpeed =
+                ParaValue.BottlePosSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.BottlePosPosition = 
+                ParaValue.BottlePosPosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed =
+                ParaValue.FillingValveOpenSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition =
+                ParaValue.FillingValveOpenPosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed =
+                ParaValue.FillingValveCloseSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition =
+                ParaValue.FillingValveClosePosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCacheSpeed =
+                ParaValue.FillingValveCacheSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCachePosition =
+                ParaValue.FillingValueCachePosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveJogSpeed =
+                ParaValue.FillingValueJogSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime =
+                ParaValue.MachineDelayFunneDownTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime =
+                ParaValue.MachineDelayFunneUpTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime =
+                ParaValue.MachineDelayFillingValveOpenTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime =
+                ParaValue.MachineDelayFillingValveCloseTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime =
+                ParaValue.MachineDelayInBottleTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet =
+                ParaValue.BottValueSet;
+            PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime = 
+                ParaValue.ValveDelytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue =
+                ParaValue.CacheShutdownValue;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed =
+                ParaValue.ShakeTable1_TestSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed =
+                ParaValue.ShakeTable2_TestSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed =
+                ParaValue.ShakeTable3_TestSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime =
+                ParaValue.MissingDelaytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime =
+                ParaValue.BottleJamDelaytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime =
+                ParaValue.EliminateCylinderDelayTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime =
+                ParaValue.EliminateCylinderHoldingTime;
+        }
+
+        private void StartSystemRunTime()
+        {
+            string localDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+            string systemRunTimePath = Path.Combine(localDataPath, "CCDCount\\SystemRunTime.XML");
+            if (File.Exists(systemRunTimePath))
+            {
+                var systemMessage = XmlStorage.DeserializeFromXml<SystemMessageConfigModel>(systemRunTimePath);
+                InitRunTime = systemMessage.SystemRunTime;
+                TimeSpan timeSpan = TimeSpan.FromTicks(InitRunTime);
+            }
+            SystemRunTime.Start();
+        }
+
+        private void StopSystemRunTime()
+        {
+            string localDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+            string systemruntimefoundPath = Path.Combine(localDataPath, "CCDCount");
+            if (!Directory.Exists(systemruntimefoundPath))
+            {
+                Directory.CreateDirectory(systemruntimefoundPath);
+            }
+            string systemRunTimePath = Path.Combine(systemruntimefoundPath, "SystemRunTime.XML");
+            SystemRunTime.Stop();
+            long ticks = SystemRunTime.ElapsedTicks;
+            XmlStorage.SerializeToXml(new SystemMessageConfigModel()
+            {
+                SystemRunTime = ticks + InitRunTime
+            }, systemRunTimePath);
+        }
+
+        private void SetupFullScreen()
+        {
+            // 隐藏标题栏和边框
+            this.WindowStyle = WindowStyle.None;
+
+            // 禁止调整大小
+            this.ResizeMode = ResizeMode.NoResize;
+
+            // 设置为最顶层窗口
+            //this.Topmost = true;
+
+            // 最大化窗口
+            this.WindowState = WindowState.Maximized;
+
+            // 隐藏任务栏(可选)
+            this.Top = 0;
+            this.Left = 0;
+            this.Width = SystemParameters.PrimaryScreenWidth;
+            this.Height = SystemParameters.PrimaryScreenHeight;
+        }
+
+        #endregion
+
+        private void MenuBtn_Click(object sender, RoutedEventArgs e)
+        {
+            HeardPanel.Visibility = HeardPanel.Visibility == Visibility.Visible?Visibility.Hidden:Visibility.Visible;
+        }
+
+        private void KeyBoardBtn_Click(object sender, RoutedEventArgs e)
+        {
+            OnScreenKeyboard.KeyBoardShow();
+        }
+
+        private void PlcOperationBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                ShowUri = new Uri("WpfPage\\PlcOperationPage.xaml", UriKind.Relative);
+                ShowFrame.Navigate(ShowUri);
+            }
+            else
+            {
+                var MessageResult = MessageBox.Show("尚未连接PLC,是否重连", "重连确认", MessageBoxButton.YesNo);
+                if (MessageResult == MessageBoxResult.Yes)
+                {
+                    InitPlcManger();
+                    if (PlcSettingMessageBus.pLCManagement.IsConnect)
+                    {
+                        UpdatePlcPara();
+                        ShowUri = new Uri("WpfPage\\PlcOperationPage.xaml", UriKind.Relative);
+                        ShowFrame.Navigate(ShowUri);
+                    }
+                    else
+                    {
+                        MessageBox.Show("连接PLC失败,请检查PLC状态");
+                    }
+                }
+            }
+        }
+
+        private void AuditTrailShowBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ShowUri = new Uri("WpfPage\\AuditTrailPage.xaml", UriKind.Relative);
+            ShowFrame.Navigate(ShowUri);
+        }
+    }
+}

+ 18 - 0
WpfSwitchLanguage/WpfFrom/SplashWindow.xaml

@@ -0,0 +1,18 @@
+<Window x:Class="CCDCountWpf.SplashWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CCDCountWpf"
+        mc:Ignorable="d"
+        Title="SplashWindow" Height="450" Width="800" 
+        WindowStyle="None" AllowsTransparency="True"
+        Background="Transparent" WindowStartupLocation="CenterScreen" Icon="/FromImage/mmexport1752891278116.jpg">
+    <Grid Background="White">
+        <TextBlock Text="翰林航宇视觉数粒系统" HorizontalAlignment="Center" 
+                           Foreground="#FF0072BF" FontSize="40" VerticalAlignment="Top" Cursor="Arrow" Margin="0,20,0,0"/>
+        <Image Source="/FromImage/mmexport1752891278116.jpg" Stretch="Fill" Width="200" Height="200" Cursor="Arrow"/>
+        <TextBlock Text="程序启动中" HorizontalAlignment="Right" Margin="0,0,60,20" 
+                           Foreground="#FF0072BF" FontSize="40" VerticalAlignment="Bottom" Cursor="Arrow"/>
+    </Grid>
+</Window>

+ 27 - 0
WpfSwitchLanguage/WpfFrom/SplashWindow.xaml.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf
+{
+    /// <summary>
+    /// SplashWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class SplashWindow : Window
+    {
+        public SplashWindow()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 68 - 0
WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml

@@ -0,0 +1,68 @@
+<Window x:Class="CCDCountWpf.UserLoginWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CCDCountWpf"
+        mc:Ignorable="d"
+        Title="UserLoginWindow" Height="300" Width="450"
+        WindowStyle="None" AllowsTransparency="True"
+        WindowStartupLocation="CenterScreen" Icon="/FromImage/mmexport1752891278116.jpg" KeyDown="Window_KeyDown">
+    <Grid Background="#B2E0E0E0">
+        <Grid VerticalAlignment="Top" Height="60" Background="#FF1200D1">
+            <Border BorderBrush="Black" BorderThickness="1"/>
+            <Label Content="用户登录" Foreground="White" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+            <Button x:Name="KeyBoardBtn" Height="60" Background="{x:Null}" Click="KeyBoardBtn_Click" Width="60" HorizontalAlignment="Right">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/键盘_白.png" Width="40" Height="40" />
+                    <TextBlock Text="键盘" FontSize="10" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" Foreground="White" />
+                </StackPanel>
+            </Button>
+        </Grid>
+        <Border  Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="80,120,80,0" Height="155" VerticalAlignment="Top">
+            <StackPanel Orientation="Vertical">
+                <StackPanel Orientation="Horizontal" Height="95">
+                    <StackPanel Orientation="Vertical" Margin="30,0,0,0">
+                        <Label  Content="用户名:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                        <Label  Content="密码:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical">
+                        <TextBox x:Name="UserNameTbx" HorizontalAlignment="Left" Margin="0,15,0,0"  Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}" GotFocus="UserNameTbx_GotFocus"/>
+                        <PasswordBox x:Name="UserPassTbx"  HorizontalAlignment="Left" Margin="0,17,0,0" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" Background="{x:Null}" GotFocus="UserPassTbx_GotFocus"  />
+                    </StackPanel>
+                </StackPanel>
+                <StackPanel Orientation="Horizontal">
+                    <Button x:Name="UserLoginBtn" Content="登录" BorderThickness="1" HorizontalAlignment="Left" Margin="50,10,10,0" VerticalAlignment="Top" Width="80" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="UserLoginBtn_Click" Cursor="Hand">
+                        <Button.Template>
+                            <ControlTemplate TargetType="Button">
+                                <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                </Border>
+                            </ControlTemplate>
+                        </Button.Template>
+                    </Button>
+                    <Button x:Name="UserCancelBtn" Content="取消" BorderThickness="1" HorizontalAlignment="Left" Margin="10,10,10,0" VerticalAlignment="Top" Width="80" Height="40" Background="#B20123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="UserCancelBtn_Click" Cursor="Hand">
+                        <Button.Template>
+                            <ControlTemplate TargetType="Button">
+                                <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                </Border>
+                            </ControlTemplate>
+                        </Button.Template>
+                    </Button>
+                </StackPanel>
+            </StackPanel>
+            <!-- 卡片内容 -->
+        </Border>
+    </Grid>
+</Window>

+ 78 - 0
WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml.cs

@@ -0,0 +1,78 @@
+using CCDCount.DLL;
+using CCDCount.DLL.Tools;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf
+{
+    /// <summary>
+    /// UserLoginWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class UserLoginWindow : Window
+    {
+        public UserLoginWindow()
+        {
+            InitializeComponent();
+        }
+
+        private void UserLoginBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(!MessageBus.UserMessageClass.CheckUserLogin(UserNameTbx.Text, UserPassTbx.Password))
+            {
+                MessageBox.Show("用户名或密码错误!");
+                return;
+            }
+            MessageBus.NowLoginUserMessage = MessageBus.UserMessageClass.GetUserMessageForName(UserNameTbx.Text)[0];
+            FaultLog.SetUserID(MessageBus.NowLoginUserMessage.Id);
+            SplashWindow splash = new SplashWindow();
+            splash.Show();
+            this.Close();
+
+            MainWindow mainWindow = new MainWindow();
+            mainWindow.Show();
+            splash.Close();
+        }
+
+        private void UserCancelBtn_Click(object sender, RoutedEventArgs e)
+        {
+            this.Close();
+            Environment.Exit(0);
+        }
+
+        private void Window_KeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key == Key.Enter)
+            {
+                // 触发目标按钮的点击事件
+                UserLoginBtn.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
+                e.Handled = true; // 标记事件已处理
+            }
+        }
+
+        private void UserNameTbx_GotFocus(object sender, RoutedEventArgs e)
+        {
+            //OnScreenKeyboard.Show();
+        }
+
+        private void UserPassTbx_GotFocus(object sender, RoutedEventArgs e)
+        {
+            //OnScreenKeyboard.Show();
+        }
+
+        private void KeyBoardBtn_Click(object sender, RoutedEventArgs e)
+        {
+            OnScreenKeyboard.KeyBoardShow();
+        }
+    }
+}

+ 81 - 0
WpfSwitchLanguage/WpfPage/AuditTrailPage.xaml

@@ -0,0 +1,81 @@
+<Page x:Class="CCDCountWpf.WpfPage.AuditTrailPage"
+      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:CCDCountWpf.WpfPage" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
+      mc:Ignorable="d" 
+      d:DesignHeight="450" d:DesignWidth="800"
+      Title="AuditTrailPage">
+
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="40" />
+            <RowDefinition Height="*" />
+        </Grid.RowDefinitions>
+        <Grid Grid.Row="0">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*" />
+                <ColumnDefinition Width="*" />
+                <ColumnDefinition Width="*" />
+                <ColumnDefinition Width="*" />
+            </Grid.ColumnDefinitions>
+            <Button x:Name="BatchRecordBtn" Content="批记录" Grid.Column="0" Click="BatchRecordBtn_Click"></Button>
+            <Button x:Name="FormulationRecordBtn" Content="生产配方记录" Grid.Column="1" Click="FormulationRecordBtn_Click"></Button>
+            <Button x:Name="ValueChangeRecordBtd" Content="参数修改记录" Grid.Column="2" Click="ValueChangeRecordBtd_Click"></Button>
+            <Button x:Name="ErrorRecordBtn" Content="异常记录" Grid.Column="3" Click="ErrorRecordBtn_Click"></Button>
+        </Grid>
+        <Grid Grid.Row="1">
+            <Grid x:Name="BatchRecordGrid" Visibility="Visible">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="50" />
+                    <RowDefinition Height="*" />
+                </Grid.RowDefinitions>
+                <Label Content="日期筛选:" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0" />
+                <DatePicker x:Name="BatchMinTime" Width="120" Height="25"  HorizontalAlignment="Left" VerticalAlignment="Center" SelectedDateChanged="BatchMinTime_SelectedDateChanged" Margin="65,0,0,0"/>
+                <Label Content="-" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="190,0,0,0" />
+                <DatePicker x:Name="BatchMaxTime" Width="120" Height="25"  HorizontalAlignment="Left" Margin="210,0,0,0" VerticalAlignment="Center" SelectedDateChanged="BatchMaxTime_SelectedDateChanged"/>
+                <Label Content="记录间隔:" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,350,0" />
+                <ComboBox x:Name="TimeIntervalComBox" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,270,0" Width="80" SelectionChanged="TimeIntervalComBox_SelectionChanged" />
+                <Label Content="批次选择:" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,200,0" />
+                <ComboBox Grid.Row="0" x:Name="BatchNumComBox" ItemsSource="{Binding BatchItems}" MaxDropDownHeight="100" Background="{x:Null}" HorizontalAlignment="Right" VerticalAlignment="Center" Height="30" Width="180" FontSize="12" HorizontalContentAlignment="Center" Padding="6,6,5,3" Margin="0,0,10,0" SelectionChanged="BatchNumComBox_SelectionChanged"/>
+                <wpf:WebView2 x:Name="BatchRecordWebBrowser" Grid.Row="1" />
+            </Grid>
+            <Grid x:Name="FormulationRecordGrid" Visibility="Collapsed">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="50" />
+                    <RowDefinition Height="*" />
+                </Grid.RowDefinitions>
+                <Label Content="配方选择:" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,200,0" />
+                <ComboBox Grid.Row="0" x:Name="FormulationRecordComBox" ItemsSource="{Binding FormulationItems}" MaxDropDownHeight="100" Background="{x:Null}" HorizontalAlignment="Right" VerticalAlignment="Center" Height="30" Width="180" FontSize="12" HorizontalContentAlignment="Center" Padding="6,6,5,3" Margin="0,0,10,0" SelectionChanged="FormulationRecordComBox_SelectionChanged"/>
+                <wpf:WebView2 x:Name="FormulationRecordWebBrowser" Grid.Row="1" />
+            </Grid>
+            <Grid x:Name="ValueChangeRecordGrid" Visibility="Collapsed">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="50" />
+                    <RowDefinition Height="*" />
+                </Grid.RowDefinitions>
+                <Label Content="日期筛选:" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0" />
+                <DatePicker x:Name="ValueChangeRecordMinTime" Width="120" Height="25"  HorizontalAlignment="Left" VerticalAlignment="Center" SelectedDateChanged="ValueChangeRecordMinTime_SelectedDateChanged" Margin="65,0,0,0"/>
+                <Label Content="-" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="190,0,0,0" />
+                <DatePicker x:Name="ValueChangeRecordMaxTime" Width="120" Height="25"  HorizontalAlignment="Left" Margin="210,0,0,0" VerticalAlignment="Center" SelectedDateChanged="ValueChangeRecordMaxTime_SelectedDateChanged"/>
+                <Label Content="日期选择:" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,200,0" />
+                <ComboBox Grid.Row="0" x:Name="ValueChangeDateComBox" ItemsSource="{Binding ValueChangeItems}" MaxDropDownHeight="100" Background="{x:Null}" HorizontalAlignment="Right" VerticalAlignment="Center" Height="30" Width="180" FontSize="12" HorizontalContentAlignment="Center" Padding="6,6,5,3" Margin="0,0,10,0" SelectionChanged="ValueChangeRecordComBox_SelectionChanged"/>
+                <wpf:WebView2 x:Name="ValueChangeRecordWebBrowser" Grid.Row="1" />
+            </Grid>
+            <Grid x:Name="ErrorRecordGrid" Visibility="Collapsed">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="50" />
+                    <RowDefinition Height="*" />
+                </Grid.RowDefinitions>
+                <Label Content="日期筛选:" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0" />
+                <DatePicker x:Name="ErrorMessageRecordMinTime" Width="120" Height="25"  HorizontalAlignment="Left" VerticalAlignment="Center" SelectedDateChanged="ErrorMessageRecordMinTime_SelectedDateChanged" Margin="65,0,0,0"/>
+                <Label Content="-" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="190,0,0,0" />
+                <DatePicker x:Name="ErrorMessageRecordMaxTime" Width="120" Height="25"  HorizontalAlignment="Left" Margin="210,0,0,0" VerticalAlignment="Center" SelectedDateChanged="ErrorMessageRecordMaxTime_SelectedDateChanged"/>
+                <Label Content="日期选择:" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,200,0" />
+                <ComboBox Grid.Row="0" x:Name="ErrorMessageDateComBox" ItemsSource="{Binding ErrorMessItems}" MaxDropDownHeight="100" Background="{x:Null}" HorizontalAlignment="Right" VerticalAlignment="Center" Height="30" Width="180" FontSize="12" HorizontalContentAlignment="Center" Padding="6,6,5,3" Margin="0,0,10,0" SelectionChanged="ErrorMessageRecordComBox_SelectionChanged"/>
+                <wpf:WebView2 x:Name="ErrorMessageRecordWebBrowser" Grid.Row="1" />
+            </Grid>
+        </Grid>
+    </Grid>
+</Page>

+ 955 - 0
WpfSwitchLanguage/WpfPage/AuditTrailPage.xaml.cs

@@ -0,0 +1,955 @@
+using CCDCount.DLL.AuditTrail;
+using CCDCount.DLL.SqlDataClass;
+using CCDCount.DLL.Tools;
+using CCDCount.MODEL.AuditTrailModel;
+using CCDCount.MODEL.ConfigModel;
+using LogClass;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// AuditTrailPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class AuditTrailPage : Page
+    {
+        #region 实例
+        /// <summary>
+        /// 批次信息数据类
+        /// </summary>
+        BatchMessSqliteDataClass batchMessSqliteData = null;
+        ErrorMesSqliteDataClass errorMesSqliteData = null;
+
+        // <summary>
+        /// 批次记录类(数据转PDF)
+        /// </summary>
+        BatchRecordClass batchRecord = new BatchRecordClass();
+
+        FormulationRecordClass formulationRecordClass = new FormulationRecordClass();
+
+        ValueChangeRecordClass ValueChangeRecordClass = new ValueChangeRecordClass();
+
+        ErrorMessageRecordClass errorMessageRecordClass = new ErrorMessageRecordClass();
+        #endregion
+
+        #region 变量
+        /// <summary>
+        /// 时间间隔
+        /// </summary>
+        int TimeInterval = 0;
+        string FormulationfolderPath = "";
+        #endregion
+
+        #region 窗口事件
+        /// <summary>
+        /// 构建方法
+        /// </summary>
+        public AuditTrailPage()
+        {
+            InitializeComponent();
+            this.Height = Double.NaN;
+            this.Width = Double.NaN;
+            DataContext = ShowMessageBus.ShowBinding;
+            try
+            {
+                LOG.log("初始化批次列表", 6);
+                InitBatchItems();
+                InitTimeIntervalComBox();
+                LOG.log("初始化配方列表", 6);
+                InitFormationItems();
+                LOG.log("初始化值更改列表", 6);
+                InitValueChangeItems();
+                LOG.log("初始化异常数据列表", 6);
+                InitErrorMessage();
+            }
+            catch(Exception ex) 
+            {
+                LOG.error(ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 批号时间筛选选择时间-最小时间
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void BatchMinTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (BatchMinTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (BatchMaxTime.SelectedDate == null)
+                {
+                    InitBatchItemsByMinTime((DateTime)BatchMinTime.SelectedDate);
+                }
+                else
+                {
+                    InitBatchItems((DateTime)BatchMinTime.SelectedDate, (DateTime)BatchMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 批号时间筛选选择时间-最大时间
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void BatchMaxTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (BatchMaxTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (BatchMinTime.SelectedDate == null)
+                {
+                    InitBatchItemsByMaxTime((DateTime)BatchMaxTime.SelectedDate);
+                }
+                else
+                {
+                    InitBatchItems((DateTime)BatchMinTime.SelectedDate, (DateTime)BatchMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 批号选择事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void BatchNumComBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (BatchNumComBox.SelectedItem == null || BatchNumComBox.SelectedItem.ToString() == "")
+            {
+                return;
+            }
+            if (TimeInterval == 0) return;
+            string LoadPath = GenerateBatchPDF();
+            BatchLoadPdf(LoadPath);
+        }
+
+        /// <summary>
+        /// 时间间隔选择事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void TimeIntervalComBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (TimeIntervalComBox.SelectedItem != null)
+            {
+                // 获取显示的文本
+                var selectedText = TimeIntervalComBox.Text;
+
+                // 获取选中的值
+                var selectedValue = Convert.ToInt32(TimeIntervalComBox.SelectedValue?.ToString());
+
+                TimeInterval = selectedValue;
+
+                if (BatchNumComBox.SelectedItem == null || BatchNumComBox.SelectedItem.ToString() == "")
+                {
+                    return;
+                }
+                if (TimeInterval == 0) return;
+                string LoadPath = GenerateBatchPDF();
+                BatchLoadPdf(LoadPath);
+            }
+        }
+
+        /// <summary>
+        /// 批号记录按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void BatchRecordBtn_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            BatchRecordGrid.Visibility = System.Windows.Visibility.Visible;
+            FormulationRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            ValueChangeRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            ErrorRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+        }
+
+        /// <summary>
+        /// 配方记录按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void FormulationRecordBtn_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            BatchRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            FormulationRecordGrid.Visibility = System.Windows.Visibility.Visible;
+            ValueChangeRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            ErrorRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+        }
+
+        /// <summary>
+        /// 值改变记录按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ValueChangeRecordBtd_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            BatchRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            FormulationRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            ValueChangeRecordGrid.Visibility = System.Windows.Visibility.Visible;
+            ErrorRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+        }
+
+        /// <summary>
+        /// 错误记录按钮点击事件
+        /// </summary>
+        private void ErrorRecordBtn_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            BatchRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            FormulationRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            ValueChangeRecordGrid.Visibility = System.Windows.Visibility.Collapsed;
+            ErrorRecordGrid.Visibility = System.Windows.Visibility.Visible;
+        }
+
+        /// <summary>
+        /// 配方选择事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void FormulationRecordComBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (FormulationRecordComBox.SelectedItem == null || FormulationRecordComBox.SelectedItem.ToString() == "")
+            {
+                return;
+            }
+            FormulationfolderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Formulations\\{FormulationRecordComBox.SelectedItem.ToString()}.xml";
+            string pdfFilePath = GenerateFormulationPDF();
+            FormulationLoadPdf(pdfFilePath);
+        }
+
+        /// <summary>
+        /// 值改变记录最小时间选择框选择事件
+        /// </summary>
+        private void ValueChangeRecordMinTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (ValueChangeRecordMinTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (ValueChangeRecordMaxTime.SelectedDate == null)
+                {
+                    InitValueChangeItemsByMinTime((DateTime)ValueChangeRecordMinTime.SelectedDate);
+                }
+                else
+                {
+                    InitValueChangeItems((DateTime)ValueChangeRecordMinTime.SelectedDate, (DateTime)ValueChangeRecordMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 值改变记录最大时间选择框选择事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ValueChangeRecordMaxTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (ValueChangeRecordMaxTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (ValueChangeRecordMinTime.SelectedDate == null)
+                {
+                    InitValueChangeItemsByMaxTime((DateTime)ValueChangeRecordMaxTime.SelectedDate);
+                }
+                else
+                {
+                    InitValueChangeItems((DateTime)ValueChangeRecordMinTime.SelectedDate, (DateTime)ValueChangeRecordMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 值改变记录选择框选择事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ValueChangeRecordComBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (ValueChangeDateComBox.SelectedItem == null || ValueChangeDateComBox.SelectedItem.ToString() == "")
+            {
+                return;
+            }
+            string LoadPath = GenerateValueChangePDF();
+            ValueChangeLoadPdf(LoadPath);
+        }
+
+        /// <summary>
+        /// 异常信息选择事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ErrorMessageRecordComBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (ErrorMessageDateComBox.SelectedItem == null || ErrorMessageDateComBox.SelectedItem.ToString() == "")
+            {
+                return;
+            }
+            string LoadPath = GenerateErrorMessagePDF();
+            ErrorMessageLoadPdf(LoadPath);
+        }
+
+        /// <summary>
+        /// 异常信息时间选择事件-最小时间
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ErrorMessageRecordMinTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (ErrorMessageRecordMinTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (ErrorMessageRecordMaxTime.SelectedDate == null)
+                {
+                    InitErrorMessageByMinTime((DateTime)ErrorMessageRecordMinTime.SelectedDate);
+                }
+                else
+                {
+                    InitErrorMessage((DateTime)ErrorMessageRecordMinTime.SelectedDate, (DateTime)ErrorMessageRecordMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 异常信息时间选择事件-最大时间
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ErrorMessageRecordMaxTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (ErrorMessageRecordMaxTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (ErrorMessageRecordMinTime.SelectedDate == null)
+                {
+                    InitErrorMessageByMaxTime((DateTime)ErrorMessageRecordMaxTime.SelectedDate);
+                }
+                else
+                {
+                    InitErrorMessage((DateTime)ErrorMessageRecordMinTime.SelectedDate, (DateTime)ErrorMessageRecordMaxTime.SelectedDate);
+                }
+            }
+        }
+        #endregion
+
+        #region 私有方法
+        /// <summary>
+        /// 初始化批次列表
+        /// </summary>
+        private void InitBatchItems()
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化批号列表
+        /// </summary>
+        private void InitBatchItems(DateTime Mintime, DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime && f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化批号列表
+        /// </summary>
+        private void InitBatchItemsByMinTime(DateTime Mintime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化批号列表
+        /// </summary>
+        private void InitBatchItemsByMaxTime(DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化时间间隔下拉框
+        /// </summary>
+        private void InitTimeIntervalComBox()
+        {
+            // 数据源
+            var items = new List<KeyValuePair<string, int>>
+            {
+                new KeyValuePair<string, int>("1秒", 1),
+                new KeyValuePair<string, int>("5秒", 5),
+                new KeyValuePair<string, int>("10秒", 10),
+                new KeyValuePair<string, int>("30秒",30),
+                new KeyValuePair<string, int>("1分", 60),
+                new KeyValuePair<string, int>("5分", 300),
+            };
+            TimeIntervalComBox.ItemsSource = items;
+            TimeIntervalComBox.DisplayMemberPath = "Key";
+            TimeIntervalComBox.SelectedValuePath = "Value";
+            TimeIntervalComBox.SelectedIndex = 0;
+        }
+
+        /// <summary>
+        /// 初始化配方列表
+        /// </summary>
+        private void InitFormationItems()
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Formulations";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 获取文件列表(包含子目录)
+                string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);
+                ShowMessageBus.ShowBinding.FormulationItems.Clear();
+                foreach (string file in files)
+                {
+                    ShowMessageBus.ShowBinding.FormulationItems.Add(Path.GetFileNameWithoutExtension(file));
+                }
+                if (ShowMessageBus.ShowBinding.FormulationName != null && ShowMessageBus.ShowBinding.FormulationName != string.Empty)
+                {
+                    try
+                    {
+                        FormulationRecordComBox.SelectedItem = ShowMessageBus.ShowBinding.FormulationName;
+                    }
+                    catch { }
+                }
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 生成批记录PDF
+        /// </summary>
+        /// <returns></returns>
+        private string GenerateBatchPDF()
+        {
+            string BatchNumber = BatchNumComBox.SelectedItem.ToString();
+            //string LoadPath = $"{AppDomain.CurrentDomain.BaseDirectory}PDF\\BatchData.PDF";
+            batchMessSqliteData = new BatchMessSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData\\BatchData_{BatchNumber}.db");
+            var batchMess = batchMessSqliteData.GetAllBatchMessage();
+            var ShowtableMessage = batchMess.Where((item, index) => index % TimeInterval == 0).ToList();
+            List<string> ColSpan = new List<string>()
+            {
+                "批次号",
+                "料筒震盘速度",
+                "过滤震台速度",
+                "计数震台速度",
+                "装瓶数量",
+                "装瓶速度",
+                "记录时间"
+            };
+            batchRecord.GetRecordLogo(Properties.Resources.Logo);
+            return batchRecord.BatchRecordToPDFReColspan(ShowtableMessage, ColSpan);
+        }
+
+        /// <summary>
+        /// 生成配方PDF
+        /// </summary>
+        /// <returns></returns>
+        private string GenerateFormulationPDF()
+        {
+            string BatchNumber = BatchNumComBox.SelectedItem.ToString();
+            FormulationConfigClass formulationConfigClass = null;
+            formulationConfigClass = XmlStorage.DeserializeFromXml<FormulationConfigClass>(FormulationfolderPath);
+            formulationRecordClass.GetRecordLogo(Properties.Resources.Logo);
+            List<string> RowSpanNames = new List<string>()
+            {
+                "配方名称",
+                "二值化阈值",
+                "允许物体中断的最大连续行数",
+                "合格物体的最长长度",
+                "合格物体的最短长度",
+                "判定标准识别码",
+                "合格物体的最大面积",
+                "合格物体的最小面积",
+                "噪声过滤阈值",
+                "通道数量",
+                "曝光时间",
+                "采集行频",
+                "设备名称",
+                "速度模式运行速度",
+                "点动速度",
+                "瓶装设定值",
+                "中转阀打开速度",
+                "中转阀打开时间",
+                "罐装减速值",
+                "缓存减速值",
+                "缓存计数延迟时间",
+                "缓存停机值",
+                "罐装料筒震台高速值",
+                "罐装过滤震台高速值",
+                "罐装计数震台高速值",
+                "罐装料筒震台减速值",
+                "罐装过滤震台减速值",
+                "罐装计数震台减速值",
+                "缓存料筒震台高速值",
+                "缓存过滤震台高速值",
+                "缓存计数震台高速值",
+                "缓存料筒震台减速值",
+                "缓存过滤震台减速值",
+                "缓存计数震台减速值",
+                "阀门打开延迟",
+                "回零偏移值",
+                "回零偏移速度",
+                "中转阀关闭速度",
+                "中转阀打开位置",
+                "中转阀关闭位置",
+                "气阀打开延迟",
+                "装瓶停机值",
+                "装瓶停机时间",
+                "送瓶轮运行速度",
+                "送瓶轮点动速度",
+                "送瓶轮回零偏移值",
+                "送瓶轮回零速度",
+                "送瓶轮位置长度",
+                "送瓶轮暂停时间",
+                "下料延时"
+            };
+            return formulationRecordClass.FormulationRecordToPDFReRowspan(formulationConfigClass, RowSpanNames);
+        }
+
+        /// <summary>
+        /// 加载PDF
+        /// </summary>
+        /// <param name="pdfFilePath"></param>
+        private async void BatchLoadPdf(string pdfFilePath)
+        {
+            // 加载 PDF 文件
+            await BatchRecordWebBrowser.EnsureCoreWebView2Async(null);
+            BatchRecordWebBrowser.CoreWebView2.Navigate(pdfFilePath);
+        }
+
+        /// <summary>
+        /// 加载PDF
+        /// </summary>
+        /// <param name="pdfFilePath"></param>
+        private async void FormulationLoadPdf(string pdfFilePath)
+        {
+            // 加载 PDF 文件
+            await FormulationRecordWebBrowser.EnsureCoreWebView2Async(null);
+            FormulationRecordWebBrowser.CoreWebView2.Navigate(pdfFilePath);
+        }
+
+        /// <summary>
+        /// 加载PDF
+        /// </summary>
+        /// <param name="pdfFilePath"></param>
+        private async void ValueChangeLoadPdf(string pdfFilePath)
+        {
+            // 加载 PDF 文件
+            await ValueChangeRecordWebBrowser.EnsureCoreWebView2Async(null);
+            ValueChangeRecordWebBrowser.CoreWebView2.Navigate(pdfFilePath);
+        }
+
+        /// <summary>
+        /// 加载PDF
+        /// </summary>
+        /// <param name="pdfFilePath"></param>
+        private async void ErrorMessageLoadPdf(string pdfFilePath)
+        {
+            // 加载 PDF 文件
+            await ErrorMessageRecordWebBrowser.EnsureCoreWebView2Async(null);
+            ErrorMessageRecordWebBrowser.CoreWebView2.Navigate(pdfFilePath);
+        }
+
+        /// <summary>
+        /// 初始化值更改列表
+        /// </summary>
+        private void InitValueChangeItems()
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ValueChangeItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ValueChangeItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ValueChangeDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitValueChangeItems(DateTime Mintime, DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime && f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ValueChangeItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ValueChangeItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ValueChangeDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitValueChangeItemsByMinTime(DateTime Mintime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ValueChangeItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ValueChangeItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ValueChangeDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitValueChangeItemsByMaxTime(DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ValueChangeItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ValueChangeItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ValueChangeDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 生成值更改记录PDF
+        /// </summary>
+        /// <returns></returns>
+        private string GenerateValueChangePDF()
+        {
+            string ValueChangeValue = ValueChangeDateComBox.SelectedItem.ToString();
+            errorMesSqliteData = new ErrorMesSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage\\FaultMessage_{ValueChangeValue}.db");
+            var ValueChangeMess = errorMesSqliteData.GetValueChangeMessage();
+            List<string> ColSpan = new List<string>()
+            {
+                "信息类别",
+                "信息类型",
+                "错误信息",
+                "记录时间",
+                "操作员ID",
+            };
+            ValueChangeRecordClass.GetRecordLogo(Properties.Resources.Logo);
+            return ValueChangeRecordClass.ValueChangeRecordToPDFReColspan(ValueChangeMess, ColSpan);
+            //return ValueChangeRecordClass.ValueChangeRecordToPDF(ValueChangeMess);
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitErrorMessage()
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ErrorMessItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ErrorMessItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ErrorMessageDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitErrorMessage(DateTime Mintime, DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime && f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ErrorMessItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ErrorMessItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ErrorMessageDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitErrorMessageByMinTime(DateTime Mintime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ErrorMessItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ErrorMessItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ErrorMessageDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化异常数据列表
+        /// </summary>
+        private void InitErrorMessageByMaxTime(DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.ErrorMessItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.ErrorMessItems.Add(Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                ErrorMessageDateComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 生成值更改记录PDF
+        /// </summary>
+        /// <returns></returns>
+        private string GenerateErrorMessagePDF()
+        {
+            string ValueChangeValue = ErrorMessageDateComBox.SelectedItem.ToString();
+            errorMesSqliteData = new ErrorMesSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\FaultMessage\\FaultMessage_{ValueChangeValue}.db");
+            var ValueChangeMess = errorMesSqliteData.GetErrorMessage();
+            List<string> ColSpan = new List<string>()
+            {
+                "信息类别",
+                "信息类型",
+                "错误信息",
+                "信息路径",
+                "记录时间",
+                "操作员ID",
+            };
+            errorMessageRecordClass.GetRecordLogo(Properties.Resources.Logo);
+            return errorMessageRecordClass.ErrorMessageRecordToPDFReColspan(ValueChangeMess, ColSpan);
+            //return ValueChangeRecordClass.ValueChangeRecordToPDF(ValueChangeMess);
+        }
+        #endregion
+    }
+}

+ 71 - 0
WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml

@@ -0,0 +1,71 @@
+<Page x:Class="CCDCountWpf.WpfPage.HistoryDataPage"
+      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:CCDCountWpf.WpfPage"
+      mc:Ignorable="d" 
+      d:DesignHeight="450" d:DesignWidth="800"
+      Title="HistoryDataPage">
+
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="60"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="60"/>
+        </Grid.RowDefinitions>
+        <Grid Grid.Row="0">
+            <Label Content="日期筛选:" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0" />
+            <DatePicker x:Name="BatchNumRecordMinTime" Width="120" Height="25"  HorizontalAlignment="Left" VerticalAlignment="Center" SelectedDateChanged="BatchNumRecordMinTime_SelectedDateChanged" Margin="65,0,0,0"/>
+            <Label Content="-" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="190,0,0,0" />
+            <DatePicker x:Name="BatchNumRecordMaxTime" Width="120" Height="25"  HorizontalAlignment="Left" Margin="210,0,0,0" VerticalAlignment="Center" SelectedDateChanged="BatchNumRecordMaxTime_SelectedDateChanged"/>
+            <Label Content="批次选择:" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,200,0" />
+            <ComboBox Grid.Row="0" x:Name="BatchNumComBox" ItemsSource="{Binding BatchItems}" MaxDropDownHeight="100" Background="{x:Null}" HorizontalAlignment="Right" VerticalAlignment="Center" Height="30" Width="180" FontSize="12" HorizontalContentAlignment="Center" Padding="6,6,5,3" Margin="0,0,10,0" SelectionChanged="BatchNumRecordComBox_SelectionChanged"/>
+        </Grid>
+        <Border Grid.Row="1" BorderBrush="Black" BorderThickness="1" Margin="2,2,2,2">
+            <Image x:Name="ShowBox" Source="{Binding HistoryImage}" Margin="0,0,0,0"/>
+        </Border>
+        <Border x:Name="PageChangeBorder" Grid.Row="2" Margin="2,2,2,2" VerticalAlignment="Center" HorizontalAlignment="Center" Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1">
+            <StackPanel Orientation="Horizontal">
+                <Button x:Name="PreviousBtn" Content="上一张" Height="40" Width="100" Margin="30,5,30,5" Click="PreviousBtn_Click" Padding="1,1,1,1" VerticalAlignment="Center" BorderThickness="1" Background="#FF0123FF" Foreground="White" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>              
+                <Label Content="第" FontSize="20" VerticalAlignment="Center" Foreground="White" />
+                <Label Content="{Binding HistoryImageNum}" FontSize="20" VerticalAlignment="Center" Foreground="White" />
+                <Label Content="张/共" FontSize="20" VerticalAlignment="Center" Foreground="White" />
+                <Label Content="{Binding HistoryImageCount}" FontSize="20" VerticalAlignment="Center" Foreground="White" />
+                <Label Content="张" FontSize="20" Margin="0,0,20,0" VerticalAlignment="Center" Foreground="White" />
+                <Label Content="跳转至" FontSize="20" VerticalAlignment="Center" Foreground="White" />
+                <TextBox x:Name="NowPageNumTbx" Text="{Binding HistoryImageNum}"  Height="40" Width="50" FontSize="20" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" VerticalAlignment="Center" Background="{x:Null}" Foreground="White" />
+                <Label Content="张" FontSize="20" Margin="0,0,5,0" VerticalAlignment="Center" Foreground="White" />
+                <Button x:Name="SkipBtn" Content="跳转" Height="30" Width="50" Margin="0,0,0,0" Click="SkipBtn_Click" VerticalAlignment="Center" BorderThickness="1" Background="#FF0123FF" Foreground="White" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+                <Button x:Name="NextBtn" Content="下一张" Height="40" Width="100" Margin="30,0,30,0" Click="NextBtn_Click" VerticalAlignment="Center" BorderThickness="1" Background="#FF0123FF" Foreground="White" Cursor="Hand">
+                    <Button.Template>
+                        <ControlTemplate TargetType="Button">
+                            <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Button.Template>
+                </Button>
+            </StackPanel>
+        </Border>
+    </Grid>
+</Page>

+ 319 - 0
WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml.cs

@@ -0,0 +1,319 @@
+using CCDCount.DLL;
+using CCDCount.DLL.SqlDataClass;
+using CCDCount.MODEL.ConfigModel;
+using CCDCount.MODEL.ShuLiModel;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// HistoryDataPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class HistoryDataPage : Page
+    {
+        private static ActionMesSqliteDataClass actionMesSqliteDataClass = null;
+        int DataStartLine = 0;
+        private int PageHeight = 2000;
+        public HistoryDataPage()
+        {
+            InitializeComponent();
+            DataContext = ShowMessageBus.ShowBinding;
+            InitBatchItems();
+            //UpDateShowBinding();
+        }
+
+        private void PreviousBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (ShowMessageBus.ShowBinding.HistoryImageNum <= 1)
+            {
+                MessageBox.Show("已经是第一页");
+                return;
+            }
+            ShowMessageBus.ShowBinding.HistoryImageNum -= 1;
+            UpDateShowBinding();
+        }
+
+        private void NextBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (ShowMessageBus.ShowBinding.HistoryImageNum >= ShowMessageBus.ShowBinding.HistoryImageCount)
+            {
+                MessageBox.Show("已经是最后一页");
+                return;
+            }
+            ShowMessageBus.ShowBinding.HistoryImageNum += 1;
+            UpDateShowBinding();
+        }
+
+        private void UpDateShowBinding()
+        {
+            if (actionMesSqliteDataClass == null)
+            {
+                return;
+            }
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            BitmapImage ShowBitMap = null;
+            Bitmap BitmapImage = null;
+            List<ActiveObjectClass> ShowResult = actionMesSqliteDataClass.GetActiveObjectForPage((ShowMessageBus.ShowBinding.HistoryImageNum - 1) * PageHeight + DataStartLine, ShowMessageBus.ShowBinding.HistoryImageNum * PageHeight + DataStartLine);
+            if (ShowResult.Count > 0)
+            {
+                int ThisImageStartLine = (int)ShowResult.Min(o => o.StartLine);
+                int ImageHeight = (int)(ShowResult.Max(o => o.LastSeenLine) - ShowResult.Min(o => o.StartLine))+50;
+                int ImageWidth = ShowResult.Max(o => o.ImageWidth);
+                BitmapImage = new Bitmap(ImageWidth, ImageHeight <= PageHeight ? PageHeight : ImageHeight);
+
+                using (Graphics g = Graphics.FromImage(BitmapImage))
+                {
+                    g.Clear(System.Drawing.Color.White);
+
+                    var redPen = new System.Drawing.Pen(System.Drawing.Color.Red, 1);
+                    var bluePen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0, 146, 255), 1);
+                    var GreenPen = new System.Drawing.Pen(System.Drawing.Color.SeaGreen, 5);
+
+                    foreach (var item in ShowResult)
+                    {
+                        int roix = item.MinStartCol - 5;
+                        int roiy = (int)(item.StartLine - ThisImageStartLine) + 15;
+                        int roiheight = (int)(item.LastSeenLine - (long)item.StartLine) + 10;
+                        int roiwidth = item.MaxEndCol - item.MinStartCol + 10;
+                        g.DrawRectangle(GreenPen, new System.Drawing.Rectangle(roix, roiy, roiwidth, roiheight));
+
+                        Font font = new Font("Arial", 20);
+                        g.DrawString(item.Num.ToString(), font, System.Drawing.Brushes.Black, new System.Drawing.Point(roix - 20 * item.Num.ToString().Length, roiy - 20));
+
+                        foreach (var item1 in item.RowsData)
+                        {
+                            int yPos = (int)(item1.RowsCol - ThisImageStartLine + 20);
+                            g.DrawLine(item.StateCode == 0 ? bluePen : redPen, new System.Drawing.Point(item1.StartCol, yPos), new System.Drawing.Point(item1.EndCol, yPos));
+                        }
+                    }
+                }
+            }
+            else
+            {
+                BitmapImage = new Bitmap(4096, PageHeight);
+                using (Graphics g = Graphics.FromImage(BitmapImage))
+                {
+                    g.Clear(System.Drawing.Color.White);
+                }
+            }
+            Application.Current.Dispatcher.InvokeAsync(() =>
+            {
+                ShowBitMap = ConvertToBitmapImage(BitmapImage);
+                ShowMessageBus.ShowBinding.HistoryImage = ShowBitMap;
+            });
+            stopwatch.Stop();
+            Console.WriteLine($"{stopwatch.ElapsedMilliseconds}ms");
+        }
+
+        // Bitmap 转 BitmapImage 的辅助方法
+        private BitmapImage ConvertToBitmapImage(Bitmap bitmap)
+        {
+            using (MemoryStream memory = new MemoryStream())
+            {
+                bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
+                memory.Position = 0;
+                var bitmapImage = new BitmapImage();
+                bitmapImage.BeginInit();
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+                bitmapImage.StreamSource = memory;
+                bitmapImage.EndInit();
+                return bitmapImage;
+            }
+        }
+
+        private void SkipBtn_Click(object sender, RoutedEventArgs e)
+        {
+            UpDateShowBinding();
+        }
+
+        /// <summary>
+        /// 初始化批次列表
+        /// </summary>
+        private void InitBatchItems()
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\ActiveObjectData\\Cam{MessageBus.NowSettingLoadMainThread.cameraConfig.CamerNo}";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.db", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(System.IO.Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化批号列表
+        /// </summary>
+        private void InitBatchItems(DateTime Mintime, DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime && f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(System.IO.Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化批号列表
+        /// </summary>
+        private void InitBatchItemsByMinTime(DateTime Mintime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime > Mintime).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(System.IO.Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        /// <summary>
+        /// 初始化批号列表
+        /// </summary>
+        private void InitBatchItemsByMaxTime(DateTime MaxTime)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 使用 DirectoryInfo 获取文件并按修改时间排序
+                DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
+                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+
+                // 按照修改时间排序(最新的在前)
+                var sortedFiles = files.Where(f => f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
+                ShowMessageBus.ShowBinding.BatchItems.Clear();
+                foreach (FileInfo file in sortedFiles)
+                {
+                    ShowMessageBus.ShowBinding.BatchItems.Add(System.IO.Path.GetFileNameWithoutExtension(file.Name).Split('_')[1]);
+                }
+                BatchNumComBox.SelectedIndex = 0;
+            }
+            catch
+            { }
+        }
+
+        private void BatchNumRecordMinTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (BatchNumRecordMinTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (BatchNumRecordMaxTime.SelectedDate == null)
+                {
+                    InitBatchItemsByMinTime((DateTime)BatchNumRecordMinTime.SelectedDate);
+                }
+                else
+                {
+                    InitBatchItems((DateTime)BatchNumRecordMinTime.SelectedDate, (DateTime)BatchNumRecordMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        private void BatchNumRecordMaxTime_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (BatchNumRecordMaxTime.SelectedDate == null)
+            {
+                return;
+            }
+            else
+            {
+                if (BatchNumRecordMinTime.SelectedDate == null)
+                {
+                    InitBatchItemsByMaxTime((DateTime)BatchNumRecordMaxTime.SelectedDate);
+                }
+                else
+                {
+                    InitBatchItems((DateTime)BatchNumRecordMinTime.SelectedDate, (DateTime)BatchNumRecordMaxTime.SelectedDate);
+                }
+            }
+        }
+
+        private void BatchNumRecordComBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (BatchNumComBox.SelectedItem != null && BatchNumComBox.SelectedItem.ToString() != string.Empty)
+            {
+                string BatchNumber = BatchNumComBox.SelectedItem.ToString();
+                actionMesSqliteDataClass = new ActionMesSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\ActiveObjectData\\Cam{MessageBus.NowSettingLoadMainThread.cameraConfig.CamerNo}\\ActiveObjectData_{BatchNumber}.db");
+                //actionMesSqliteDataClass = new ActionMesSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\ActiveObjectData\\Cam{MessageBus.MainThreadS[0].cameraConfig.CamerNo}\\ActiveObjectData_20250908.db");
+                actionMesSqliteDataClass.GetAllActionMinStartMaxEndLine(out int num, out int StartLine, out int EndLine);
+                ShowMessageBus.ShowBinding.HistoryImageCount = (EndLine - StartLine) / PageHeight;
+                DataStartLine = StartLine;
+                ShowMessageBus.ShowBinding.HistoryImageNum = 1;
+                UpDateShowBinding();
+            }
+        }
+    }
+}

+ 463 - 0
WpfSwitchLanguage/WpfPage/MainPage.xaml

@@ -0,0 +1,463 @@
+<Page x:Class="CCDCountWpf.WpfPage.MainPage"
+      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:CCDCountWpf.WpfPage"
+      xmlns:BindNameSpace="clr-namespace:CCDCountWpf"
+      mc:Ignorable="d"
+      Title="MainPage" Height="1000" Width="1920" Loaded="Page_Loaded">
+
+    <Grid>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="*"/>
+            <ColumnDefinition Width="380"/>
+        </Grid.ColumnDefinitions>
+        <Grid Margin="0,0,0,240">
+            <Border BorderBrush="Black" BorderThickness="1" Margin="2,2,2,2">
+                <Image x:Name="ShowBox"  Source="{Binding BitmapImage}" Margin="0,0,0,0"/>
+            </Border>
+        </Grid>
+
+        <Border BorderBrush="Black" BorderThickness="1" Height="240" VerticalAlignment="Bottom" Padding="0,0,0,5" Margin="2,2,2,2">
+            <Grid>
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="0.85*"/>
+                    <ColumnDefinition Width="0.85*"/>
+                    <ColumnDefinition Width="*"/>
+                </Grid.ColumnDefinitions>
+
+                <Border Grid.Column="0" 
+                    Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="5,10,5,0" Height="218" VerticalAlignment="Top" Cursor="">
+                    <Grid>
+                        <StackPanel Orientation="Vertical" Margin="0,0,80,0">
+                            <StackPanel Orientation="Horizontal">
+                                <Label  Content="总粒数:" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                                <Label x:Name="AllActiveNumLab" Content="{Binding AllActiveNum}" HorizontalAlignment="Left" Margin="20,5,0,0"  Width="80" FontWeight="Bold" FontSize="20"  Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White"/>
+                                <Label  Content="粒" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal">
+                                <Label  Content="合格数:" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                                <Label x:Name="AllOkNumLab" Content="{Binding AllOkNum}" HorizontalAlignment="Left" Margin="20,5,0,0" Width="80" FontWeight="Bold" FontSize="20" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White"/>
+                                <Label  Content="粒" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal">
+                                <Label  Content="不合格数:" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                                <Label x:Name="AllNgNumLab" Content="{Binding AllNgNum}" HorizontalAlignment="Left" Margin="0,5,0,0" Width="80" FontWeight="Bold" FontSize="20" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White"/>
+                                <Label  Content="粒" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal">
+                                <Label  Content="装瓶数:" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                                <Label  Content="{Binding BottingCount}" HorizontalAlignment="Left" Margin="20,5,0,0" Width="80" FontWeight="Bold" FontSize="20" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White"/>
+                                <Label  Content="瓶" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal">
+                                <Label  Content="罐装速度:" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                                <Label  Content="{Binding BottingCount}" HorizontalAlignment="Left" Margin="0,5,0,0" Width="80" FontWeight="Bold" FontSize="20" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White"/>
+                                <Label  Content="瓶/分" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                            </StackPanel>
+                        </StackPanel>
+                        <Label x:Name="CamRunStaticLab" Content="{Binding CamRunStatic}" HorizontalAlignment="Right" Margin="10,5,10,0" VerticalAlignment="Top" Background="{x:Null}" FontSize="25" Foreground="{Binding CameraStaticColor}" FontWeight="Bold" />
+                        <Button x:Name="DataClear" Content="清零" BorderThickness="1" HorizontalAlignment="Right" Margin="10,0,10,12" Width="80" Height="40" Background="#FF0123FF" FontWeight="Bold" FontSize="20" Foreground="White" Click="DataClear_Click" Cursor="Hand" VerticalAlignment="Bottom">
+                            <Button.Template>
+                                <ControlTemplate TargetType="Button">
+                                    <Border CornerRadius="5" 
+                                    Background="{TemplateBinding Background}"
+                                    BorderBrush="{TemplateBinding BorderBrush}"
+                                    BorderThickness="{TemplateBinding BorderThickness}">
+                                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                    </Border>
+                                </ControlTemplate>
+                            </Button.Template>
+                        </Button>
+                    </Grid>
+                    <!-- 卡片内容 -->
+                </Border>
+
+                <Border Grid.Column="1" 
+                    Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="5,10,5,0" Height="60" VerticalAlignment="Top">
+                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
+                        <Label  Content="计数速度:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Foreground="White"/>
+                        <Label x:Name="ShuLiSpeedTbx" Content="{Binding ShuLiSpeed}" HorizontalAlignment="Left" Margin="0,0,0,0" Width="60" FontWeight="Bold" FontSize="20" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White"/>
+                        <Label Content="粒/秒" FontWeight="Bold" FontSize="20" Margin="0,10,0,0" Foreground="White" />
+                    </StackPanel>
+                </Border>
+                <Border Grid.Column="1" 
+                    Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="5,75,5,0" Height="153" VerticalAlignment="Top">
+                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
+                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
+                            <TextBlock Text="生产批次:" FontSize="20" Margin="0,0,20,0" VerticalAlignment="Center" Foreground="White"/>
+                            <TextBox x:Name="BatchNumberTbx" Text="{Binding Source={x:Static BindNameSpace:ShowMessageBus.ShowBinding},Path = BatchNumber,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="160" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White" KeyDown="TextBox_KeyDown" Height="45"/>
+                        </StackPanel>
+                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
+                            <Button x:Name="StartIdentifyBtn" Content="开始" BorderThickness="1" HorizontalAlignment="Right" Margin="0,0,20,0" VerticalAlignment="Top" Width="100" Height="60" Background="#FF0123FF" FontWeight="Bold" FontSize="20" Foreground="White" Cursor="Hand" Click="StartIdentifyBtn_Click">
+                                <Button.Template>
+                                    <ControlTemplate TargetType="Button">
+                                        <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                        </Border>
+                                    </ControlTemplate>
+                                </Button.Template>
+                            </Button>
+                            <Button x:Name="StopIdentifyBtn" Content="暂停" BorderThickness="1" HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Height="60" Background="#FF0123FF" FontWeight="Bold" FontSize="20" Foreground="White" Cursor="Hand" Click="StopIdentifyBtn_Click">
+                                <Button.Template>
+                                    <ControlTemplate TargetType="Button">
+                                        <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                        </Border>
+                                    </ControlTemplate>
+                                </Button.Template>
+                            </Button>
+                        </StackPanel>
+                    </StackPanel>
+                </Border>
+
+                <Border Grid.Column="2" 
+                    Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="5,10,5,0" Height="218" VerticalAlignment="Top" Cursor="">
+                    <Grid>
+                        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
+                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
+                                <Label Content="当前配方:" FontWeight="Bold" FontSize="20" Margin="10,0,0,0" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
+                                <TextBox x:Name="FormulationName" Text="{Binding FormulationName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="140" Height="40"  Foreground="White" Background="{x:Null}" KeyDown="TextBox_KeyDown" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"></TextBox>
+                                <Button x:Name="SaveFormulationBtn" Content="保存配方" BorderThickness="1" HorizontalAlignment="Center" Margin="20,0,0,0" VerticalAlignment="Center" Width="110" Height="50" Background="#FF0123FF" FontWeight="Bold" FontSize="20" Foreground="White" Cursor="Hand" Click="SaveFormulationBtn_Click">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal" Margin="0,15,0,0" HorizontalAlignment="Center" VerticalAlignment="Center">
+                                <Label Content="选择配方:" FontWeight="Bold" FontSize="20" Margin="10,0,0,0" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
+                                <ComboBox  x:Name="FormulationCoBox" Height="40" Width="140" ItemsSource="{Binding FormulationItems}" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" FontSize="20">
+                                    <ComboBox.Template>
+                                        <ControlTemplate TargetType="ComboBox">
+                                            <Grid>
+                                                <ToggleButton
+                                                    Foreground="White"
+                                                    IsChecked="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
+                                                    ClickMode="Press">
+                                                    <ToggleButton.Template>
+                                                        <ControlTemplate TargetType="ToggleButton">
+                                                            <Border x:Name="Border" Background="#FF0087FF" BorderBrush="#FFABADB3" BorderThickness="1">
+                                                                <Grid>
+                                                                    <Grid.ColumnDefinitions>
+                                                                        <ColumnDefinition />
+                                                                        <ColumnDefinition Width="20" />
+                                                                    </Grid.ColumnDefinitions>
+                                                                    <ContentPresenter Grid.Column="0" Margin="3" />
+                                                                    <Path x:Name="Arrow" Grid.Column="1" 
+                                                                    Fill="White"
+                                                                    HorizontalAlignment="Center" 
+                                                                    VerticalAlignment="Center"
+                                                                    Data="M 0 0 L 4 4 L 8 0 Z" />
+                                                                </Grid>
+                                                            </Border>
+                                                            <ControlTemplate.Triggers>
+                                                                <Trigger Property="IsMouseOver" Value="True">
+                                                                    <Setter TargetName="Border" Property="Background" Value="LightBlue" />
+                                                                </Trigger>
+                                                            </ControlTemplate.Triggers>
+                                                        </ControlTemplate>
+                                                    </ToggleButton.Template>
+                                                </ToggleButton>
+                                                <ContentPresenter x:Name="ContentSite" 
+                                                    IsHitTestVisible="False"
+                                                    Content="{TemplateBinding SelectionBoxItem}"
+                                                    ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
+                                                    Margin="3,3,23,3"
+                                                    VerticalAlignment="Center"
+                                                    HorizontalAlignment="Left" 
+                                                    TextBlock.Foreground="White"/>
+                                                <Popup x:Name="Popup" 
+                                                    Placement="Bottom"
+                                                    IsOpen="{TemplateBinding IsDropDownOpen}"
+                                                    AllowsTransparency="True" 
+                                                    Focusable="False"
+                                                    PopupAnimation="Slide">
+                                                    <Border x:Name="DropDownBorder" 
+                                                         Background="#FF0087FF"
+                                                         BorderBrush="#FF0087FF"
+                                                         BorderThickness="1">
+                                                        <ScrollViewer Margin="0,3,0,3" 
+                                                            SnapsToDevicePixels="True">
+                                                            <ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" />
+                                                        </ScrollViewer>
+                                                    </Border>
+                                                </Popup>
+                                            </Grid>
+                                        </ControlTemplate>
+                                    </ComboBox.Template>
+
+                                    <ComboBox.ItemContainerStyle>
+                                        <Style TargetType="ComboBoxItem">
+                                            <Setter Property="Background" Value="#FF0087FF" />
+                                            <Setter Property="Foreground" Value="White" />
+                                            <Style.Triggers>
+                                                <Trigger Property="IsHighlighted" Value="True">
+                                                    <Setter Property="Background" Value="LightBlue" />
+                                                </Trigger>
+                                            </Style.Triggers>
+                                        </Style>
+                                    </ComboBox.ItemContainerStyle>
+                                </ComboBox>
+                                <Button x:Name="ReadFormulationBtn" Content="读取配方" BorderThickness="1" HorizontalAlignment="Center" Margin="20,0,0,0" VerticalAlignment="Center" Width="110" Height="50" Background="#FF0123FF" FontWeight="Bold" FontSize="20" Foreground="White" Cursor="Hand" Click="ReadFormulationBtn_Click">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                            </StackPanel>
+                        </StackPanel>
+                            
+                    </Grid>
+                </Border>
+            </Grid>
+        </Border>
+
+        <Border Grid.Column="1" BorderBrush="Black" BorderThickness="1" Margin="2,2,2,2">
+            <Border Background="#FF0087FF" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="15,10,15,10" Cursor="">
+                <Grid>
+                    <ScrollViewer VerticalScrollBarVisibility="Auto">
+                        <StackPanel Orientation="Vertical">
+                            <StackPanel Orientation="Horizontal" Margin="0,10,0,0" HorizontalAlignment="Center">
+                                <TextBlock Text="A速度:" FontSize="20" Margin="0,0,0,0" VerticalAlignment="Center" Foreground="White"/>
+                                <Button x:Name="BottingMaterialCylinderVibrationTableHighSpeedValueUpUPBtn" Content="++" Width="45" Height="45" Click="BottingMaterialCylinderVibrationTableHighSpeedValueUpUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                    Background="{TemplateBinding Background}"
+                                    BorderBrush="{TemplateBinding BorderBrush}"
+                                    BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottingMaterialCylinderVibrationTableHighSpeedValueUpBtn" Content="+" Width="45" Height="45" Click="BottingMaterialCylinderVibrationTableHighSpeedValueUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <TextBox Text="{Binding Source={x:Static BindNameSpace:PlcSettingMessageBus.PlcMessageShowBindage},Path = ShakeTable1H_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="79" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" Background="{x:Null}" KeyDown="TextBox_KeyDown"/>
+                                <Button x:Name="BottingMaterialCylinderVibrationTableHighSpeedValueDownBtn" Content="-" Width="45" Click="BottingMaterialCylinderVibrationTableHighSpeedValueDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottingMaterialCylinderVibrationTableHighSpeedValueDownDownBtn" Content="--" Width="45" Click="BottingMaterialCylinderVibrationTableHighSpeedValueDownDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                             Background="{TemplateBinding Background}"
+                                             BorderBrush="{TemplateBinding BorderBrush}"
+                                             BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal" Margin="0,20,0,0" HorizontalAlignment="Center">
+                                <TextBlock Text="B速度:" FontSize="20" Margin="0,0,0,0" VerticalAlignment="Center" Foreground="White"/>
+                                <Button x:Name="BottingFilterVibrationTableHighSpeedValueUpUpBtn" Content="++" Width="45" Height="45" Click="BottingFilterVibrationTableHighSpeedValueUpUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                        Background="{TemplateBinding Background}"
+                                        BorderBrush="{TemplateBinding BorderBrush}"
+                                        BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottingFilterVibrationTableHighSpeedValueUpBtn" Content="+" Width="45" Height="45" Click="BottingFilterVibrationTableHighSpeedValueUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                    Background="{TemplateBinding Background}"
+                                    BorderBrush="{TemplateBinding BorderBrush}"
+                                    BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <TextBox Text="{Binding Source={x:Static BindNameSpace:PlcSettingMessageBus.PlcMessageShowBindage},Path = ShakeTable2H_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" Background="{x:Null}" KeyDown="TextBox_KeyDown"/>
+                                <Button x:Name="BottingFilterVibrationTableHighSpeedValueDownBtn" Content="-" Width="45" Click="BottingFilterVibrationTableHighSpeedValueDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                             Background="{TemplateBinding Background}"
+                                             BorderBrush="{TemplateBinding BorderBrush}"
+                                             BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottingFilterVibrationTableHighSpeedValueDownDownBtn" Content="--" Width="45" Click="BottingFilterVibrationTableHighSpeedValueDownDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                             Background="{TemplateBinding Background}"
+                                             BorderBrush="{TemplateBinding BorderBrush}"
+                                             BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal" Margin="0,20,0,0" HorizontalAlignment="Center">
+                                <TextBlock Text="C速度:" FontSize="20" Margin="0,0,0,0" VerticalAlignment="Center" Foreground="White"/>
+                                <Button x:Name="BottingCountVibrationTableHighSpeedValueUpUpBtn" Content="++" Width="45" Height="45" Click="BottingCountVibrationTableHighSpeedValueUpUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                    Background="{TemplateBinding Background}"
+                                    BorderBrush="{TemplateBinding BorderBrush}"
+                                    BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottingCountVibrationTableHighSpeedValueUpBtn" Content="+" Width="45" Height="45" Click="BottingCountVibrationTableHighSpeedValueUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <TextBox Text="{Binding Source={x:Static BindNameSpace:PlcSettingMessageBus.PlcMessageShowBindage},Path = ShakeTable3H_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White" KeyDown="TextBox_KeyDown"/>
+                                <Button x:Name="BottingCountVibrationTableHighSpeedValueDownBtn" Content="-" Width="45" Click="BottingCountVibrationTableHighSpeedValueDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottingCountVibrationTableHighSpeedValueDownDownBtn" Content="--" Width="45" Click="BottingCountVibrationTableHighSpeedValueDownDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal" Margin="0,20,0,0" HorizontalAlignment="Center">
+                                <TextBlock Text="罐装值:" FontSize="20" Margin="0,0,0,0" VerticalAlignment="Center" Foreground="White"/>
+                                <Button x:Name="BottValueSetUpUpBtn" Content="++" Width="45" Height="45" Click="BottValueSetUpUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                    Background="{TemplateBinding Background}"
+                                    BorderBrush="{TemplateBinding BorderBrush}"
+                                    BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottValueSetUpBtn" Content="+" Width="45" Height="45" Click="BottValueSetUpBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <TextBox Text="{Binding Source={x:Static BindNameSpace:PlcSettingMessageBus.PlcMessageShowBindage},Path = BottValueSet,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White" KeyDown="TextBox_KeyDown"/>
+                                <Button x:Name="BottValueSetDownBtn" Content="-" Width="45" Click="BottValueSetDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                                <Button x:Name="BottValueSetDownDownBtn" Content="--" Width="45" Click="BottValueSetDownDownBtn_Click" Background="#FF0123FF" Foreground="White" FontSize="20" Cursor="Hand">
+                                    <Button.Template>
+                                        <ControlTemplate TargetType="Button">
+                                            <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                            </Border>
+                                        </ControlTemplate>
+                                    </Button.Template>
+                                </Button>
+                            </StackPanel>
+                        </StackPanel>
+                    </ScrollViewer>
+                </Grid>
+            </Border>
+        </Border>
+
+    </Grid>
+</Page>

+ 533 - 0
WpfSwitchLanguage/WpfPage/MainPage.xaml.cs

@@ -0,0 +1,533 @@
+
+using CCDCount.DLL;
+using CCDCount.DLL.SqlDataClass;
+using CCDCount.MODEL.AuditTrailModel;
+using CCDCount.MODEL.ConfigModel;
+using LogClass;
+using MvCameraControl;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Interop;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// MainPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainPage : Page
+    {
+        #region 变量与实例
+        #endregion
+        public MainPage()
+        {
+            InitializeComponent();
+            DataContext  = ShowMessageBus.ShowBinding;
+            InitFormationItems();
+        }
+
+        private void DataClear_Click(object sender, RoutedEventArgs e)
+        {
+            if(MessageBus.NowSettingLoadMainThread == null)
+                return;
+            MessageBus.NowSettingLoadMainThread.ClearHistoryActive();
+            MessageBus.NowSettingLoadMainThread.ClearSendQueue();
+        }
+
+        private void Page_Loaded(object sender, RoutedEventArgs e)
+        {
+            this.Width = double.NaN; // 等效于 Auto
+            this.Height = double.NaN;
+
+            StopIdentifyBtn.IsEnabled = false;
+            StopIdentifyBtn.Opacity = 0.5;
+
+            if(MessageBus.NowSettingLoadMainThread != null)
+            {
+                if (MessageBus.NowSettingLoadMainThread.CameraRunStatic)
+                {
+                    StartIdentifyBtn.IsEnabled = false;
+                    StartIdentifyBtn.Opacity = 0.5;
+                    StopIdentifyBtn.IsEnabled = true;
+                    StopIdentifyBtn.Opacity = 1;
+                }
+                else
+                {
+                    StartIdentifyBtn.IsEnabled = true;
+                    StartIdentifyBtn.Opacity = 1;
+                    StopIdentifyBtn.IsEnabled = false;
+                    StopIdentifyBtn.Opacity = 0.5;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 启动相机识别
+        /// </summary>
+        private bool RunCameraIdentify()
+        {
+            if(MessageBus.NowSettingLoadMainThread != null)
+            {
+                MessageBus.NowSettingLoadMainThread.BatchNumber = ShowMessageBus.ShowBinding.BatchNumber;
+                if (MessageBus.NowSettingLoadMainThread.CameraConfigIsChange)
+                {
+                    MessageBus.NowSettingLoadMainThread.ReLoadCameraConfig();
+                }
+                //启动单相机实例的全部线程
+                if (!MessageBus.NowSettingLoadMainThread.StartMianThread())
+                {
+                    FaultLog.RecordErrorMessage(MessageBus.NowSettingLoadMainThread.cameraConfig.DeviceName + "_" + MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum + "启动失败", "CCDCountWpf:MainPage-RunCameraIdentify");
+                    //LOG.error(MessageBus.MainThreadS[i].cameraConfig.DeviceName + "_" + MessageBus.MainThreadS[i].cameraConfig.CameraSNNum + "启动失败");
+                    MessageBox.Show(MessageBus.NowSettingLoadMainThread.cameraConfig.DeviceName + "_" + MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum + "启动失败");
+                    return false;
+                }
+            }
+            MessageBus.NowLoadCammeraSN = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+            return true;
+        }
+
+        /// <summary>
+        /// 停止相机识别
+        /// </summary>
+        private void StopCameraIdentify()
+        {
+            if(MessageBus.NowSettingLoadMainThread != null)
+            {
+                //启动单相机实例的全部线程
+                if (!MessageBus.NowSettingLoadMainThread.StopMianThread())
+                {
+                    FaultLog.RecordErrorMessage(MessageBus.NowSettingLoadMainThread.cameraConfig.DeviceName + "_" + MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum + "关闭失败", "CCDCountWpf:MainPage-StopCameraIdentify");
+                    MessageBox.Show(MessageBus.NowSettingLoadMainThread.cameraConfig.DeviceName + "_" + MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum + "关闭失败");
+                }
+            }
+        }
+
+        private bool RunBatchIsRun =false;
+
+        /// <summary>
+        /// 运行批次记录
+        /// </summary>
+        /// <param name="BatchNumber"></param>
+        private void RunBatchRecord(string BatchNumber)
+        {
+            if (RunBatchIsRun)
+            {
+                return;
+            }
+            List<BatchRecordModel> batchRecordModels = new List<BatchRecordModel>();
+            Stopwatch stopwatch = new Stopwatch();
+            BatchMessSqliteDataClass batchMessSqliteData = new BatchMessSqliteDataClass($"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData\\BatchData_{BatchNumber}.db");
+            RunBatchIsRun = true;
+            Task.Run(() =>
+            {
+                while (RunBatchIsRun)
+                {
+                    stopwatch.Restart();
+                    DateTime RecordTime = DateTime.Now;
+                    var OutTimeBatch = batchRecordModels.Where(x => x.RecordTime.AddMinutes(1) < RecordTime).ToList();
+                    OutTimeBatch.ForEach(x => batchRecordModels.Remove(x));
+                    PlcSettingMessageBus.pLCManagement.ReadBottingVibrationTableHighSpeedValue(out ushort BottingVibrationTableHighSpeedValue, out ushort FilterVibrationTableHighSpeedValue, out ushort CountVibrationTableHighSpeedValue);
+                    PlcSettingMessageBus.pLCManagement.ReadBottingCount(out ushort BottingCount);
+                    ushort CountSPeed = (ushort)(batchRecordModels.Count() > 0 ? (BottingCount - batchRecordModels.Min(o => o.BottingCount)) > 0 ? BottingCount - batchRecordModels.Min(o => o.BottingCount) : 0 : 0);
+                    ShowMessageBus.ShowBinding.BottingSpeed = CountSPeed;
+                    BatchRecordModel batchRecordModel = new BatchRecordModel
+                    {
+                        BatchNunber = BatchNumber,
+                        MaterialCylinderVibrationTableSpeed = BottingVibrationTableHighSpeedValue,
+                        FilterVibrationTableSpeed = FilterVibrationTableHighSpeedValue,
+                        CountVibrationTableSpeed = CountVibrationTableHighSpeedValue,
+                        BottingCount = BottingCount,
+                        BottingSpeed = CountSPeed,
+                        RecordTime = RecordTime
+                    };
+                    batchMessSqliteData.InsertBatchMessage(batchRecordModel);
+                    batchRecordModels.Add(batchRecordModel);
+                    stopwatch.Stop();
+                    int SleepTime = 998 - (int)stopwatch.ElapsedMilliseconds;
+                    if(SleepTime > 0)
+                    {
+                        Thread.Sleep(SleepTime);
+                    }
+                }
+            });
+        }
+
+        private void StopBatchRecord()
+        {
+            RunBatchIsRun = false;
+        }
+
+        private void StartIdentifyBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(String.IsNullOrWhiteSpace(ShowMessageBus.ShowBinding.BatchNumber))
+            {
+                MessageBox.Show("请输入批次号!");
+                return;
+            }
+            RunBatchRecord(ShowMessageBus.ShowBinding.BatchNumber);
+            if(!RunCameraIdentify())
+            {
+                return;
+            }
+            StartIdentifyBtn.IsEnabled = false;
+            StartIdentifyBtn.Opacity = 0.5;
+            StopIdentifyBtn.IsEnabled = true;
+            StopIdentifyBtn.Opacity = 1;
+            if(PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                PlcSettingMessageBus.pLCManagement.MachineRunToTrue();
+            }
+        }
+
+        private void StopIdentifyBtn_Click(object sender, RoutedEventArgs e)
+        {
+            StopCameraIdentify();
+            StopBatchRecord();
+            StartIdentifyBtn.IsEnabled = true;
+            StartIdentifyBtn.Opacity = 1;
+            StopIdentifyBtn.IsEnabled = false;
+            StopIdentifyBtn.Opacity = 0.5;
+            if (PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                PlcSettingMessageBus.pLCManagement.MachineStopToTrue();
+            }
+        }
+
+        private void BottingMaterialCylinderVibrationTableHighSpeedValueUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed += 10;
+            }
+        }
+
+        private void BottingMaterialCylinderVibrationTableHighSpeedValueUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed += 1;
+            }
+        }
+
+        private void BottingMaterialCylinderVibrationTableHighSpeedValueDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed -= 1;
+            }
+        }
+
+        private void BottingMaterialCylinderVibrationTableHighSpeedValueDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed -= 10;
+            }
+        }
+
+        private void BottingFilterVibrationTableHighSpeedValueUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed += 10;
+            }
+        }
+
+        private void BottingFilterVibrationTableHighSpeedValueUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed += 1;
+            }
+        }
+
+        private void BottingFilterVibrationTableHighSpeedValueDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed -= 1;
+            }
+        }
+
+        private void BottingFilterVibrationTableHighSpeedValueDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed -= 10;
+            }
+        }
+
+        private void BottingCountVibrationTableHighSpeedValueUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed += 10;
+            }
+        }
+
+        private void BottingCountVibrationTableHighSpeedValueUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed += 1;
+            }
+        }
+
+        private void BottingCountVibrationTableHighSpeedValueDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed -= 1;
+            }
+        }
+
+        private void BottingCountVibrationTableHighSpeedValueDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed -= 10;
+            }
+        }
+
+        private void BottValueSetUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet + 5) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet += 5;
+            }
+        }
+
+        private void BottValueSetUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet += 1;
+            }
+        }
+
+        private void BottValueSetDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet -= 1;
+            }
+        }
+
+        private void BottValueSetDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet - 5) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet -= 5;
+            }
+        }
+
+        private void TextBox_KeyDown(object sender,KeyEventArgs e)
+        {
+            if (e.Key == Key.Enter)
+            {
+                TextBox textBox = sender as TextBox;
+                if (textBox != null)
+                {
+                    // 强制更新源数据
+                    BindingExpression bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
+                    bindingExpression.UpdateSource();
+                }
+            }
+        }
+
+        /// <summary>
+        /// 初始化配方列表
+        /// </summary>
+        private void InitFormationItems()
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Formulations";
+            if (!Directory.Exists(folderPath))
+            {
+                // 创建文件夹
+                Directory.CreateDirectory(folderPath);
+            }
+            try
+            {
+                // 获取文件列表(包含子目录)
+                string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);
+                ShowMessageBus.ShowBinding.FormulationItems.Clear();
+                foreach (string file in files)
+                {
+                    ShowMessageBus.ShowBinding.FormulationItems.Add(Path.GetFileNameWithoutExtension(file));
+                }
+                if (ShowMessageBus.ShowBinding.FormulationName != null && ShowMessageBus.ShowBinding.FormulationName != string.Empty)
+                {
+                    try
+                    {
+                        FormulationCoBox.SelectedItem = ShowMessageBus.ShowBinding.FormulationName;
+                    }
+                    catch { }
+                }
+            }
+            catch
+            { }
+        }
+
+        private void SaveFormulationBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (string.IsNullOrEmpty(ShowMessageBus.ShowBinding.FormulationName))
+            {
+                MessageBox.Show("请输入配方名称!");
+                return;
+            }
+            var ParaValue = PlcSettingMessageBus.pLCManagement.ReadAllPara();
+            FormulationConfigClass formulationConfigClass = FormulationClass.InitFormulation(
+                MessageBus.NowSettingLoadMainThread.cameraConfig, MessageBus.NowSettingLoadMainThread.shuLiConfig,ParaValue);
+            if (formulationConfigClass == null)
+            {
+                MessageBox.Show("获取参数失败,请检查与PLC的连接");
+                return;
+            }
+            formulationConfigClass.FormulationName = ShowMessageBus.ShowBinding.FormulationName;
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Formulations";
+            string FilePath = folderPath + "\\" + ShowMessageBus.ShowBinding.FormulationName + ".xml";
+            if (File.Exists(FilePath))
+            {
+                var confirmResult = MessageBox.Show("配方已存在,是否覆盖?",
+                                  "保存确认", MessageBoxButton.YesNo);
+                if (confirmResult == MessageBoxResult.No)
+                {
+                    return;
+                }
+            }
+            if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
+            {
+                XmlStorage.SerializeToXml(formulationConfigClass, FilePath);
+                InitFormationItems();
+                MessageBus.NowSettingLoadMainThread.FormulationName = formulationConfigClass.FormulationName;
+                MessageBus.NowSettingLoadMainThread.IsLoadFormulation = true;
+                MessageBox.Show("保存成功");
+            }
+        }
+
+        private void ReadFormulationBtn_Click(object sender, RoutedEventArgs e)
+        {
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Formulations\\{FormulationCoBox.SelectedItem}.xml";
+            if (!File.Exists(folderPath))
+            {
+                MessageBox.Show("指定文件不存在,请选择一个正确的配方");
+                return;
+            }
+            try
+            {
+                FormulationConfigClass formulationConfigClass = null;
+                formulationConfigClass = XmlStorage.DeserializeFromXml<FormulationConfigClass>(folderPath);
+                LoadFormulation(formulationConfigClass);
+                MessageBus.NowSettingLoadMainThread.FormulationName = formulationConfigClass.FormulationName;
+                MessageBus.NowSettingLoadMainThread.IsLoadFormulation = true;
+                MessageBox.Show("加载成功");
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"读取文件时出错:{ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 加载配方
+        /// </summary>
+        /// <param name="FormulationConfig"></param>
+        private void LoadFormulation(FormulationConfigClass FormulationConfig)
+        {
+            ShowMessageBus.ShowBinding.AcquistionLineRate = FormulationConfig.AcquistionLineRateValue.ToString();
+            ShowMessageBus.ShowBinding.ExposureTimeValue = FormulationConfig.ExposureTimeValue.ToString();
+            ShowMessageBus.ShowBinding.Channel = FormulationConfig.Channel.ToString();
+            ShowMessageBus.ShowBinding.FormulationName = FormulationConfig.FormulationName;
+            ShowMessageBus.ShowBinding.MAX_OBJECT_LENGTH = FormulationConfig.MAX_Object_LENGTH.ToString();
+            ShowMessageBus.ShowBinding.MIN_OBJECT_LENGTH = FormulationConfig.MIN_Object_LENGTH.ToString();
+            ShowMessageBus.ShowBinding.PandingCode = FormulationConfig.PandingCode.ToString();
+            ShowMessageBus.ShowBinding.RegionThreshold = FormulationConfig.RegionThreshold.ToString();
+
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingModel =
+                FormulationConfig.FillingMode;
+            PlcSettingMessageBus.PlcMessageShowBindage.BeltsSpeed =
+                FormulationConfig.BeltsSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed =
+                FormulationConfig.ShakeTable1H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed =
+                FormulationConfig.ShakeTable2H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed =
+                FormulationConfig.ShakeTable3H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed =
+                FormulationConfig.ShakeTable1M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed =
+                FormulationConfig.ShakeTable2M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed =
+                FormulationConfig.ShakeTable3M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed =
+                FormulationConfig.ShakeTable1L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed =
+                FormulationConfig.ShakeTable2L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed =
+                FormulationConfig.ShakeTable3L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed =
+                FormulationConfig.ShakeTable1H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed =
+                FormulationConfig.ShakeTable2H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed =
+                FormulationConfig.ShakeTable3H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed =
+                FormulationConfig.ShakeTable1M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed =
+                FormulationConfig.ShakeTable1M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed =
+                FormulationConfig.ShakeTable3M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed =
+                FormulationConfig.ShakeTable1L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed =
+                FormulationConfig.ShakeTable1L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed =
+                FormulationConfig.ShakeTable3L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed =
+                FormulationConfig.FillingValveCloseSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition =
+                FormulationConfig.FillingValveClosePosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime =
+                FormulationConfig.ValveDelytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed =
+                FormulationConfig.ScrewJogSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet =
+                FormulationConfig.BottValueSet;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed =
+                FormulationConfig.FillingValveOpenSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition =
+                FormulationConfig.FillingValveOpenPosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue =
+                FormulationConfig.CacheShutdownValue;
+        }
+    }
+}

+ 23 - 0
WpfSwitchLanguage/WpfPage/MessagePage.xaml

@@ -0,0 +1,23 @@
+<Page x:Class="CCDCountWpf.WpfPage.MessagePage"
+      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:CCDCountWpf.WpfPage"
+      mc:Ignorable="d" 
+      d:DesignHeight="450" d:DesignWidth="800"
+      Title="MessagePage">
+
+    <Grid>
+        <DataGrid ItemsSource="{Binding ErrMessageShowList}" AutoGenerateColumns="False">
+            <DataGrid.Columns>
+                <DataGridTextColumn Header="编号" Binding="{Binding Number}" />
+                <DataGridTextColumn Header="类别" Binding="{Binding Category}" />
+                <DataGridTextColumn Header="类型" Binding="{Binding MessageType}" />
+                <DataGridTextColumn Header="消息文本" Binding="{Binding Message}" />
+                <DataGridTextColumn Header="时间" Binding="{Binding DateTime}" />
+                <DataGridTextColumn Header="用户ID" Binding="{Binding UserID}" />
+            </DataGrid.Columns>
+        </DataGrid>
+    </Grid>
+</Page>

+ 29 - 0
WpfSwitchLanguage/WpfPage/MessagePage.xaml.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// MessagePage.xaml 的交互逻辑
+    /// </summary>
+    public partial class MessagePage : Page
+    {
+        public MessagePage()
+        {
+            InitializeComponent();
+            DataContext = ShowMessageBus.ShowBinding;
+        }
+    }
+}

+ 47 - 0
WpfSwitchLanguage/WpfPage/PlcOperationPage.xaml

@@ -0,0 +1,47 @@
+<Page x:Class="CCDCountWpf.WpfPage.PlcOperationPage"
+      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:CCDCountWpf.WpfPage"
+      mc:Ignorable="d"
+      Title="PlcOperationPage" Height="509" Width="822">
+    <Grid>
+        <Grid x:Name="ShowGrid" Grid.Row="1">
+            <Grid x:Name="PLCRuningSetting" Visibility="Visible">
+                <WrapPanel Orientation="Horizontal" Grid.Column="0"
+                           ItemHeight="70" ItemWidth="130" HorizontalAlignment="Left"
+                           VerticalAlignment="Top">
+                    <Button x:Name="Valve1Jog" Content="闸门一点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve1Jog_Click"/>
+                    <Button x:Name="Valve2Jog" Content="闸门二点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve2Jog_Click"/>
+                    <Button x:Name="Valve3Jog" Content="闸门三点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve3Jog_Click"/>
+                    <Button x:Name="Valve4Jog" Content="闸门四点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve4Jog_Click"/>
+                    <Button x:Name="Valve5Jog" Content="闸门五点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve5Jog_Click"/>
+                    <Button x:Name="Valve6Jog" Content="闸门六点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve6Jog_Click"/>
+                    <Button x:Name="Valve7Jog" Content="闸门七点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve7Jog_Click"/>
+                    <Button x:Name="Valve8Jog" Content="闸门八点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" Click="Valve8Jog_Click"/>
+                    <Button x:Name="MachineRunBtn" Content="PLC启动"  Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="InitiateBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="InitiateBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="MachineStopBtn" Content="PLC停止" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="StopBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="StopBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="ScrewHomeBtn" Content="传动轴回零" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="ScrewHomeBtn_PreviewMouseLeftButtonDown"/>
+                    <Button x:Name="ScrewJogFwdBtn" Content="传动轴正向点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="ScrewJogFwdBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ScrewJogFwdBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="ScrewJogRevBtn" Content="传动轴反向点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="ScrewJogRevBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ScrewJogRevBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="FillingValveManualOpenBtn" Content="中转阀开" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FillingValveManualOpenBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveManualOpenBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="FillingValveManualCloseBtn" Content="中转阀关" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FillingValveManualCloseBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveManualCloseBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="FillingValveManualCacheBtn" Content="中转阀缓存" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FillingValveManualCacheBtn_PreviewMouseLeftButtonDown"/>
+                    <Button x:Name="FillingValveJogFwdBtn" Content="中转阀正向点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FillingValveJogFwdBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveJogFwdBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="FillingValveJogRevBtn" Content="中转阀反向点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FillingValveJogRevBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveJogRevBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="FillingValveHomeBtn" Content="中转阀回原点" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FillingValveHomeBtn_PreviewMouseLeftButtonDown" />
+                    <Button x:Name="BeltsJogBtn" Content="传送带点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="BeltsJogBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="BeltsJogBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="ShakeTableJogBtn" Content="震盘点动" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="ShakeTableJogBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ShakeTableJogBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="MachineManualUpBtn" Content="整机上升" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="MachineManualUpBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="MachineManualUpBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="MachineManualDownBtn" Content="整机下降" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="MachineManualDownBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="MachineManualDownBtn_PreviewMouseLeftButtonUp"/>
+                    <Button x:Name="FunnelValveManualControlBtn" Content="漏斗" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="FunnelValveManualControlBtn_PreviewMouseLeftButtonDown" />
+                    <Button x:Name="MachineManualBeltsBtn" Content="传送带运行状态" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="MachineManualBeltsBtn_PreviewMouseLeftButtonDown" />
+                    <Button x:Name="MachineAirLockValveBtn" Content="气锁" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="MachineAirLockValveBtn_PreviewMouseLeftButtonDown" />
+                    <Button x:Name="ShakeTable_TestBtn" Content="震台调试开关" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="ShakeTable_TestBtn_PreviewMouseLeftButtonDown" />
+                    <Button x:Name="DataResetBtn" Content="数据清零" HorizontalAlignment="Left" Margin="40,0,0,0" Height="40" Width="90" PreviewMouseLeftButtonDown="DataResetBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="DataResetBtn_PreviewMouseLeftButtonUp" />
+                </WrapPanel>
+            </Grid>
+        </Grid>
+    </Grid>
+</Page>

+ 247 - 0
WpfSwitchLanguage/WpfPage/PlcOperationPage.xaml.cs

@@ -0,0 +1,247 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// PlcOperationPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class PlcOperationPage : Page
+    {
+        public PlcOperationPage()
+        {
+            InitializeComponent();
+            this.Width = Double.NaN;
+            this.Height = Double.NaN;
+            DataContext = PlcSettingMessageBus.PlcMessageShowBindage;
+        }
+
+        /// <summary>
+        /// 开始按钮按下事件
+        /// </summary>
+        private void InitiateBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.MachineRunToTrue();
+        }
+
+        /// <summary>
+        /// 开始按钮抬起事件
+        /// </summary>
+        private void InitiateBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            //pLCManagement.InitiateToFalse();
+        }
+
+        /// <summary>
+        /// 停止按钮按下事件
+        /// </summary>
+        private void StopBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.MachineStopToTrue();
+        }
+
+        /// <summary>
+        /// 停止按钮抬起事件
+        /// </summary>
+        private void StopBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            //pLCManagement.StopToFalse();
+        }
+        private void Valve1Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(0);
+        }
+
+        private void Valve2Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(1);
+        }
+
+        private void Valve3Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(2);
+        }
+
+        private void Valve4Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(3);
+        }
+
+        private void Valve5Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(4);
+        }
+
+        private void Valve6Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(5);
+        }
+
+        private void Valve7Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(6);
+        }
+
+        private void Valve8Jog_Click(object sender, RoutedEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(7);
+        }
+
+        private void ScrewHomeBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ScrewHomeToTrue();
+        }
+
+        private void ScrewJogFwdBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ScrewJogFwdToTrue();
+        }
+
+        private void ScrewJogFwdBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ScrewJogFwdToFalse();
+        }
+
+        private void ScrewJogRevBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ScrewJogRevToTrue();
+        }
+
+        private void ScrewJogRevBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ScrewJogRevToFalse();
+        }
+
+        private void FillingValveManualOpenBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualOpenToTrue();
+        }
+
+        private void FillingValveManualCloseBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualCloseToTrue();
+        }
+
+        private void FillingValveManualCacheBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualCache();
+        }
+
+        private void FillingValveJogFwdBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveJogFwdToTrue();
+        }
+
+        private void FillingValveJogFwdBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveJogFwdToFalse();
+        }
+
+        private void FillingValveJogRevBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveJogRevToTrue();
+        }
+
+        private void FillingValveJogRevBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveJogRevToFalse();
+        }
+
+        private void FillingValveHomeBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveHomeToTrue();
+        }
+
+        private void BeltsJogBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.BeltsJogToTrue();
+        }
+
+        private void BeltsJogBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.BeltsJogToFalse();
+        }
+
+        private void ShakeTableJogBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ShakeTableJogToTrue();
+        }
+
+        private void ShakeTableJogBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.ShakeTableJogToFalse();
+        }
+
+        private void MachineManualUpBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.MachineManualUpToTrue();
+        }
+
+        private void MachineManualUpBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.MachineManualUpToFalse();
+        }
+
+        private void MachineManualDownBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.MachineManualDownToTrue();
+        }
+
+        private void MachineManualDownBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.MachineManualDownToFalse();
+        }
+
+        private void FunnelValveManualControlBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchFunnelValveManualControl();
+        }
+
+        private void MachineManualBeltsBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchMachineManualControl();
+        }
+
+        private void MachineAirLockValveBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchMachineAirLockValve();
+        }
+
+        private void FillingValveManualOpenBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualOpenToFalse();
+        }
+
+        private void FillingValveManualCloseBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualCloseToFalse();
+        }
+
+        private void DataResetBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.DataResetToTrue();
+        }
+
+        private void DataResetBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.DataResetToFalse();
+        }
+
+        private void ShakeTable_TestBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.SwitchShakeTable_Test();
+        }
+    }
+}

+ 319 - 0
WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml

@@ -0,0 +1,319 @@
+<Page x:Class="CCDCountWpf.WpfPage.PlcSettingPage"
+      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:CCDCountWpf.WpfPage"
+      mc:Ignorable="d"
+      Title="PlcSettingPage" Width="1002" Height="1200">
+    <Grid>
+        <Grid x:Name="ShowGrid" Margin="0,0,0,0">
+            <Button x:Name="ReloadBtn" Height="50" Width="80" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" Click="ReloadBtn_Click"></Button>
+            <WrapPanel Orientation="Horizontal" Grid.Column="0"
+                           ItemHeight="50" ItemWidth="300" HorizontalAlignment="Left"
+                           VerticalAlignment="Top" Margin="0,60,0,0">
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装料筒震台高速值:" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ShakeTable1H_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1H_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1H_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1H_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1H_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装过滤震台高速值:" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ShakeTable2H_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2H_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2H_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2H_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2H_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装计数震台高速值:" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ShakeTable3H_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3H_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3H_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3H_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3H_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装料筒震台减速值:" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ShakeTable1M_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1M_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1M_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1M_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1M_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装过滤震台减速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable2M_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2M_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2M_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2M_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2M_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装计数震台减速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable3M_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3M_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3M_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3M_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3M_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装料筒震台低速值:" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ShakeTable1L_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1L_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1L_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1L_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1L_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装过滤震台低速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable2L_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2L_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2L_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2L_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2L_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装计数震台低速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable3L_FillingSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3L_FillingSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3L_FillingSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3L_FillingSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3L_FillingSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存料筒震台高速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable1H_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1H_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1H_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1H_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1H_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存过滤震台高速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable2H_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2H_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2H_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2H_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2H_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存计数震台高速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable3H_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3H_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3H_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3H_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3H_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存料筒震台减速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable1M_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1M_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1M_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1M_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1M_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存过滤震台减速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable2M_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2M_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2M_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2M_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2M_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存计数震台减速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable3M_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3M_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3M_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3M_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3M_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存料筒震台低速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable1L_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1L_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1L_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1L_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1L_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存过滤震台低速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable2L_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2L_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2L_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2L_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2L_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存计数震台低速值:" FontSize="16" VerticalAlignment="Center" Margin="5,0,0,0"/>
+                    <Button x:Name="ShakeTable3L_CacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3L_CacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3L_CacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3L_CacheSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3L_CacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="料筒震台测试速度:" FontSize="16" VerticalAlignment="Center" Margin="5,0,16,0"/>
+                    <Button x:Name="ShakeTable1_TestSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable1_TestSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable1_TestSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable1_TestSpeedDownBtn" Content="-" Width="30" Click="ShakeTable1_TestSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="过滤震台测试速度:" FontSize="16" VerticalAlignment="Center" Margin="5,0,16,0"/>
+                    <Button x:Name="ShakeTable2_TestSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable2_TestSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable2_TestSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable2_TestSpeedDownBtn" Content="-" Width="30" Click="ShakeTable2_TestSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="计数震台测试速度:" FontSize="16" VerticalAlignment="Center" Margin="5,0,16,0"/>
+                    <Button x:Name="ShakeTable3_TestSpeedUpBtn" Content="+" Width="30" Height="30" Click="ShakeTable3_TestSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ShakeTable3_TestSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ShakeTable3_TestSpeedDownBtn" Content="-" Width="30" Click="ShakeTable3_TestSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装高速区间:" FontSize="16" VerticalAlignment="Center" Margin="5,0,48,0"/>
+                    <Button x:Name="FillingH_SpeedRatioUpBtn" Content="+" Width="30" Height="30" Click="FillingH_SpeedRatioUpBtn_Click" />
+                    <TextBox Text="{Binding FillingH_SpeedRatio,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingH_SpeedRatioDownBtn" Content="-" Width="30" Click="FillingH_SpeedRatioDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装减速区间:" FontSize="16" VerticalAlignment="Center" Margin="5,0,48,0"/>
+                    <Button x:Name="FillingM_SpeedRatioUpBtn" Content="+" Width="30" Height="30" Click="FillingM_SpeedRatioUpBtn_Click" />
+                    <TextBox Text="{Binding FillingM_SpeedRatio,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingM_SpeedRatioDownBtn" Content="-" Width="30" Click="FillingM_SpeedRatioDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="罐装低速区间:" FontSize="16" VerticalAlignment="Center" Margin="5,0,48,0"/>
+                    <Button x:Name="FillingL_SpeedRatioUpBtn" Content="+" Width="30" Height="30" Click="FillingL_SpeedRatioUpBtn_Click" />
+                    <TextBox Text="{Binding FillingL_SpeedRatio,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingL_SpeedRatioDownBtn" Content="-" Width="30" Click="FillingL_SpeedRatioDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存高速区间:" FontSize="16" VerticalAlignment="Center" Margin="5,0,48,0"/>
+                    <Button x:Name="CacheH_SpeedRatioUpBtn" Content="+" Width="30" Height="30" Click="CacheH_SpeedRatioUpBtn_Click" />
+                    <TextBox Text="{Binding CacheH_SpeedRatio,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="CacheH_SpeedRatioDownBtn" Content="-" Width="30" Click="CacheH_SpeedRatioDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存减速区间:" FontSize="16" VerticalAlignment="Center" Margin="5,0,48,0"/>
+                    <Button x:Name="CacheM_SpeedRatioUpBtn" Content="+" Width="30" Height="30" Click="CacheM_SpeedRatioUpBtn_Click" />
+                    <TextBox Text="{Binding CacheM_SpeedRatio,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="CacheM_SpeedRatioDownBtn" Content="-" Width="30" Click="CacheM_SpeedRatioDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存低速区间:" FontSize="16" VerticalAlignment="Center" Margin="5,0,48,0"/>
+                    <Button x:Name="CacheL_SpeedRatioUpBtn" Content="+" Width="30" Height="30" Click="CacheL_SpeedRatioUpBtn_Click" />
+                    <TextBox Text="{Binding CacheL_SpeedRatio,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="CacheL_SpeedRatio" Content="-" Width="30" Click="CacheL_SpeedRatioDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀打开速度:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="FillingValveOpenSpeedUpBtn" Content="+" Width="30" Height="30" Click="FillingValveOpenSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveOpenSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValveOpenSpeedDownBtn" Content="-" Width="30" Click="FillingValveOpenSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀打开位置:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="TransferValveOpenPositionUpBtn" Content="+" Width="30" Height="30" Click="FillingValveOpenPositionUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveOpenPosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValveOpenPositionDownBtn" Content="-" Width="30" Click="FillingValveOpenPositionDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀关闭速度:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="FillingValveCloseSpeedUpBtn" Content="+" Width="30" Height="30" Click="FillingValveCloseSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveCloseSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValveCloseSpeedDownBtn" Content="-" Width="30" Click="FillingValveCloseSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀关闭位置:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="FillingValveClosePositionUpBtn" Content="+" Width="30" Height="30" Click="FillingValveClosePositionUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveClosePosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValveClosePositionDownBtn" Content="-" Width="30" Click="FillingValveClosePositionDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀缓存速度:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="FillingValveCacheSpeedUpBtn" Content="+" Width="30" Height="30" Click="FillingValveCacheSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveCacheSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValveCacheSpeedDownBtn" Content="-" Width="30" Click="FillingValveCacheSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀缓存位置:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="FillingValveCachePositionUpBtn" Content="+" Width="30" Height="30" Click="FillingValveCachePositionUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveCachePosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValveCachePositionDownBtn" Content="-" Width="30" Click="FillingValveCachePositionDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="传动轴定位速度:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="BottlePosSpeedUpBtn" Content="+" Width="30" Height="30" Click="BottlePosSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding BottlePosSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="BottlePosSpeedDownBtn" Content="-" Width="30" Click="BottlePosSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="传动轴定位位置:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="BottlePosPositionUpBtn" Content="+" Width="30" Height="30" Click="BottlePosPositionUpBtn_Click" />
+                    <TextBox Text="{Binding BottlePosPosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="BottlePosPositionDownBtn" Content="-" Width="30" Click="BottlePosPositionDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="传动轴点动速度:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ScrewJogSpeedUpBtn" Content="+" Width="30" Height="30" Click="ScrewJogSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding ScrewJogSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ScrewJogSpeedDownBtn" Content="-" Width="30" Click="ScrewJogSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="进瓶速度:" FontSize="16" Margin="5,0,80,0" VerticalAlignment="Center"/>
+                    <Button x:Name="InBottleSpeedUpBtn" Content="+" Width="30" Height="30" Click="InBottleSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding InBottleSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="InBottleSpeedDownBtn" Content="-" Width="30" Click="InBottleSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀点动速度:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="FillingValueJogSpeedUpBtn" Content="+" Width="30" Height="30" Click="FillingValueJogSpeedUpBtn_Click" />
+                    <TextBox Text="{Binding FillingValveJogSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="FillingValueJogSpeedDownBtn" Content="-" Width="30" Click="FillingValueJogSpeedDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="漏斗下降延时:" FontSize="16" Margin="5,0,48,0" VerticalAlignment="Center"/>
+                    <Button x:Name="MachineDelayFunneDownTimeUpBtn" Content="+" Width="30" Height="30" Click="MachineDelayFunneDownTimeUpBtn_Click" />
+                    <TextBox Text="{Binding MachineDelayFunneDownTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="MachineDelayFunneDownTimeDownBtn" Content="-" Width="30" Click="MachineDelayFunneDownTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="漏斗上升延时:" FontSize="16" Margin="5,0,48,0" VerticalAlignment="Center"/>
+                    <Button x:Name="MachineDelayFunneUpTimeUpBtn" Content="+" Width="30" Height="30" Click="MachineDelayFunneUpTimeUpBtn_Click" />
+                    <TextBox Text="{Binding MachineDelayFunneUpTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="MachineDelayFunneUpTimeDownBtn" Content="-" Width="30" Click="MachineDelayFunneUpTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀打开延时:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="MachineDelayFillingValveOpenTimeUpBtn" Content="+" Width="30" Height="30" Click="MachineDelayFillingValveOpenTimeUpBtn_Click" />
+                    <TextBox Text="{Binding MachineDelayFillingValveOpenTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="MachineDelayFillingValveOpenTimeDownBtn" Content="-" Width="30" Click="MachineDelayFillingValveOpenTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="中转阀关闭延时:" FontSize="16" Margin="5,0,32,0" VerticalAlignment="Center"/>
+                    <Button x:Name="MachineDelayFillingValveCloseTimeUpBtn" Content="+" Width="30" Height="30" Click="MachineDelayFillingValveCloseTimeUpBtn_Click" />
+                    <TextBox Text="{Binding MachineDelayFillingValveCloseTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="MachineDelayFillingValveCloseTimeDownBtn" Content="-" Width="30" Click="MachineDelayFillingValveCloseTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="进瓶延时:" FontSize="16" Margin="5,0,80,0" VerticalAlignment="Center"/>
+                    <Button x:Name="MachineDelayInBottleTimeUpBtn" Content="+" Width="30" Height="30" Click="MachineDelayInBottleTimeUpBtn_Click" />
+                    <TextBox Text="{Binding MachineDelayInBottleTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="MachineDelayInBottleTimeDownBtn" Content="-" Width="30" Click="MachineDelayInBottleTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="气阀开延时:" FontSize="16" Margin="5,0,64,0" VerticalAlignment="Center"/>
+                    <Button x:Name="ValveDelytimeUpBtn" Content="+" Width="30" Height="30" Click="ValveDelytimeUpBtn_Click" />
+                    <TextBox Text="{Binding ValveDelytime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="ValveDelytimeDownBtn" Content="-" Width="30" Click="ValveDelytimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缺瓶检测时间:" FontSize="16" Margin="5,0,48,0" VerticalAlignment="Center"/>
+                    <Button x:Name="MissingDelaytimeUpBtn" Content="+" Width="30" Height="30" Click="MissingDelaytimeUpBtn_Click" />
+                    <TextBox Text="{Binding MissingDelaytime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="MissingDelaytimeDownBtn" Content="-" Width="30" Click="MissingDelaytimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="堵瓶检测时间:" FontSize="16" Margin="5,0,48,0" VerticalAlignment="Center"/>
+                    <Button x:Name="BottleJamDelaytimeUpBtn" Content="+" Width="30" Height="30" Click="BottleJamDelaytimeUpBtn_Click" />
+                    <TextBox Text="{Binding BottleJamDelaytime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="BottleJamDelaytimeDownBtn" Content="-" Width="30" Click="BottleJamDelaytimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="剔废气缸延时时间:" FontSize="16" Margin="5,0,16,0" VerticalAlignment="Center"/>
+                    <Button x:Name="EliminateCylinderDelayTimeUpBtn" Content="+" Width="30" Height="30" Click="EliminateCylinderDelayTimeUpBtn_Click" />
+                    <TextBox Text="{Binding EliminateCylinderDelayTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="EliminateCylinderDelayTimeDownBtn" Content="-" Width="30" Click="EliminateCylinderDelayTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="剔废气缸保持时间:" FontSize="16" Margin="5,0,16,0" VerticalAlignment="Center"/>
+                    <Button x:Name="EliminateCylinderHoldingTimeUpBtn" Content="+" Width="30" Height="30" Click="EliminateCylinderHoldingTimeUpBtn_Click" />
+                    <TextBox Text="{Binding EliminateCylinderHoldingTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="EliminateCylinderHoldingTimeDownBtn" Content="-" Width="30" Click="EliminateCylinderHoldingTimeDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="瓶装设定值:" FontSize="16" Margin="5,0,64,0" VerticalAlignment="Center"/>
+                    <Button x:Name="BottValueSetUpBtn" Content="+" Width="30" Height="30" Click="BottValueSetUpBtn_Click" />
+                    <TextBox Text="{Binding BottValueSet,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="BottValueSetDownBtn" Content="-" Width="30" Click="BottValueSetDownBtn_Click" />
+                </StackPanel>
+                <StackPanel Height="30" Orientation="Horizontal">
+                    <TextBlock Text="缓存停机值:" FontSize="16" Margin="5,0,64,0" VerticalAlignment="Center"/>
+                    <Button x:Name="CacheShutdownValueUpBtn" Content="+" Width="30" Height="30" Click="CacheShutdownValueUpBtn_Click" />
+                    <TextBox Text="{Binding CacheShutdownValue,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="80" KeyDown="TextBox_KeyDown"/>
+                    <Button x:Name="CacheShutdownValueDownBtn" Content="-" Width="30" Click="CacheShutdownValueDownBtn_Click" />
+                </StackPanel>
+            </WrapPanel>
+            
+        </Grid>
+    </Grid>
+</Page>

+ 1058 - 0
WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml.cs

@@ -0,0 +1,1058 @@
+using CCDCount.DLL;
+using System;
+using System.Drawing;
+using System.Globalization;
+using System.Security.Cryptography.X509Certificates;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// PlcSettingPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class PlcSettingPage : Page
+    {
+        public PlcSettingPage()
+        {
+            InitializeComponent();
+            this.Width = Double.NaN;
+            this.Height = Double.NaN;
+            DataContext = PlcSettingMessageBus.PlcMessageShowBindage;
+        }
+
+        private void ScrewJogSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed, out float result))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed = (result + 0.5f).ToString();
+            }
+        }
+
+        private void ScrewJogSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed, out float result))
+            {
+                if((result - 0.5f)>=0)
+                {
+                    PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed = (result - 0.5f).ToString();
+                }
+            }
+        }
+
+        private void BottValueSetUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet + 1) > 
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet += 1;
+            }
+        }
+
+        private void BottValueSetDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet -= 1;
+            }
+        }
+
+        private void FillingValveOpenSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed, out float result))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed = (result + 0.5f).ToString();
+            }
+        }
+
+        private void FillingValveOpenSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed, out float result))
+            {
+                if((result - 0.5f)>=0)
+                {
+                    PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed = (result - 0.5f).ToString();
+                }
+            }
+        }
+
+
+        private void CacheShutdownValueUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue + 1) > 
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue += 1;
+            }
+        }
+
+        private void CacheShutdownValueDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue - 1) < 
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue -= 1;
+            }
+        }
+
+        private void ShakeTable1H_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed + 1) > 
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1H_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed - 1) < 
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2H_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed + 1) > 
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed)
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed += 1;
+        }
+
+        private void ShakeTable2H_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3H_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed+1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable3H_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed - 1)<
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable1M_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed +1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1M_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed - 1)<
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2M_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable2M_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed - 1) < 
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3M_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable3M_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed -= 1;
+            }
+        }
+
+
+        private void ShakeTable1L_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1L_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2L_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable2L_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3L_FillingSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed += 1;
+            }
+        }
+
+        private void ShakeTable3L_FillingSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable1H_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1H_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2H_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed += 1;
+            }
+        }
+
+        private void ShakeTable2H_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed - 1)<
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3H_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed += 1;
+            }
+        }
+
+        private void ShakeTable3H_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed - 1)<
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable1M_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1M_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2M_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed + 1)>
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed)
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed += 1;
+        }
+
+        private void ShakeTable2M_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed - 1)<
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3M_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed)
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed += 1;
+        }
+
+        private void ShakeTable3M_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed - 1)<
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable1L_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1L_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2L_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed)
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed += 1;
+        }
+
+        private void ShakeTable2L_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3L_CacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed)
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed += 1;
+        }
+
+        private void ShakeTable3L_CacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed -= 1;
+            }
+        }
+
+        private void FillingValveCloseSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed = (value + 0.5).ToString();
+            }
+        }
+
+        private void FillingValveCloseSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed, out float value))
+            {
+                if(value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed = (value - 0.5).ToString();
+            }
+        }
+
+        private void FillingValveOpenPositionUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition = (value + 0.5).ToString();
+            }
+        }
+
+        private void FillingValveOpenPositionDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition, out float value))
+            {
+                if(value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition = (value - 0.5).ToString();
+            }
+        }
+
+        private void FillingValveClosePositionUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition = (value + 0.5).ToString();
+            }    
+        }
+
+        private void FillingValveClosePositionDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition, out float value))
+            {
+                if(value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition = (value - 0.5).ToString();
+            }
+        }
+
+        private void ValveDelytimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime += 1;
+            }
+        }
+
+        private void ValveDelytimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime -= 1;
+            }
+        }
+
+        private void TextBox_KeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key == Key.Enter)
+            {
+                TextBox textBox = sender as TextBox;
+                if (textBox != null)
+                {
+                    // 强制更新源数据
+                    BindingExpression bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
+                    bindingExpression.UpdateSource();
+                }
+            }
+        }
+
+        private void FillingH_SpeedRatioUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio += 1;
+            }
+        }
+
+        private void FillingH_SpeedRatioDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio&& 
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio-1>0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio -= 1;
+            }
+        }
+
+        private void FillingM_SpeedRatioUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio += 1;
+            }
+        }
+
+        private void FillingM_SpeedRatioDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio &&
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio -= 1;
+            }
+        }
+
+        private void FillingL_SpeedRatioUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio += 1;
+            }
+        }
+
+        private void FillingL_SpeedRatioDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio &&
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio -= 1;
+            }
+        }
+
+        private void CacheH_SpeedRatioUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio += 1;
+            }
+        }
+
+        private void CacheH_SpeedRatioDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio -= 1;
+            }
+        }
+
+        private void CacheM_SpeedRatioUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio += 1;
+            }
+        }
+
+        private void CacheM_SpeedRatioDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio -= 1;
+            }
+        }
+
+        private void CacheL_SpeedRatioUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio += 1;
+            }
+        }
+
+        private void CacheL_SpeedRatioDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio -= 1;
+            }
+        }
+
+        private void InBottleSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.InBottleSpeed, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.InBottleSpeed = (value + 0.5).ToString();
+            }
+        }
+
+        private void InBottleSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.InBottleSpeed, out float value))
+            {
+                if (value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.InBottleSpeed = (value - 0.5).ToString();
+            }
+        }
+
+        private void FillingValueJogSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveJogSpeed, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveJogSpeed = (value + 0.5).ToString();
+            }
+        }
+
+        private void FillingValueJogSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveJogSpeed, out float value))
+            {
+                if (value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveJogSpeed = (value - 0.5).ToString();
+            }
+        }
+
+        private void MachineDelayFunneDownTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime += 1;
+            }
+        }
+
+        private void MachineDelayFunneDownTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime -= 1;
+            }
+        }
+
+        private void MachineDelayFunneUpTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime += 1;
+            }
+        }
+
+        private void MachineDelayFunneUpTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime -= 1;
+            }
+        }
+
+        private void MachineDelayFillingValveOpenTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime += 1;
+            }
+        }
+
+        private void MachineDelayFillingValveOpenTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime -= 1;
+            } 
+        }
+
+        private void MachineDelayFillingValveCloseTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime += 1;
+            }
+        }
+
+        private void MachineDelayFillingValveCloseTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime -= 1;
+            }
+        }
+
+        private void MachineDelayInBottleTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime += 1;
+            }
+        }
+
+        private void MachineDelayInBottleTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime -= 1;
+            }
+        }
+
+        private void FillingValveCacheSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCacheSpeed, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCacheSpeed = (value + 0.5).ToString();
+            }
+        }
+
+        private void FillingValveCacheSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCacheSpeed, out float value))
+            {
+                if (value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCacheSpeed = (value - 0.5).ToString();
+            }
+        }
+
+        private void FillingValveCachePositionUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCachePosition, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCachePosition = (value + 0.5).ToString();
+            }
+        }
+
+        private void FillingValveCachePositionDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCachePosition, out float value))
+            {
+                if (value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCachePosition = (value - 0.5).ToString();
+            }
+        }
+
+        private void BottlePosPositionUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.BottlePosPosition, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottlePosPosition = (value + 0.5).ToString();
+            }
+        }
+
+        private void BottlePosPositionDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.BottlePosPosition, out float value))
+            {
+                if (value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.BottlePosPosition = (value - 0.5).ToString();
+            }
+        }
+
+        private void BottlePosSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.BottlePosSpeed, out float value))
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottlePosSpeed = (value + 0.5).ToString();
+            }
+        }
+
+        private void BottlePosSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (float.TryParse(PlcSettingMessageBus.PlcMessageShowBindage.BottlePosSpeed, out float value))
+            {
+                if (value - 0.5 < 0) return;
+                PlcSettingMessageBus.PlcMessageShowBindage.BottlePosSpeed = (value - 0.5).ToString();
+            }
+        }
+
+        private void ShakeTable1_TestSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed += 1;
+            }
+        }
+
+        private void ShakeTable1_TestSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed &&
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable2_TestSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed += 1;
+            }
+        }
+
+        private void ShakeTable2_TestSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed &&
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed -= 1;
+            }
+        }
+
+        private void ShakeTable3_TestSpeedUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed += 1;
+            }
+        }
+
+        private void ShakeTable3_TestSpeedDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed &&
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed -= 1;
+            }
+        }
+
+        private void MissingDelaytimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime += 1;
+            }
+        }
+
+        private void MissingDelaytimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime -= 1;
+            }
+        }
+
+        private void BottleJamDelaytimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime += 1;
+            }
+        }
+
+        private void BottleJamDelaytimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime -= 1;
+            }
+        }
+
+        private void EliminateCylinderDelayTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime += 1;
+            }
+        }
+
+        private void EliminateCylinderDelayTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime -= 1;
+            }
+        }
+
+        private void EliminateCylinderHoldingTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime += 1;
+            }
+        }
+
+        private void EliminateCylinderHoldingTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime -= 1;
+            }
+        }
+
+        private void ReloadBtn_Click(object sender, RoutedEventArgs e)
+        {
+            UpdatePlcPara();
+        }
+        private void UpdatePlcPara()
+        {
+            var ParaValue = PlcSettingMessageBus.pLCManagement.ReadAllPara();
+            if (ParaValue == null) return;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingModel =
+                ParaValue.FillingMode;
+            PlcSettingMessageBus.PlcMessageShowBindage.BeltsSpeed =
+                ParaValue.BeltsSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed =
+                ParaValue.ShakeTable1H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed =
+                ParaValue.ShakeTable2H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed =
+                ParaValue.ShakeTable3H_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_FillingSpeed =
+                ParaValue.ShakeTable1M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_FillingSpeed =
+                ParaValue.ShakeTable2M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_FillingSpeed =
+                ParaValue.ShakeTable3M_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_FillingSpeed =
+                ParaValue.ShakeTable1L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_FillingSpeed =
+                ParaValue.ShakeTable2L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_FillingSpeed =
+                ParaValue.ShakeTable3L_FillingSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_CacheSpeed =
+                ParaValue.ShakeTable1H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_CacheSpeed =
+                ParaValue.ShakeTable2H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_CacheSpeed =
+                ParaValue.ShakeTable3H_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1M_CacheSpeed =
+                ParaValue.ShakeTable1M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2M_CacheSpeed =
+                ParaValue.ShakeTable2M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3M_CacheSpeed =
+                ParaValue.ShakeTable3M_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1L_CacheSpeed =
+                ParaValue.ShakeTable1L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2L_CacheSpeed =
+                ParaValue.ShakeTable2L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3L_CacheSpeed =
+                ParaValue.ShakeTable3L_CacheSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingH_SpeedRatio =
+                ParaValue.FillingH_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingM_SpeedRatio =
+                ParaValue.FillingM_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingL_SpeedRatio =
+                ParaValue.FillingL_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheH_SpeedRatio =
+                ParaValue.CacheH_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheM_SpeedRatio =
+                ParaValue.CacheM_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheL_SpeedRatio =
+                ParaValue.CacheL_SpeedRatio;
+            PlcSettingMessageBus.PlcMessageShowBindage.ScrewJogSpeed =
+                ParaValue.ScrewJogSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.InBottleSpeed =
+                ParaValue.InBottleSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.BottlePosSpeed =
+                ParaValue.BottlePosSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.BottlePosPosition =
+                ParaValue.BottlePosPosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenSpeed =
+                ParaValue.FillingValveOpenSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveOpenPosition =
+                ParaValue.FillingValveOpenPosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCloseSpeed =
+                ParaValue.FillingValveCloseSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveClosePosition =
+                ParaValue.FillingValveClosePosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCacheSpeed =
+                ParaValue.FillingValveCacheSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveCachePosition =
+                ParaValue.FillingValueCachePosition.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.FillingValveJogSpeed =
+                ParaValue.FillingValueJogSpeed.ToString();
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneDownTime =
+                ParaValue.MachineDelayFunneDownTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFunneUpTime =
+                ParaValue.MachineDelayFunneUpTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveOpenTime =
+                ParaValue.MachineDelayFillingValveOpenTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayFillingValveCloseTime =
+                ParaValue.MachineDelayFillingValveCloseTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MachineDelayInBottleTime =
+                ParaValue.MachineDelayInBottleTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet =
+                ParaValue.BottValueSet;
+            PlcSettingMessageBus.PlcMessageShowBindage.ValveDelytime =
+                ParaValue.ValveDelytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheShutdownValue =
+                ParaValue.CacheShutdownValue;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed =
+                ParaValue.ShakeTable1_TestSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2_TestSpeed =
+                ParaValue.ShakeTable2_TestSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3_TestSpeed =
+                ParaValue.ShakeTable3_TestSpeed;
+            PlcSettingMessageBus.PlcMessageShowBindage.MissingDelaytime =
+                ParaValue.MissingDelaytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.BottleJamDelaytime =
+                ParaValue.BottleJamDelaytime;
+            PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderDelayTime =
+                ParaValue.EliminateCylinderDelayTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime =
+                ParaValue.EliminateCylinderHoldingTime;
+        }
+    }
+}

+ 116 - 0
WpfSwitchLanguage/WpfPage/SettingPage.xaml

@@ -0,0 +1,116 @@
+<Page x:Class="CCDCountWpf.WpfPage.SettingPage"
+      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:CCDCountWpf.WpfPage"
+      mc:Ignorable="d" 
+      d:DesignHeight="550" d:DesignWidth="800"
+      Title="SettingPage" Loaded="Page_Loaded">
+
+    <Grid>
+        <Grid Margin="0,0,0,0">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="330"/>
+            </Grid.ColumnDefinitions>
+            <Border Grid.Column="0" BorderBrush="Black" BorderThickness="1" Margin="2,2,2,2">
+                <Image x:Name="ShowBox"  Source="{Binding DebugImage}" Margin="0,0,0,0"/>
+            </Border>
+
+            <Grid Grid.Column="1"  Margin="2,2,2,2">
+                <Border BorderBrush="Black" BorderThickness="1"/>
+                <Grid x:Name="SettingGrid" Margin="0,0,0,0">
+                    <Grid x:Name ="BtnList" Height="40" VerticalAlignment="Top">
+                        <Button x:Name="CameraSettingBtn" Content="相机参数设置" HorizontalAlignment="Left" Margin="0,0,0,0" Width="165" Background="{x:Null}" Click="CameraSettingBtn_Click"/>
+                        <Button x:Name="ShuLiSettingBtn" Content="数粒参数设置" HorizontalAlignment="Left" Margin="165,0,0,0" Width="165" Background="{x:Null}" Click="ShuLiSettingBtn_Click"/>
+                    </Grid>
+                    <Grid x:Name="CameraSettingGrid" Margin="0,40,0,0" Visibility="Collapsed">
+                        <Label x:Name="CameraSelectLab"  Content="选择相机:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" FontSize="15" Height="30" Width="85"/>
+                        <ComboBox x:Name="CamSelectConBox" ItemsSource="{Binding CameraItems}" DisplayMemberPath="Name" SelectedValuePath="SNValue" Background="{x:Null}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="105,10,0,0" Height="30" Width="180" FontSize="12" HorizontalContentAlignment="Center" Padding="6,6,5,3" SelectionChanged="CamSelectConBox_SelectionChanged" />
+                        <Button x:Name="CamListFlushBtn" HorizontalAlignment="Right" VerticalAlignment="Top" Width="30" Height="30" Margin="0,10,5,0" Background="#FF1709AF" Click="CamListFlushBtn_Click">
+                            <Button.Template>
+                                <ControlTemplate TargetType="Button">
+                                    <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                    </Border>
+                                </ControlTemplate>
+                            </Button.Template>
+                            <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                                <Image  Source="/FromImage/刷新.png" Width="25" Height="25" />
+                            </StackPanel>
+                        </Button>
+                        <StackPanel Orientation="Horizontal" Margin="0,50,0,0" VerticalAlignment="Top">
+                            <StackPanel x:Name="CameraParameLab" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0">
+                                <Label x:Name="ExposureTimeLab" Content="曝光:" Width="85" Height="30" FontSize="15" />
+                                <Label x:Name="AcquistionLineRateLab" Content="行频:" Width="85" Height="30" FontSize="15" Margin="0,10,0,0" />
+                                <Label x:Name="ImageWidthLab" Content="图像宽:" Width="85" Height="30" FontSize="15" Margin="0,10,0,0" />
+                                <Label x:Name="CamUserNameLab" Content="用户设定名:" Width="85" Height="30" FontSize="15" Margin="0,10,0,0" />
+                                <Label x:Name="CamOffsetXLab" Content="视野偏移:" Width="85" Height="30" FontSize="15" Margin="0,10,0,0" />
+                            </StackPanel>
+                            <StackPanel x:Name="CameraParameTbx" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0">
+                                <TextBox x:Name="ExposureTimeTbx" Width="100" Text="{Binding ExposureTimeValue,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="30" FontSize="15" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="AcquistionLineRateTbx" Text="{Binding AcquistionLineRate,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="100" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="ImageWidthTbx" Text="{Binding ImageWidth,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="100" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="CamUserNameTbx" Text="{Binding CamUserName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="100" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="CamOffsetXTbx" Text="{Binding CamOffsetX,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="100" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                            </StackPanel>
+                        </StackPanel>
+                    </Grid>
+                    <Grid x:Name="ShuLiSettingGrid" Margin="0,40,0,0" Visibility="Visible">
+                        <StackPanel Orientation="Horizontal" Height="160" VerticalAlignment="Top">
+                            <StackPanel Orientation="Vertical" Margin="10,10,0,0">
+                                <Label Content="配方名:" Width="90" Height="30" FontSize="15" />
+                                <Label x:Name="RegionThresholdLab" Content="预处理阈值:" Width="90" Height="30" FontSize="15" Margin="0,10,0,0" />
+                                <Label x:Name="ChannelLab" Content="阀门通道数:" Width="90" Height="30" FontSize="15" Margin="0,10,0,0" />
+                                <Label x:Name="NoiseFilterLab" Content="噪点过滤:" Width="90" Height="30" FontSize="15" Margin="0,10,0,0" />
+                            </StackPanel>
+                            <StackPanel Orientation="Vertical" Margin="10,10,0,0">
+                                <TextBox x:Name="FormulationNameTbx" Width="100" Text="{Binding FormulationName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="30" FontSize="15" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="RegionThresholdTbx" Width="100" Text="{Binding RegionThreshold,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="ChannelTbx" Width="100" Text="{Binding Channel,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                                <TextBox x:Name="NoiseFilterTbx" Width="100" Text="{Binding NoiseFilter,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="30" FontSize="15" Margin="0,10,0,0" KeyDown="TextBox_KeyDown" />
+                            </StackPanel>
+                        </StackPanel>
+                        <Label Content="合格检测类型" Margin="10,170,0,0" FontSize="15" Height="30" VerticalAlignment="Top"/>
+                        <RadioButton x:Name="CheckModel1RadBtn" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="40,205,0,0" Content="不检测" FontSize="15" Checked="CheckModel1RadBtn_Checked" />
+                        <RadioButton x:Name="CheckModel2RadBtn" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="40,235,0,0" Content="通过长度检测" FontSize="15" Checked="CheckModel2RadBtn_Checked" />
+                        <RadioButton x:Name="CheckModel3RadBtn" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="40,265,0,0" Content="通过面积" FontSize="15" Checked="CheckModel3RadBtn_Checked" />
+                        <RadioButton x:Name="CheckModel4RadBtn" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="40,295,0,0" Content="通过长度面积检测" FontSize="15" Checked="CheckModel4RadBtn_Checked" />
+                        <StackPanel Orientation="Vertical" Height="60" VerticalAlignment="Top" Margin="0,320,0,0">
+                            <StackPanel x:Name="WHParaPanel" Orientation="Horizontal">
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="120" Content="合格长度范围:" FontSize="15" Margin="10,0,0,0"/>
+                                <TextBox x:Name="MIN_OBJECT_HEIGHT_TBX" Text="{Binding MIN_OBJECT_LENGTH,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="15" Margin="10,5,0,0" Width="70" KeyDown="TextBox_KeyDown"/>
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="15" Content="-" FontSize="15" Margin="10,0,0,0"/>
+                                <TextBox x:Name="MAX_OBJECT_HEIGHT_TBX" Text="{Binding MAX_OBJECT_LENGTH,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="15" Margin="10,5,0,0" Width="70" KeyDown="TextBox_KeyDown"/>
+                            </StackPanel>
+                            <StackPanel x:Name="AreaParaPanel" Orientation="Horizontal">
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="120" Content="合格粒面积范围:" FontSize="15" Margin="10,0,0,0"/>
+                                <TextBox x:Name="MinArea_TBX" Text="{Binding MinArea,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="15" Margin="10,4,0,0" Width="70" KeyDown="TextBox_KeyDown"/>
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="15" Content="-" FontSize="15" Margin="10,0,0,0"/>
+                                <TextBox x:Name="MaxArea_TBX" Text="{Binding MaxArea,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="15" Margin="10,4,0,0" Width="70" KeyDown="TextBox_KeyDown"/>
+                            </StackPanel>
+                        </StackPanel>
+                        <StackPanel Orientation="Vertical" Height="100" VerticalAlignment="Top" Margin="0,380,0,0">
+                            <StackPanel Orientation="Horizontal">
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="120" Content="标准药粒宽高:" FontSize="15" Margin="10,0,0,0"/>
+                            </StackPanel>
+                            <StackPanel x:Name="KeliLWPanel" Orientation="Horizontal">
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="30" Content="宽:" FontSize="15" Margin="10,0,0,0"/>
+                                <TextBox x:Name="KeLiW_TBX" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="15" Margin="10,4,0,0" Width="100" KeyDown="TextBox_KeyDown"/>
+                                <Label HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="30" Content="高:" FontSize="15" Margin="10,0,0,0"/>
+                                <TextBox x:Name="KeLiL_TBX" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" FontSize="15" Margin="10,4,0,0" Width="100" KeyDown="TextBox_KeyDown"/>
+                            </StackPanel>
+                            <StackPanel x:Name="ParametricTrainingPanel" Orientation="Horizontal" HorizontalAlignment="Right">
+                                <Button x:Name="ParametricTrainingBtn" Content="参数训练" Width="80" Height="35" Margin="0,2,10,0" Click="ParametricTrainingBtn_Click"/>
+                            </StackPanel>
+                        </StackPanel>
+                    </Grid>
+                </Grid>
+            </Grid>
+        </Grid>
+    </Grid>
+</Page>

+ 244 - 0
WpfSwitchLanguage/WpfPage/SettingPage.xaml.cs

@@ -0,0 +1,244 @@
+using CCDCount.DLL;
+using CCDCount.MODEL.CameraClass;
+using CCDCount.MODEL.ConfigModel;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// SettingPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class SettingPage : Page
+    {
+        public SettingPage()
+        {
+            InitializeComponent();
+            DataContext = ShowMessageBus.ShowBinding;
+        }
+
+        private void Page_Loaded(object sender, RoutedEventArgs e)
+        {
+            if (MessageBus.NowSettingLoadMainThread != null)
+            {
+                CamSelectConBox.SelectedValue = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+                if(MessageBus.NowSettingLoadMainThread.shuLiConfig.PandingCode == -1)
+                {
+                    CheckModel1RadBtn.IsChecked = true;
+                }
+                else if(MessageBus.NowSettingLoadMainThread.shuLiConfig.PandingCode == 0)
+                {
+                    CheckModel2RadBtn.IsChecked = true;
+                }
+                else if (MessageBus.NowSettingLoadMainThread.shuLiConfig.PandingCode == 1)
+                {
+                    CheckModel3RadBtn.IsChecked = true;
+                }
+                else if (MessageBus.NowSettingLoadMainThread.shuLiConfig.PandingCode == 2)
+                {
+                    CheckModel4RadBtn.IsChecked = true;
+                }
+            }
+            else
+            {
+                CamSelectConBox.SelectedValue = "";
+            }
+        }
+
+        private void CameraSettingBtn_Click(object sender, RoutedEventArgs e)
+        {
+            CameraSettingGrid.Visibility = Visibility.Visible;
+            ShuLiSettingGrid.Visibility = Visibility.Collapsed;
+        }
+
+        private void ShuLiSettingBtn_Click(object sender, RoutedEventArgs e)
+        {
+            CameraSettingGrid.Visibility = Visibility.Collapsed;
+            ShuLiSettingGrid.Visibility = Visibility.Visible;
+        }
+
+        private void CamListFlushBtn_Click(object sender, RoutedEventArgs e)
+        {
+            List<CameraInfoClass> CameraInfoList = new List<CameraInfoClass>();
+            MessageBus.CameraClass.GetCameraList(out CameraInfoList);
+            if (CameraInfoList.Count > 0)
+            {
+                ShowMessageBus.ShowBinding.CameraItems.Clear();
+                ShowMessageBus.ShowBinding.CameraItems.Add(new CameraCoboxItem() { Name = "请选择相机", SNValue = "" });
+                foreach (var item in CameraInfoList)
+                {
+                    ShowMessageBus.ShowBinding.CameraItems.Add(new CameraCoboxItem()
+                    {
+                        Name = item.DeviceName + "_" + item.DeviceSN,
+                        SNValue = item.DeviceSN
+                    });
+                }
+                CamSelectConBox.SelectedValue = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+            }
+        }
+
+        private void CamSelectConBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if(ShowMessageBus.ShowBinding.CameraItems.Count == 0) return;
+            //string ThisItemSN = ShowMessageBus.ShowBinding.CameraSNNum;
+            string ThisItemSN = CamSelectConBox.SelectedValue.ToString();
+            if (MessageBus.NowSettingLoadMainThread == null || ThisItemSN == MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum) return;
+            if (ThisItemSN != string.Empty && ThisItemSN != null)
+            {
+                if (MessageBus.NowSettingLoadMainThread.CameraRunStatic)
+                {
+                    var confirmResult = MessageBox.Show("检测到正在识别,切换相机需要关闭识别,是否继续切换",
+                                      "切换确认", MessageBoxButton.YesNo);
+                    if (confirmResult == MessageBoxResult.No)
+                    {
+                        CamSelectConBox.SelectedValue = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+                        return;
+                    }
+                    MessageBus.NowSettingLoadMainThread.StopMianThread();
+                }
+                if (MessageBus.NowSettingLoadMainThread.ReLoadCamera(ThisItemSN))
+                {
+                    MessageBus.NowSettingLoadMainThread.GetCameraConfig();
+                    ShowMessageBus.ShowBinding.ImageWidth = MessageBus.NowSettingLoadMainThread.cameraConfig.Width.ToString();
+                    ShowMessageBus.ShowBinding.CamUserName = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraName;
+                    ShowMessageBus.ShowBinding.CamOffsetX = MessageBus.NowSettingLoadMainThread.cameraConfig.OffsetX.ToString();
+                    ShowMessageBus.ShowBinding.ExposureTimeValue = MessageBus.NowSettingLoadMainThread.cameraConfig.ExposureTimeValue.ToString();
+                    ShowMessageBus.ShowBinding.AcquistionLineRate = MessageBus.NowSettingLoadMainThread.cameraConfig.AcquistionLineRateValue.ToString();
+                    ShowMessageBus.ShowBinding.CameraSNNum = ThisItemSN;
+                }
+                else
+                {
+                    MessageBox.Show("切换相机失败!");
+                    CamSelectConBox.SelectedItem = MessageBus.NowSettingLoadMainThread.cameraConfig.DeviceName + "_" + MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+                    return;
+                }
+            }
+            else
+            {
+                if (MessageBus.NowSettingLoadMainThread.CameraRunStatic)
+                {
+                    var confirmResult = MessageBox.Show("检测到正在识别,切换相机需要关闭识别,是否继续切换",
+                                      "切换确认", MessageBoxButton.YesNo);
+                    if (confirmResult == MessageBoxResult.No)
+                    {
+                        CamSelectConBox.SelectedValue = MessageBus.NowSettingLoadMainThread.cameraConfig.CameraSNNum;
+                        return;
+                    }
+                    MessageBus.NowSettingLoadMainThread.StopMianThread();
+                }
+                else
+                {
+                    MessageBus.NowSettingLoadMainThread.DisposeCamera();
+                }
+                ShowMessageBus.ShowBinding.ImageWidth = "0";
+                ShowMessageBus.ShowBinding.CamUserName = string.Empty;
+                ShowMessageBus.ShowBinding.CamOffsetX = "0";
+                ShowMessageBus.ShowBinding.ExposureTimeValue = "0";
+                ShowMessageBus.ShowBinding.AcquistionLineRate = "0";
+                ShowMessageBus.ShowBinding.CameraSNNum = null;
+            }
+        }
+
+        private void CheckModel1RadBtn_Checked(object sender, RoutedEventArgs e)
+        {
+            ShowMessageBus.ShowBinding.PandingCode = "-1";
+            WHParaPanel.Visibility = Visibility.Collapsed;
+            AreaParaPanel.Visibility = Visibility.Collapsed;
+        }
+
+        private void CheckModel2RadBtn_Checked(object sender, RoutedEventArgs e)
+        {
+            ShowMessageBus.ShowBinding.PandingCode = "0";
+            WHParaPanel.Visibility = Visibility.Visible;
+            AreaParaPanel.Visibility = Visibility.Collapsed;
+        }
+
+        private void CheckModel3RadBtn_Checked(object sender, RoutedEventArgs e)
+        {
+            ShowMessageBus.ShowBinding.PandingCode = "1";
+            WHParaPanel.Visibility = Visibility.Collapsed;
+            AreaParaPanel.Visibility = Visibility.Visible;
+        }
+
+        private void CheckModel4RadBtn_Checked(object sender, RoutedEventArgs e)
+        {
+            ShowMessageBus.ShowBinding.PandingCode = "2";
+            WHParaPanel.Visibility = Visibility.Visible;
+            AreaParaPanel.Visibility = Visibility.Visible;
+        }
+
+        //private void SaveAllConfigBtn_Click(object sender, RoutedEventArgs e)
+        //{
+        //    List<SaveConfigModel> SaveConfig = new List<SaveConfigModel>();
+        //    if(MessageBus.MainThreadS.Count <= 0)
+        //    {
+        //        return;
+        //    }
+        //    foreach (var item in MessageBus.MainThreadS)
+        //    {
+        //        SaveConfig.Add(new SaveConfigModel()
+        //        {
+        //            CameraConfig = item.cameraConfig,
+        //            ShuLiConfigClass = item.shuLiConfig
+        //        });
+        //    }
+        //    if (!Directory.Exists(".\\Config\\")) Directory.CreateDirectory(".\\Config\\");
+        //    {
+        //        XmlStorage.SerializeToXml(SaveConfig, ".\\Config\\CCDCountConfig.xml");
+        //    }
+        //}
+
+
+        /// <summary>
+        /// 加载配方
+        /// </summary>
+        /// <param name="FormulationConfig"></param>
+        private void LoadFormulation(FormulationConfigClass FormulationConfig)
+        {
+            ShowMessageBus.ShowBinding.AcquistionLineRate = FormulationConfig.AcquistionLineRateValue.ToString();
+            ShowMessageBus.ShowBinding.ExposureTimeValue = FormulationConfig.ExposureTimeValue.ToString();
+            ShowMessageBus.ShowBinding.Channel = FormulationConfig.Channel.ToString();
+            ShowMessageBus.ShowBinding.FormulationName = FormulationConfig.FormulationName;
+            ShowMessageBus.ShowBinding.MAX_OBJECT_LENGTH = FormulationConfig.MAX_Object_LENGTH.ToString();
+            ShowMessageBus.ShowBinding.MIN_OBJECT_LENGTH = FormulationConfig.MIN_Object_LENGTH.ToString();
+            ShowMessageBus.ShowBinding.PandingCode = FormulationConfig.PandingCode.ToString();
+            ShowMessageBus.ShowBinding.RegionThreshold = FormulationConfig.RegionThreshold.ToString();
+        }
+
+        private void ParametricTrainingBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if(string.IsNullOrEmpty(KeLiW_TBX.Text)||string.IsNullOrEmpty(KeLiL_TBX.Text))
+            {
+                MessageBox.Show("请输入标准颗粒的宽高");
+                return;
+            }
+            int KeliW = Convert.ToInt32(KeLiW_TBX.Text);
+            int KeliL = Convert.ToInt32(KeLiL_TBX.Text);
+            var paravalue = MessageBus.NowSettingLoadMainThread.ParameterTrain(KeliW, KeliL);
+            ShowMessageBus.ShowBinding.NoiseFilter = paravalue.NoiseFilterThreshold.ToString();
+            ShowMessageBus.ShowBinding.MaxArea = ((int)(paravalue.MaxArea*1.1)).ToString();
+            ShowMessageBus.ShowBinding.MinArea = ((int)(paravalue.MinArea*0.9)).ToString();
+            ShowMessageBus.ShowBinding.MAX_OBJECT_LENGTH = ((int)(paravalue.MaxLength*1.1)).ToString();
+            ShowMessageBus.ShowBinding.MIN_OBJECT_LENGTH = ((int)(paravalue.MinLength*0.9)).ToString();
+        }
+        private void TextBox_KeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key == Key.Enter)
+            {
+                TextBox textBox = sender as TextBox;
+                if (textBox != null)
+                {
+                    // 强制更新源数据
+                    BindingExpression bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
+                    bindingExpression.UpdateSource();
+                }
+            }
+        }
+    }
+}

+ 51 - 0
WpfSwitchLanguage/WpfPage/UserManagementPage.xaml

@@ -0,0 +1,51 @@
+<Page x:Class="CCDCountWpf.WpfPage.UserManagementPage"
+      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:CCDCountWpf.WpfPage"
+      mc:Ignorable="d" 
+      d:DesignHeight="450" d:DesignWidth="800"
+      Title="UserManagementPage">
+    <Grid>
+        <Grid Height="30" VerticalAlignment="Top">
+            <StackPanel Orientation="Horizontal">
+                <Button x:Name="AddUserBtn" HorizontalAlignment="Left" Height="25" Width="25" Background="{x:Null}" Click="AddUserBtn_Click">
+                    <StackPanel Orientation="Vertical">
+                        <Image  Source="/FromImage/用户增加.png"/>
+                    </StackPanel>
+                </Button>
+                <Button x:Name="DeleteUserBtn" HorizontalAlignment="Left" Height="25" Width="25" Background="{x:Null}" Click="DeleteUserBtn_Click">
+                    <StackPanel Orientation="Vertical">
+                        <Image  Source="/FromImage/用户删除.png"/>
+                    </StackPanel>
+                </Button>
+                <Button x:Name="ChangeUserBtn" HorizontalAlignment="Left" Height="25" Width="25" Background="{x:Null}" Click="ChangeUserBtn_Click">
+                    <StackPanel Orientation="Vertical">
+                        <Image  Source="/FromImage/用户修改.png"/>
+                    </StackPanel>
+                </Button>
+            </StackPanel>
+        </Grid>
+        <DataGrid x:Name="UserMessageDataGrid" ItemsSource="{Binding UserMesDataModels}" AutoGenerateColumns="False" Margin="0,30,0,0" SelectionMode="Single"
+            SelectionUnit="FullRow" SelectionChanged="DataGrid_SelectionChanged">
+            <!-- 添加行样式 -->
+            <DataGrid.RowStyle>
+                <Style TargetType="DataGridRow">
+                    <Style.Triggers>
+                        <Trigger Property="IsSelected" Value="True">
+                            <!-- 设置蓝色背景和白色文字 -->
+                            <Setter Property="Background" Value="DodgerBlue"/>
+                            <Setter Property="Foreground" Value="White"/>
+                        </Trigger>
+                    </Style.Triggers>
+                </Style>
+            </DataGrid.RowStyle>
+            <DataGrid.Columns>
+                <DataGridTextColumn Header="ID" Binding="{Binding Id}" />
+                <DataGridTextColumn Header="用户名" Binding="{Binding UserName}" />
+                <DataGridTextColumn Header="用户信息" Binding="{Binding UserMes}" />
+            </DataGrid.Columns>
+        </DataGrid>
+    </Grid>
+</Page>

+ 81 - 0
WpfSwitchLanguage/WpfPage/UserManagementPage.xaml.cs

@@ -0,0 +1,81 @@
+using CCDCount.MODEL.SqlDataModel;
+using CCDCountWpf.WpfFrom;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// UserManagementPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class UserManagementPage : Page
+    {
+        UserMesDataModelClass SelectUserMessage = null;
+        public UserManagementPage()
+        {
+            InitializeComponent();
+            DataContext = ShowMessageBus.ShowBinding;
+            ShowMessageBus.ShowBinding.UserMesDataModels = MessageBus.UserMessageClass.GetAllUserMessage();
+        }
+
+        private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            var selectedItem = UserMessageDataGrid.SelectedItem as UserMesDataModelClass; // 替换为实际数据类型
+            if (selectedItem != null)
+            {
+                SelectUserMessage = selectedItem;
+            }
+        }
+
+        private void ChangeUserBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (SelectUserMessage.Id == 1&&MessageBus.NowLoginUserMessage.Id != 1)
+            {
+                MessageBox.Show("权限不足,不可操作Admin用户");
+                return;
+            }
+            if (SelectUserMessage == null)
+            {
+                MessageBox.Show("请选择用户");
+                return;
+            }
+            ChangeUserWindow changeUserWindow = new ChangeUserWindow();
+            changeUserWindow.UserMessage = SelectUserMessage;
+            changeUserWindow.ShowDialog();
+        }
+
+        private void DeleteUserBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (SelectUserMessage.Id == 1)
+            {
+                MessageBox.Show("Admin管理员账户,不可删除");
+                return;
+            }
+            if (SelectUserMessage == null)
+            {
+                MessageBox.Show("请选择用户");
+                return;
+            }
+            MessageBus.UserMessageClass.DeleteUserMessage(SelectUserMessage.Id);
+            ShowMessageBus.ShowBinding.UserMesDataModels = MessageBus.UserMessageClass.GetAllUserMessage();
+        }
+
+        private void AddUserBtn_Click(object sender, RoutedEventArgs e)
+        {
+            AddUserWindow addUserWindow = new AddUserWindow();
+            addUserWindow.ShowDialog();
+        }
+    }
+}

+ 338 - 0
WpfSwitchLanguage/WpfSwitchLanguage.csproj

@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{91D2CF08-1B12-4B8F-81F0-13F1C16FDB0A}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>CCDCountWpf</RootNamespace>
+    <AssemblyName>CCDCountWpf</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>x64</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationIcon>23s6k-ono7l-001.ico</ApplicationIcon>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>7.3</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationManifest>app.manifest</ApplicationManifest>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MvCameraControl.Net, Version=4.3.2.2, Culture=neutral, PublicKeyToken=a3c7c5e3a730cd12, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\TestWork.DLL\DLL\MvCameraControl.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="MvFGCtrlC.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=52fddfb3f94be800, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\TestWork.DLL\DLL\MvFGCtrlC.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Compile Include="PlcMessageShowBindingClass.cs" />
+    <Compile Include="WpfFrom\AddUserWindow.xaml.cs">
+      <DependentUpon>AddUserWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfFrom\ChangeUserWindow.xaml.cs">
+      <DependentUpon>ChangeUserWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfFrom\SplashWindow.xaml.cs">
+      <DependentUpon>SplashWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfFrom\UserLoginWindow.xaml.cs">
+      <DependentUpon>UserLoginWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\AuditTrailPage.xaml.cs">
+      <DependentUpon>AuditTrailPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\HistoryDataPage.xaml.cs">
+      <DependentUpon>HistoryDataPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\MessagePage.xaml.cs">
+      <DependentUpon>MessagePage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\PlcOperationPage.xaml.cs">
+      <DependentUpon>PlcOperationPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\PlcSettingPage.xaml.cs">
+      <DependentUpon>PlcSettingPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\SettingPage.xaml.cs">
+      <DependentUpon>SettingPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfPage\UserManagementPage.xaml.cs">
+      <DependentUpon>UserManagementPage.xaml</DependentUpon>
+    </Compile>
+    <Page Include="WpfFrom\AddUserWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfFrom\ChangeUserWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfFrom\SplashWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfFrom\UserLoginWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\AuditTrailPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\HistoryDataPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\MainPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfFrom\MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ShowBindingClass.cs" />
+    <Compile Include="WpfPage\MainPage.xaml.cs">
+      <DependentUpon>MainPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="WpfFrom\MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Page Include="WpfPage\MessagePage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\PlcOperationPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\PlcSettingPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\SettingPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="WpfPage\UserManagementPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="app.manifest" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\数据.png" />
+    <Resource Include="FromImage\相机小_黑.png" />
+    <Resource Include="FromImage\设置.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\退出.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\中断.png" />
+    <Resource Include="FromImage\运行.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\TestWork.DLL\CCDCount.DLL.csproj">
+      <Project>{e7f2647e-07d6-41f2-81fd-fa32da6d2526}</Project>
+      <Name>CCDCount.DLL</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\TestWork.MODEL\CCDCount.MODEL.csproj">
+      <Project>{c230b744-cabc-4b34-80bb-2cee55a8b2b9}</Project>
+      <Name>CCDCount.MODEL</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\刷新.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\暂停.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\故障.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\export.png" />
+    <Resource Include="FromImage\print.png" />
+    <Resource Include="FromImage\用户修改.png" />
+    <Resource Include="FromImage\用户删除.png" />
+    <Resource Include="FromImage\用户增加.png" />
+    <Resource Include="FromImage\用户管理.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\mmexport1752891278116.jpg" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\PLC信息管理.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\菜单_灰.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\退出_灰.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\相机小_灰.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\菜单_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\相机小_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\数据_白.png" />
+    <Resource Include="FromImage\设置_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\退出_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\PLC信息管理_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\故障_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\用户管理_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\键盘_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\23s6k-ono7l-001.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="23s6k-ono7l-001.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\审计信息审计_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\操作_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="EntityFramework">
+      <Version>6.5.1</Version>
+    </PackageReference>
+    <PackageReference Include="Microsoft.Web.WebView2">
+      <Version>1.0.3485.44</Version>
+    </PackageReference>
+    <PackageReference Include="Stub.System.Data.SQLite.Core.NetFramework">
+      <Version>1.0.119</Version>
+    </PackageReference>
+    <PackageReference Include="System.Data.SQLite">
+      <Version>1.0.119</Version>
+    </PackageReference>
+    <PackageReference Include="System.Data.SQLite.Core">
+      <Version>1.0.119</Version>
+    </PackageReference>
+    <PackageReference Include="System.Data.SQLite.EF6">
+      <Version>1.0.119</Version>
+    </PackageReference>
+    <PackageReference Include="System.Data.SQLite.Linq">
+      <Version>1.0.119</Version>
+    </PackageReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 79 - 0
WpfSwitchLanguage/app.manifest

@@ -0,0 +1,79 @@
+<?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="requireAdministrator" uiAccess="false" />
+      </requestedPrivileges>
+    </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>