Browse Source

20260415001 异地备份

向羽 孟 2 weeks ago
parent
commit
0ea836c972
37 changed files with 2414 additions and 1308 deletions
  1. 5 1
      TestWork.DLL/AlarmTools/AlarmMessageList.cs
  2. 41 2
      TestWork.DLL/AlarmTools/SystemAlarm.cs
  3. 2 1
      TestWork.DLL/CCDCount.DLL.csproj
  4. 3 5
      TestWork.DLL/CameraClass.cs
  5. 80 11
      TestWork.DLL/CanBus/CanManagerClass.cs
  6. 274 130
      TestWork.DLL/MainThreadClass.cs
  7. 113 18
      TestWork.DLL/PLCManagementClass.cs
  8. 78 658
      TestWork.DLL/ShuLiClass.cs
  9. 173 10
      TestWork.DLL/SqlDataClass/ActionMesSqliteDataClass.cs
  10. 198 1
      TestWork.DLL/Tools/AutoStartHelper.cs
  11. 5 4
      TestWork.DLL/Tools/ConfigManager.cs
  12. 128 6
      TestWork.DLL/Tools/OnScreenKeyboardClass.cs
  13. 0 19
      TestWork.DLL/packages.config
  14. 19 0
      TestWork.MODEL/PlcModel/PlcAlarmModelClass.cs
  15. 16 0
      TestWork.MODEL/PlcModel/PlcParaModelClass.cs
  16. 0 66
      TestWork.MODEL/PlcModel/PlcStaticModelClass.cs
  17. 11 2
      TestWork.MODEL/ShuLiModel/ActiveObjectClass.cs
  18. 10 2
      WpfSwitchLanguage/Language/String_Chinese.xaml
  19. 8 0
      WpfSwitchLanguage/Language/String_English.xaml
  20. 80 0
      WpfSwitchLanguage/PlcMessageShowBindingClass.cs
  21. 23 5
      WpfSwitchLanguage/Style/Styles.xaml
  22. 13 0
      WpfSwitchLanguage/WpfFrom/LoadingWindow.xaml
  23. 32 0
      WpfSwitchLanguage/WpfFrom/LoadingWindow.xaml.cs
  24. 7 7
      WpfSwitchLanguage/WpfFrom/MainWindow.xaml
  25. 285 121
      WpfSwitchLanguage/WpfFrom/MainWindow.xaml.cs
  26. 1 0
      WpfSwitchLanguage/WpfFrom/StartWindow.xaml
  27. 35 5
      WpfSwitchLanguage/WpfFrom/StartWindow.xaml.cs
  28. 1 1
      WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml
  29. 9 6
      WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml.cs
  30. 20 2
      WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml
  31. 81 7
      WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml.cs
  32. 2 2
      WpfSwitchLanguage/WpfPage/MainPage.xaml
  33. 197 54
      WpfSwitchLanguage/WpfPage/MainPage.xaml.cs
  34. 155 111
      WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml
  35. 290 46
      WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml.cs
  36. 12 5
      WpfSwitchLanguage/WpfPage/SettingPage.xaml.cs
  37. 7 0
      WpfSwitchLanguage/WpfSwitchLanguage.csproj

+ 5 - 1
TestWork.DLL/AlarmTools/AlarmMessageList.cs

@@ -43,6 +43,10 @@ namespace CCDCount.DLL.AlarmTools
         传动轴伺服报警 = 31,
         堵瓶停机 = 32,
         缺瓶停机 = 33,
-        等待复位 = 34
+        等待复位 = 34,
+        CAN连接失败 = 35,
+        视觉未启动 = 36,
+        颗粒缓存超限 = 37,
+        PLC连接中 = 38
     }
 }

+ 41 - 2
TestWork.DLL/AlarmTools/SystemAlarm.cs

@@ -146,6 +146,14 @@ namespace CCDCount.DLL.AlarmTools
                 IsAlarm =false
             },
             new AlarmMessModel()
+            {
+                ID = (int)AlarmMessageList.CAN连接失败,
+                AlarmName = "CAN连接失败",
+                AlarmEnType = "SystemException",
+                AlarmChType = "系统",
+                IsAlarm =false
+            },
+            new AlarmMessModel()
             {
                 ID = (int)AlarmMessageList.气压压力检测开关报警,
                 AlarmName = "气压压力检测开关报警",
@@ -202,6 +210,22 @@ namespace CCDCount.DLL.AlarmTools
                 IsAlarm =false
             },
             new AlarmMessModel()
+            {
+                ID = (int)AlarmMessageList.视觉未启动,
+                AlarmName = "视觉未启动",
+                AlarmEnType = "PlcException",
+                AlarmChType = "PLC报警",
+                IsAlarm =false
+            },
+            new AlarmMessModel()
+            {
+                ID = (int)AlarmMessageList.颗粒缓存超限,
+                AlarmName = "颗粒缓存超限",
+                AlarmEnType = "PlcException",
+                AlarmChType = "PLC报警",
+                IsAlarm =false
+            },
+            new AlarmMessModel()
             {
                 ID = (int)AlarmMessageList.数粒超大粒,
                 AlarmName = "数粒超大粒",
@@ -289,7 +313,6 @@ namespace CCDCount.DLL.AlarmTools
                 AlarmChType = "PLC报警",
                 IsAlarm =false
             },
-
             new AlarmMessModel()
             {
                 ID = (int)AlarmMessageList.等待复位,
@@ -298,6 +321,14 @@ namespace CCDCount.DLL.AlarmTools
                 AlarmChType = "PLC报警",
                 IsAlarm =false
             },
+            new AlarmMessModel()
+            {
+                ID = (int)AlarmMessageList.PLC连接中,
+                AlarmName = "PLC连接中",
+                AlarmEnType = "SystemException",
+                AlarmChType = "系统",
+                IsAlarm =false
+            },
         };
 
         /// <summary>
@@ -331,6 +362,11 @@ namespace CCDCount.DLL.AlarmTools
             AlarmMessList.Find(x => x.ID == (int)ID).IsAlarm = false;
         }
 
+        public static bool CheckAlarmStatic(AlarmMessageList ID)
+        {
+            return AlarmMessList.Find(x => x.ID == (int)ID).IsAlarm;
+        }
+
         public static void AlarmCancelByTime(AlarmMessageList ID,int DelayTime)
         {
             var CancelValue = AlarmMessList.Find(x => x.ID == (int)ID);
@@ -340,7 +376,10 @@ namespace CCDCount.DLL.AlarmTools
             }
         }
 
-
+        /// <summary>
+        /// 关闭超时的视觉报警
+        /// </summary>
+        /// <param name="DelayTime"></param>
         public static void AllVisionAlarmCancel(int DelayTime)
         {
             foreach (var alarm in AlarmMessList)

+ 2 - 1
TestWork.DLL/CCDCount.DLL.csproj

@@ -28,11 +28,12 @@
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
+    <Optimize>false</Optimize>
     <OutputPath>bin\Release\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
     <DebugSymbols>true</DebugSymbols>

+ 3 - 5
TestWork.DLL/CameraClass.cs

@@ -156,8 +156,7 @@ namespace CCDCount.DLL
                     device.Parameters.SetStringValue("DeviceUserID", DeviceConfig.CameraName);
                 device.Parameters.SetFloatValue("ExposureTime", DeviceConfig.ExposureTimeValue);
                 device.Parameters.SetIntValue("AcquisitionLineRate", DeviceConfig.AcquistionLineRateValue);
-                device.Parameters.GetIntValue("Height", out IIntValue height);
-                device.Parameters.SetIntValue("Height", height.Min);
+                device.Parameters.SetIntValue("Height", DeviceConfig.Height);
                 device.Parameters.SetIntValue("OffsetX", DeviceConfig.OffsetX);
                 device.Parameters.SetIntValue("Width", DeviceConfig.Width);
             }
@@ -254,8 +253,7 @@ namespace CCDCount.DLL
                     device.Parameters.SetStringValue("DeviceUserID", RecameraConfig.CameraName);
                 device.Parameters.SetFloatValue("ExposureTime", RecameraConfig.ExposureTimeValue);
                 device.Parameters.SetIntValue("AcquisitionLineRate", RecameraConfig.AcquistionLineRateValue);
-                device.Parameters.GetIntValue("Height", out IIntValue height);
-                device.Parameters.SetIntValue("Height", height.Min);
+                device.Parameters.SetIntValue("Height", RecameraConfig.Height);
                 device.Parameters.SetIntValue("OffsetX", RecameraConfig.OffsetX);
                 device.Parameters.SetIntValue("Width", RecameraConfig.Width);
                 // 设置采集连续模式
@@ -533,7 +531,7 @@ namespace CCDCount.DLL
             try
             {
                 if (device == null) return result;
-                device.StreamGrabber.SetImageNodeNum(30);
+                device.StreamGrabber.SetImageNodeNum(500);
 
                 device.StreamGrabber.FrameGrabedEvent += FrameGrabbedEventHandler;
 

+ 80 - 11
TestWork.DLL/CanBus/CanManagerClass.cs

@@ -1,4 +1,6 @@
-using System;
+using CCDCount.DLL.AlarmTools;
+using LogClass;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -12,7 +14,6 @@ namespace CCDCount.DLL.CanBus
         UInt32 m_devind = 0;
         UInt32 m_canind = 0;
         int DataLen = 8;
-        int SendCount = 0;
 
         VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();
 
@@ -38,37 +39,105 @@ namespace CCDCount.DLL.CanBus
             if (CanLibraryClass.VCI_InitCAN(m_devtype, m_devind, m_canind, ref config) == 0)
             {
                 Console.WriteLine("初始化Can失败");
+                SystemAlarm.AlarmAlert(AlarmMessageList.CAN连接失败,"CAN Connect Error", "CAN连接失败","CanManagerClass-InitCan");
                 return;
             }
             if (CanLibraryClass.VCI_StartCAN(m_devtype, m_devind, m_canind) == 0)
             {
                 Console.WriteLine("开启Can失败");
+                SystemAlarm.AlarmAlert(AlarmMessageList.CAN连接失败, "CAN Connect Error", "CAN连接失败", "CanManagerClass-InitCan");
                 return;
             }
+            SystemAlarm.AlarmCancel(AlarmMessageList.CAN连接失败);
         }
 
-        public unsafe void SenMessage(byte[] bytes)
+        public unsafe bool SenMessage(CanSenMessage senMessage)
         {
+            bool result = false;
             VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
             sendobj.RemoteFlag = (byte)(0);
             sendobj.ExternFlag = (byte)(0);
-            sendobj.ID = Convert.ToUInt32(Convert.ToString(SendCount, 16), 16);
-            sendobj.DataLen = Convert.ToByte(bytes.Length > 8 ? 8 : bytes.Length);
-            for (int i = 0; i < DataLen; i++)
-            {
-                sendobj.Data[i] = bytes[i];
-            }
+            sendobj.ID = Convert.ToUInt32(Convert.ToString(0, 16), 16);
+            sendobj.DataLen = Convert.ToByte(DataLen);
+            string str = "";
+
+            byte SendMessage0 = new byte();
+            SendMessage0 = senMessage.SendDate;
+            sendobj.Data[0] = SendMessage0;
+
+            //byte SendMessage1 = new byte();
+            //SendMessage1 |= (byte)(1 << 0);
+            //sendobj.Data[1] = SendMessage1;
+
+            byte SendMessage6 = new byte();
+            SendMessage6 = (byte)(1 << 0);
+            sendobj.Data[6] = SendMessage6;
+
+            byte SendMessage7 = new byte();
+            if (!senMessage.IsOK)
+                SendMessage7 |= (byte)(1 << senMessage.TaiHao);
+            sendobj.Data[7] = SendMessage7;
+
+            str += "发送数据:";
+            str += string.Format("byte0:{0},byte6:{1},byte7:{2}",
+                SendMessage0.ToString("000"),
+                SendMessage6.ToString("000"), SendMessage7.ToString("000"));
+
 
             if (CanLibraryClass.VCI_Transmit(m_devtype, m_devind, m_canind, ref sendobj, 1) == 0)
             {
                 Console.WriteLine("发送失败");
-                return;
+                return result;
+            }
+            LOG.log(str, 6);
+            result = true;
+            return result;
+        }
+
+        int previousWriteDone = 0;
+        public unsafe bool GetTrigger(ref bool isFrist)
+        {
+            bool result = false;
+            UInt32 res = new UInt32();
+            VCI_CAN_OBJ[] m_recobj = new VCI_CAN_OBJ[1000];
+            res = CanLibraryClass.VCI_Receive(m_devtype, m_devind, m_canind, ref m_recobj[0], 1000, 100);
+            if (res == 0xFFFFFFFF) res = 0;
+            if (res != 0)
+            {
+                for (UInt32 i = 0; i < res; i++)
+                {
+                    if (m_recobj[i].RemoteFlag == 0)
+                    {
+                        int writeDone = -1;
+                        fixed (VCI_CAN_OBJ* m_recobj1 = &m_recobj[i])
+                        {
+                            writeDone = m_recobj1->Data[6] & 0x01;
+                            if(isFrist)
+                            {
+                                previousWriteDone = writeDone == 0 ? 1 : 0;
+                                isFrist = false;
+                                LOG.log(string.Format(
+                                    "通讯状态初始化,prevateWriteDone:{0},WriteDone:{1},IsFrist:{2}",
+                                    previousWriteDone, writeDone, isFrist), 6);
+                            }
+                        }
+                        if ((writeDone == 1 && previousWriteDone == 0) || (writeDone == 0 && previousWriteDone == 1))
+                        {
+                            result = true;
+                        }
+                        previousWriteDone = writeDone;
+                    }
+                }
             }
+            return result;
         }
 
         public void CloseCan()
         {
-            CanLibraryClass.VCI_ResetCAN(m_devtype, m_devind, m_canind);
+            if(CanLibraryClass.VCI_ResetCAN(m_devtype, m_devind, m_canind)==0)
+            {
+                LOG.error("CAN关闭失败");
+            }
         }
     }
 }

+ 274 - 130
TestWork.DLL/MainThreadClass.cs

@@ -1,4 +1,5 @@
 using CCDCount.DLL.AlarmTools;
+using CCDCount.DLL.CanBus;
 using CCDCount.DLL.SqlDataClass;
 using CCDCount.DLL.Tools;
 using CCDCount.MODEL.CameraClass;
@@ -23,7 +24,6 @@ namespace CCDCount.DLL
     public class MainThreadClass
     {
         #region 变量与实例
-        Thread SwitchIdentifyImageThread = null;
         private bool IsSwitch = false;
         public ShuLiClass shuLiClass = null;
         CameraClass cameraClass = new CameraClass();
@@ -99,6 +99,7 @@ namespace CCDCount.DLL
         // 颗粒结果待发送队列
         //ConcurrentQueue<ushort> SendQueue = new ConcurrentQueue<ushort>();
         ConcurrentQueue<TestSenMessage> SendQueue = new ConcurrentQueue<TestSenMessage>();
+        ConcurrentQueue<CanSenMessage> CanSendQueue = new ConcurrentQueue<CanSenMessage>();
 
         /// <summary>
         /// 数粒状态计时器
@@ -148,17 +149,8 @@ namespace CCDCount.DLL
                 }
                 SystemAlarm.AlarmCancel(AlarmMessageList.数粒通讯连接失败);
                 LOG.log("数粒通讯成功", 6);
-                //FaultLog.RecordLogMessage($"Modbus通讯连接成功,目标IP:{ipAddress}",6);
                 IsConnectModbus = true;
             });
-            //if (!modbusTcpClient.Connect(ipAddress))
-            //{
-            //    //FaultLog.RecordErrorMessage($"MianThread{cameraConfig.CamerNo}-Modbus通讯连接失败,目标IP:{ipAddress}");
-            //    SystemAlarm.AlarmAlert(AlarmMessageList.PLC通讯连接失败, $"Modbus通讯连接失败,目标IP:{ipAddress}", "DLL:MainThreadClass-ConnectModbus");
-            //    return;
-            //}
-            //IsConnectModbus = true;
-            //SystemAlarm.AlarmCancel(AlarmMessageList.PLC通讯连接失败);
         }
 
         /// <summary>
@@ -283,14 +275,13 @@ namespace CCDCount.DLL
                     return result;
                 }
                 _CameraStatic = true;
-                StartSendBottLogicMessageThread();
+                StartCanSendBottLogicMessageThread();
 
-                // 数据交换线程开启
-                //StartSwitchThread();
                 // 为数粒算法的识别成功一粒回调函数添加方法
-                shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
+                //shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
+                shuLiClass.WorkCompleted += Worker_OneGrainCompletedUseCan;
                 // 开启识别线程
-                shuLiClass.StartIdentifyFuntion2(cameraClass.GetCamereImageSize().Width);
+                shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width);
                 result = true;
             }
             catch(Exception ex)
@@ -310,18 +301,22 @@ namespace CCDCount.DLL
             {
 
                 // 数粒识别线程关闭
-                shuLiClass.StopIdentifyFuntion2();
+                shuLiClass.StopIdentifyFuntion();
+                LOG.log("执行数粒识别线程关闭成功",6);
                 _CameraStatic = false;
-                shuLiClass.WorkCompleted -= Worker_OneGrainCompleted;
+                //shuLiClass.WorkCompleted -= Worker_OneGrainCompleted;
+                shuLiClass.WorkCompleted -= Worker_OneGrainCompletedUseCan;
+                LOG.log("识别回调取消完成",6);
                 // 相机取图关闭
                 cameraClass.StopCamera();
                 cameraClass.FrameGrabbedEvent -= SwitchIdentifyImageEvent;
+                LOG.log("相机回调取消完成", 6);
                 IsSwitch = false;
-                // 数据交换线程关闭
-                //StopSwitchThread();
                 StopSendBottLogicMessageThread();
+                LOG.log("发送线程关闭完成", 6);
                 result = true;
                 actionMesSqliteDataClass.Dispose();
+                LOG.log("批处理实例释放完成", 6);
             }
             catch(Exception ex)
             {
@@ -991,90 +986,199 @@ namespace CCDCount.DLL
             }
         }
 
-
-        #endregion
-
-        #region 线程方法
-
-        /// <summary>
-        /// 开启交换线程
-        /// </summary>
-        private void StartSwitchThread()
-        {
-            IsSwitch = true;
-            shuLiClass.QueueSemaphore = new SemaphoreSlim(0);
-            SwitchIdentifyImageThread = new Thread(SwitchIdentifyImageProcess)
-            {
-                Priority = ThreadPriority.AboveNormal
-            };
-            SwitchIdentifyImageThread.Start();
-        }
-
         /// <summary>
-        /// 关闭交换线程
+        /// 每数完一粒识别线程执行的事件
         /// </summary>
-        private void StopSwitchThread()
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void Worker_OneGrainCompletedUseCan(object sender, ActiveObjectEventArgsClass e)
         {
-            try
+            //LOG.log("有活跃物体转换为了历史物体,回调事件被触发!", 6);
+            //LOG.log(string.Format("图像处理实例中的待识别图像缓存队列长度{0}", shuLiClass.ImageNum), 6);
+            if (e.Actives.Where(o => o.StateCode == 7).Count() > 0)
             {
-                // 标志位设为false
-                IsSwitch = false;
-                if (SwitchIdentifyImageThread != null && SwitchIdentifyImageThread.IsAlive)
-                    SwitchIdentifyImageThread.Join();
-                SystemAlarm.AlarmCancel(AlarmMessageList.数据分配线程停止失败);
+                stopwatch.Restart();
+                _ShuLiState = false;
             }
-            catch (Exception ex)
+            else if (stopwatch.ElapsedMilliseconds > 1000)
             {
-                SystemAlarm.AlarmAlert(AlarmMessageList.数据分配线程停止失败, 
-                    "stop thread failed!, " + ex.Message,
-                    "数据分配线程停止失败:" + ex.Message,
-                    "DLL:MainThreadClass-StopSwitchThread");
-                //FaultLog.RecordErrorMessage("MainThreadClass-StopSwitchThread:Stop thread failed!, " + ex.Message);
-                Console.WriteLine("MainThreadClass-StopSwitchThread:Stop thread failed!, " + ex.Message);
-                throw;
+                stopwatch.Stop();
+                _ShuLiState = true;
             }
-        }
-
-        /// <summary>
-        /// 交换线程
-        /// </summary>
-        private void SwitchIdentifyImageProcess()
-        {
-            while (IsSwitch)
+            var Hset = new HashSet<int>();
+            byte result = new byte();
+            bool IsOK = false;
+            // 事件处理逻辑
+            foreach (ActiveObjectClass oneActive in e.Actives)
             {
-                bool result = cameraClass.GetOnceImage(out IFrameOut IFramedata);
-                if (result)
+                //往数组中计数
+                var UseTime = (oneActive.EndCheckTime - oneActive.StartCheckTime).TotalMilliseconds;
+                var QutuYanshiTime = (DateTime.Now - oneActive.PictureEndReadTime).TotalMilliseconds;
+                if (BatchNumber != "") oneActive.BatchNumber = BatchNumber;
+                LOG.log(string.Format("输出当前颗粒信息,颗粒编号:{0},开始时间:{1},第一张图像读取时间:{2},\n" +
+                    "识别耗时:{3},尾图到输出的时间:{4},颗粒状态:{5},通道数:{6}",
+                    oneActive.Num, oneActive.StartCheckTime.ToString("O"), oneActive.PictureStartReadTime.ToString("O"),
+                    UseTime.ToString(), QutuYanshiTime.ToString(), oneActive.StateCode, oneActive.ChannelNO), 6);
+                if (QutuYanshiTime > 30)
+                {
+                    //LOG.error($"结果输出延时超过了30ms,耗时{QutuYanshiTime}");
+                    Console.WriteLine($"结果输出延时超过了30ms,耗时{QutuYanshiTime}");
+                }
+                switch (oneActive.StateCode)
                 {
-                    //Debug模式,不进行图像处理
-                    if (_IsDebug)
+                    case 1:
+                        SystemAlarm.AlarmAlert(AlarmMessageList.数粒超长粒,
+                            "Counting extra-long particles",
+                            "数粒超长粒",
+                            "MianThreadClass-Worker_OneGrainCompleted");
+                        break;
+                    case 2:
+                        SystemAlarm.AlarmAlert(AlarmMessageList.数粒超短粒,
+                            "Counting ultra-short particles",
+                            "数粒超短粒",
+                            "MianThreadClass-Worker_OneGrainCompleted");
+                        break;
+                    case 5:
+                        SystemAlarm.AlarmAlert(AlarmMessageList.数粒超大粒,
+                            "Counting extra-large particles",
+                            "数粒超大粒",
+                            "MianThreadClass-Worker_OneGrainCompleted");
+                        break;
+                    case 6:
+                        SystemAlarm.AlarmAlert(AlarmMessageList.数粒超小粒,
+                            "Counting ultra-small particles",
+                            "数粒超小粒",
+                            "MianThreadClass-Worker_OneGrainCompleted");
+                        break;
+                    case 8:
+                        SystemAlarm.AlarmAlert(AlarmMessageList.疑似叠粒,
+                            "Count overlapping particles",
+                            "疑似叠粒",
+                            "MianThreadClass-Worker_OneGrainCompleted");
+                        break;
+                    case 10:
+                        SystemAlarm.AlarmAlert(AlarmMessageList.丢帧颗粒,
+                            "Counting frame loss particles",
+                            "丢帧颗粒",
+                            "MianThreadClass-Worker_OneGrainCompleted");
+                        break;
+                }
+
+                //记录到数据库
+                ThreadPool.QueueUserWorkItem(_ =>
+                {
+                    if (actionMesSqliteDataClass != null)
                     {
-                        _images.Enqueue(IFramedata);
-                        if (_images.Count > 5)
+                        try
+                        {
+                            actionMesSqliteDataClass.InsertActiveObject(oneActive);
+                        }
+                        catch (Exception ex)
                         {
-                            _images.TryDequeue(out IFrameOut image);
-                            image.Dispose();
+                            LOG.error("MianThread-Worker_OneGrainCompleted-Task:" + ex.Message);
                         }
                     }
-                    if (IFramedata == null)
+                });
+
+                if (!Hset.Add(oneActive.ChannelNO))
+                {
+                    //有重复的通道的异常记录流程
+                    var EResult = new byte();
+                    bool EIsOK = false;
+                    //正常运行流程
+                    if (oneActive.ChannelNO == -1)
+                    {
+                        //FaultLog.RecordErrorMessage("颗粒通道判定异常");
+                        FaultLog.RecordErrorMessage("Abnormal particle channel determination");
                         continue;
-                    shuLiClass.SetOnceIdentifyImageData2(IFramedata);
-                    shuLiClass.QueueSemaphore.Release(); // 通知处理线程有新数据
+                    }
+                    if (oneActive.StateCode == 0)
+                    {
+                        //单通道合格计数
+                        EResult |= (byte)(1 << oneActive.ChannelNO);
+                        EIsOK = true;
+                    }
+                    else
+                    {
+                        if (oneActive.StateCode != 7 && oneActive.StateCode != 9)
+                        {
+                            //单通道不合格计数
+                            EResult |= (byte)(1 << (oneActive.ChannelNO));
+                        }
+                        else if (oneActive.StateCode == 7)
+                        {
+                            //FaultLog.RecordErrorMessage("视野存在遮挡,请检查相机");
+                            FaultLog.RecordErrorMessage("The field of view is obstructed. Please check the camera");
+                        }
+                    }
+                    CanSendQueue.Enqueue(new CanSenMessage()
+                    {
+                        SendDate = EResult,
+                        IsOK = EIsOK,
+                        TaiHao = 0
+                    });
+                    continue;
                 }
                 else
-                    continue;
-                IFramedata.Dispose();
+                {
+                    //正常运行流程
+                    if (oneActive.ChannelNO == -1)
+                    {
+                        //FaultLog.RecordErrorMessage("颗粒通道判定异常");
+                        FaultLog.RecordErrorMessage("Abnormal particle channel determination");
+                        continue;
+                    }
+                    if (oneActive.StateCode == 0)
+                    {
+                        //单通道合格计数
+                        result |= (byte)(1 << oneActive.ChannelNO);
+                    }
+                    else
+                    {
+                        if (oneActive.StateCode != 7 && oneActive.StateCode != 9)
+                        {
+                            //单通道不合格计数
+                            result |= (byte)(1 << (oneActive.ChannelNO));
+                        }
+                        else if (oneActive.StateCode == 7)
+                        {
+                            //FaultLog.RecordErrorMessage("视野存在遮挡,请检查相机");
+                            FaultLog.RecordErrorMessage("The field of view is obstructed. Please check the camera");
+                        }
+                    }
+                }
+            }
+
+            if (IsSend)
+            {
+                CanSendQueue.Enqueue(new CanSenMessage()
+                {
+                    SendDate = result,
+                    IsOK = IsOK,
+                    TaiHao = 0
+                });
             }
+
         }
 
+        #endregion
+
+        #region 线程方法
+
+        /// <summary>
+        /// 交换数据事件-赋予给相机回调方法
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         private void SwitchIdentifyImageEvent(object sender, FrameGrabbedEventArgs e)
         {
             if (e.FrameOut!=null)
             {
-                var QutuYanshiTime = (DateTime.Now - FromUnixTimestamp((long)e.FrameOut.HostTimeStamp)).TotalMilliseconds;
-                if (QutuYanshiTime > 12)
-                {
-                    Console.WriteLine($"GetOnceImage-识别延时超过了12ms,耗时{QutuYanshiTime}");
-                }
+                //var QutuYanshiTime = (DateTime.Now - FromUnixTimestamp((long)e.FrameOut.HostTimeStamp)).TotalMilliseconds;
+                //if (QutuYanshiTime > 12)
+                //{
+                //    Console.WriteLine($"GetOnceImage-识别延时超过了12ms,耗时{QutuYanshiTime}");
+                //}
                 if (lastframeNum == -1)
                 {
                     lastframeNum = e.FrameOut.FrameNum;
@@ -1095,14 +1199,14 @@ namespace CCDCount.DLL
                 //Debug模式,不进行图像处理
                 if (_IsDebug)
                 {
-                    _images.Enqueue(e.FrameOut);
+                    _images.Enqueue(e.FrameOut.Clone() as IFrameOut);
                     if (_images.Count > 5)
                     {
                         _images.TryDequeue(out IFrameOut image);
                         image.Dispose();
                     }
                 }
-                shuLiClass.SetOnceIdentifyImageData2(e.FrameOut);
+                shuLiClass.SetOnceIdentifyImageData(e.FrameOut);
                 shuLiClass.QueueSemaphore.Release(); // 通知处理线程有新数据
             }
             e.FrameOut.Dispose();
@@ -1173,61 +1277,34 @@ namespace CCDCount.DLL
         }
 
         /// <summary>
-        /// 信息发送线程
+        /// 启动发送消息线程
         /// </summary>
-        private void SendBottLogicMessageProcess1()
+        private bool StartCanSendBottLogicMessageThread()
         {
-            //获取数据
-            TestSenMessage sendMessage;
-            bool AllowTransfer;
-            bool TransferDone;
-            Stopwatch sw = Stopwatch.StartNew();
-            while (IsSend)
+            bool result = false;
+            try
             {
-                //LOG.log("进入线程", 6);
-                sw.Restart();
-                sendMessage = new TestSenMessage();
-                //读取装瓶状态
-                AllowTransfer = false;
-                TransferDone = false;
-                bool[] ReturnValue = null;
-                modbusTcpClient.ReadCoilsRegister(slaveId: 1, startAddress: 11, numRegisters: 2,out ReturnValue);
-                if (ReturnValue == null)
-                {
-                    continue;
-                }
-                AllowTransfer = ReturnValue[1];
-                TransferDone = ReturnValue[0];
-                //LOG.log(string.Format("读取值:AllowTransfer[0]:{0},TransferDone[1]:{1}", AllowTransfer, TransferDone), 6);
-                //当允许写入且处于未写入的状态时
-                if (AllowTransfer && !TransferDone)
-                {
-                    if (SendQueue.Count() > 0)
-                    {
-                        if (!SendQueue.TryDequeue(out sendMessage))
-                        {
-                            //FaultLog.RecordErrorMessage("MainThreadClass-SendBottLogicMessageProcess-SendQueue.TryDequeue failed!");
-                        }
-                    }
-                    if (sendMessage.Message == null)
-                    {
-                        continue;
-                    }
-                    if (sendMessage.Message[0] != 0|| sendMessage.Message[1] != 0)
-                    {
-                        //写入数据
-                        modbusTcpClient.WriteMultipleRegisters(slaveId: 1, startAddress: 100, values: sendMessage.Message);
-                        modbusTcpClient.WriteCoilsRegister(slaveId: 1, CoilsAddress: 11, values: true);
-                        sw.Stop();
-                        LOG.log(string.Format("SendMessageOk:{0},SendMessageNg:{1},此次写值耗时:{2},此次写入数据量{3}", sendMessage.Message[0],sendMessage.Message[1], sw.Elapsed,sendMessage.count), 6);
-                    }
-                }
-                Thread.Sleep(1);
+                IsSend = true;
+                SendBottLogicMessageThread = new Thread(SendBottLogicMessageProcessUseCan);
+                SendBottLogicMessageThread.Start();
+                SystemAlarm.AlarmCancel(AlarmMessageList.结果发送线程启动失败);
+                result = true;
+            }
+            catch (Exception ex)
+            {
+                //FaultLog.RecordErrorMessage("MianThread-StartSendBottLogicMessageThread:Start thread failed!, " + ex.Message);
+                SystemAlarm.AlarmAlert(AlarmMessageList.结果发送线程启动失败,
+                    "MianThread-StartSendBottLogicMessageThread:Start thread failed!, " + ex.Message,
+                    "结果发送线程启动失败," + ex.Message,
+                    "DLL:MainThreadClass-StartSendBottLogicMessageThread");
+                Console.WriteLine("MianThread-StartSendBottLogicMessageThread:Start thread failed!, " + ex.Message);
+                result = false;
             }
+            return result;
         }
 
         /// <summary>
-        /// 信息发送线程2
+        /// 信息发送线程
         /// </summary>
         private void SendBottLogicMessageProcess()
         {
@@ -1298,6 +1375,67 @@ namespace CCDCount.DLL
                 Thread.Sleep(1);
             }
         }
+
+        private void SendBottLogicMessageProcessUseCan()
+        {
+            //获取数据
+            CanSenMessage sendMessage;
+            Stopwatch sw = Stopwatch.StartNew();
+            Stopwatch WriteDoneTime = Stopwatch.StartNew();
+            CanManagerClass canManager = new CanManagerClass();
+            bool isFrist = true;
+            try
+            {
+                canManager.OpenDevice();
+                canManager.InitCan();
+            }
+            catch (Exception ex)
+            {
+                LOG.error(string.Format("MainThreadClass-SendBottLogicMessageProcessUseCan-Open:{0}", ex.Message));
+            }
+            while (IsSend)
+            {
+                try
+                {
+                    //LOG.log("进入线程", 6);
+                    sendMessage = new CanSenMessage();
+                    bool IsTrigger = canManager.GetTrigger(ref isFrist);
+                    if (!IsTrigger)
+                    {
+                        continue;
+                    }
+                    else
+                    {
+                        WriteDoneTime.Restart();
+                        while (CanSendQueue.Count == 0 && IsSend)
+                        {
+                            Thread.Sleep(1);
+                        }
+                        sw.Restart();
+
+                        if (!CanSendQueue.TryDequeue(out sendMessage))
+                        {
+                            FaultLog.RecordErrorMessage("MainThreadClass-SendBottLogicMessageProcess-SendQueue.TryDequeue failed!");
+                        }
+                        canManager.SenMessage(sendMessage);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LOG.error(string.Format("MainThreadClass-SendBottLogicMessageProcessUseCan-Send:{0}", ex.Message));
+                }
+
+            }
+            try
+            {
+                canManager.CloseCan();
+            }
+            catch (Exception ex)
+            {
+                LOG.error(string.Format("MainThreadClass-SendBottLogicMessageProcessUseCan-Close:{0}", ex.Message));
+            }
+            LOG.log("发送线程关闭完成", 6);
+        }
         #endregion
 
         #region 外部函数
@@ -1313,4 +1451,10 @@ namespace CCDCount.DLL
         public ushort[] NumMessage { get; set; }
         public ushort count { get; set; }
     }
+    public class CanSenMessage
+    {
+        public byte SendDate {  get; set; }
+        public bool IsOK {  get; set; }
+        public int TaiHao {  get; set; }
+    }
 }

+ 113 - 18
TestWork.DLL/PLCManagementClass.cs

@@ -32,25 +32,25 @@ namespace CCDCount.DLL
 
         public void ConnectModbus(string ipAddress)
         {
-            Task.Run(() =>
+            int i = 10;
+            while (!modbusTcpClient.Connect(ipAddress)&&i>0)
+            {
+                isConnect = false;
+                //SystemAlarm.AlarmAlert(AlarmMessageList.PLC通讯连接失败, $"Modbus通讯连接失败,目标IP:{ipAddress}", "DLL:MainThreadClass-ConnectModbus");
+                SystemAlarm.AlarmAlert(AlarmMessageList.PLC通讯连接失败,
+                    $"PLC communication connection failed, target IP:{ipAddress}",
+                    $"PLC通讯连接失败, IP地址:{ipAddress}",
+                    "DLL:MainThreadClass-ConnectModbus");
+                i--;
+                Task.Delay(1000);
+            }
+            if(modbusTcpClient.Connect(ipAddress))
             {
-                int i = 10;
-                while (!modbusTcpClient.Connect(ipAddress)&&i>0)
-                {
-                    isConnect = false;
-                    //SystemAlarm.AlarmAlert(AlarmMessageList.PLC通讯连接失败, $"Modbus通讯连接失败,目标IP:{ipAddress}", "DLL:MainThreadClass-ConnectModbus");
-                    SystemAlarm.AlarmAlert(AlarmMessageList.PLC通讯连接失败,
-                        $"PLC communication connection failed, target IP:{ipAddress}",
-                        $"PLC通讯连接失败, IP地址:{ipAddress}",
-                        "DLL:MainThreadClass-ConnectModbus");
-                    i--;
-                    Task.Delay(1000);
-                }
                 SystemAlarm.AlarmCancel(AlarmMessageList.PLC通讯连接失败);
                 LOG.log("PLC通讯成功", 6);
                 //FaultLog.RecordLogMessage($"Modbus通讯连接成功,目标IP:{ipAddress}", 6);
                 isConnect = true;
-            });
+            }
         }
 
         /****************************************************动作操作*****************************************************************/
@@ -504,6 +504,38 @@ namespace CCDCount.DLL
             ValveState = (sendMessage & mask) != 0;
             return result;
         }
+
+        /// <summary>
+        /// 拦瓶按钮切换
+        /// </summary>
+        /// <param name="ValveState"></param>
+        /// <returns></returns>
+        public bool BottleStopperSwitch(out bool ValveState)
+        {
+            bool result = false;
+            ushort mask = (ushort)(1 << 14);
+            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 1014, 1, out ushort[] returnvalue);
+            ushort sendMessage = (ushort)(returnvalue[0] ^ mask);
+            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: sendMessage);
+            ValveState = (sendMessage & mask) != 0;
+            return result;
+        }
+
+        /// <summary>
+        /// 放瓶按钮切换
+        /// </summary>
+        /// <param name="ValveState"></param>
+        /// <returns></returns>
+        public bool BottlePassSwitch(out bool ValveState)
+        {
+            bool result = false;
+            ushort mask = (ushort)(1 << 15);
+            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 1014, 1, out ushort[] returnvalue);
+            ushort sendMessage = (ushort)(returnvalue[0] ^ mask);
+            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: sendMessage);
+            ValveState = (sendMessage & mask) != 0;
+            return result;
+        }
         /// <summary>
         /// 传送带运行状态切换
         /// </summary>
@@ -1167,6 +1199,58 @@ namespace CCDCount.DLL
         {
             return modbusTcpClient.WriteSingleRegister(1, 3656, Value);
         }
+
+        /// <summary>
+        /// 写入相机识别运行状态
+        /// </summary>
+        /// <param name="Value"></param>
+        /// <returns></returns>
+        public bool WriteCameraRunState(ushort Value)
+        {
+            return modbusTcpClient.WriteSingleRegister(1, 3692, Value);
+        }
+
+        /// <summary>
+        /// 写入缺屏停机再启动延时
+        /// </summary>
+        /// <param name="Value"></param>
+        /// <returns></returns>
+        public bool WriteMissingBottleReStartTime(ushort Value)
+        {
+            return modbusTcpClient.WriteSingleRegister(1, 3700, Value);
+        }
+
+        /// <summary>
+        /// 写入缺屏停机再启动延时
+        /// </summary>
+        /// <param name="Value"></param>
+        /// <returns></returns>
+        public bool WriteBottleStopPassTime(ushort Value)
+        {
+            return modbusTcpClient.WriteSingleRegister(1, 3666, Value);
+        }
+
+        /// <summary>
+        /// 写入缺屏停机再启动延时
+        /// </summary>
+        /// <param name="Value"></param>
+        /// <returns></returns>
+        public bool WriteBuzzerTime(ushort Value)
+        {
+            return modbusTcpClient.WriteSingleRegister(1, 3684, Value);
+        }
+
+
+        /// <summary>
+        /// 写入缺屏停机再启动延时
+        /// </summary>
+        /// <param name="Value"></param>
+        /// <returns></returns>
+        public bool WriteCacheDecelerateProportion(ushort Value)
+        {
+            return modbusTcpClient.WriteSingleRegister(1, 3688, Value);
+        }
+
         /// <summary>
         /// 写入罐装设定值
         /// </summary>
@@ -1187,7 +1271,7 @@ namespace CCDCount.DLL
         /// <summary>
         /// 读取所有参数(参数数据表)
         /// </summary>
-        public PlcParaModelClass ReadAllPara()
+        public PlcParaModelClass  ReadAllPara()
         {
             PlcParaModelClass result = null;
             var results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3000, numRegisters: 120, out ushort[] ReturnValue);
@@ -1244,7 +1328,7 @@ namespace CCDCount.DLL
             result.MachineDelayFillingValveCloseTime = ReturnValue[80];
             result.MachineDelayInBottleTime = ReturnValue[96];
             result.ValveDelytime = ReturnValue[112];
-            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3642, numRegisters: 22, out ReturnValue);
+            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3642, numRegisters: 62, out ReturnValue);
             if (!results || ReturnValue == null) return null;
             result.MissingDelaytime = ReturnValue[0];
             result.BottleJamDelaytime = ReturnValue[2];
@@ -1254,6 +1338,10 @@ namespace CCDCount.DLL
             result.EliminateCylinderDelayTime = ReturnValue[16];
             result.EliminateCylinderHoldingTime = ReturnValue[18];
             result.MaterialShortageStoppageDelayTime = ReturnValue[20];
+            result.BottleStopPassTime = ReturnValue[24];
+            result.BuzzerTime = ReturnValue[42];
+            result.CacheDecelerateProportion = ReturnValue[46];
+            result.MissBottleReSestart = ReturnValue[58];
             results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 2504, numRegisters: 2, out ReturnValue);
             if (!results || ReturnValue == null) return null;
             result.BottValueSet = ReturnValue[0];
@@ -1269,7 +1357,7 @@ namespace CCDCount.DLL
         public bool ReadBottingVibrationTableHighSpeedValue(out ushort ShakeTable1H_FillingSpeed, out ushort ShakeTable2H_FillingSpeed, out ushort ShakeTable3H_FillingSpeed)
         {
             bool result = false;
-            var results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3000, numRegisters: 48, out ushort[] ReturnValue);
+            var results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3000, numRegisters: 50, out ushort[] ReturnValue);
             if (!results || ReturnValue == null)
             {
                 ShakeTable1H_FillingSpeed = 0;
@@ -1428,10 +1516,14 @@ namespace CCDCount.DLL
             return result;
         }
 
+        /// <summary>
+        /// 读取全部报警
+        /// </summary>
+        /// <returns></returns>
         public PlcAlarmModelClass ReadAllAlarm()
         {
             PlcAlarmModelClass ResultValue = null;
-            if(modbusTcpClient.ReadHoldingRegisters(1, 1025, 2, out ushort[] returnvalue))
+            if(modbusTcpClient.ReadHoldingRegisters(1, 1025, 4, out ushort[] returnvalue))
             {
                 ResultValue = new PlcAlarmModelClass()
                 {
@@ -1448,6 +1540,9 @@ namespace CCDCount.DLL
                     WaitingForReset = ((returnvalue[0] & ((ushort)(1 << 10))) != 0),
                     BottleJamSignal = ((returnvalue[1] & ((ushort)(1 << 8))) != 0),
                     MissingBottleSignal = ((returnvalue[1] & ((ushort)(1 << 9))) != 0),
+                    PLCCameraHeartErrorSignal = ((returnvalue[0] & ((ushort)(1 << 11))) != 0),
+                    CameraNotRunSignal = ((returnvalue[0] & ((ushort)(1 << 12))) != 0),
+                    ParticleCacheOverflowSignal = ((returnvalue[3] & ((ushort)(1 << 0))) != 0),
                 };
             }
             return ResultValue;

+ 78 - 658
TestWork.DLL/ShuLiClass.cs

@@ -27,10 +27,7 @@ namespace CCDCount.DLL
         public event EventHandler<ActiveObjectEventArgsClass> WorkCompleted;
         private List<ActiveObjectClass> activeObjects = new List<ActiveObjectClass>(); // 当前跟踪中的物体
         private List<ActiveObjectClass> historyActiveObjects = new List<ActiveObjectClass>(); // 历史物体
-        private ConcurrentQueue<IFrameOut> IFrameDatas = new ConcurrentQueue<IFrameOut>(); //图像数据队列
         private LockFreeRingBuffer<IFrameOut> RingBuffer_IFrameDatas = new LockFreeRingBuffer<IFrameOut>(300);
-        private Thread IdentifyImageProcessThread = null; // 识别线程
-        private bool IsIdentify = false; //线程是否开始识别的标志
         private long currentLine = 0; //行数记录
         private ShuLiConfigClass shuLiConfig = null;// 数粒参数配置文件
         public List<int> ChannelsRoi { get { return _ChannelsRoi; } }
@@ -38,10 +35,10 @@ namespace CCDCount.DLL
         private int ChannelWidth = 0;//每个区域的宽度
         private int IdentifyImageWidth = -1;
         private int ObjectNum = 0;
-        public int ImageNum { get { return IFrameDatas.Count; } }
+        public int ImageNum { get { return RingBuffer_IFrameDatas.Count; } }
         private ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
-        private double XCoefficient = 1;
-        private double YCoefficient = 2;
+        private double XCoefficient = 0.1;
+        private double YCoefficient = 0.2;
         private DateTime[] ChannelIntervalTime = new DateTime[8];
 
         private int _HistoryActiveNum = 0;
@@ -106,13 +103,10 @@ namespace CCDCount.DLL
             return ObjectNum;
         }
 
-        List<ActiveObjectClass> lostObjects = new List<ActiveObjectClass>();
         /// <summary>
         /// 处理图像序列的主入口
         /// </summary>
         /// <param name="image">图像像素数据</param>
-        /// <param name="ImageWidth">图像宽</param>
-        /// <param name="currentLine">当前行数</param>
         /// <returns>检测到的物体总数</returns>
         public bool ProcessImageSequence(IFrameOut image)
         {
@@ -120,177 +114,7 @@ namespace CCDCount.DLL
             ReadOnlySpan<byte> spanFromArr = image.Image.PixelData.AsSpan();
             for (int i = 0; i < image.Image.Height; i++)
             {
-                result = ProcessLine2(spanFromArr,image.HostTimeStamp,image.Image.Width, i);
-                currentLine += 1;
-            }
-
-            //识别到结果并输出
-
-            _rwLock.EnterReadLock();
-            // 清理超时未更新的物体
-            lostObjects = activeObjects
-                .Where(o => (currentLine - o.LastSeenLine) > shuLiConfig.MAX_GAP || (o.LastSeenLine - o.StartLine) > shuLiConfig.MAX_Idetify_Height)
-                .ToList();
-            _rwLock.ExitReadLock();
-            _rwLock.EnterWriteLock();
-            lostObjects.ForEach(o => activeObjects.Remove(o));
-            _rwLock.ExitWriteLock();
-
-
-            List<ActiveObjectClass> OneActive = new List<ActiveObjectClass>();
-
-            // 有物体转变为活跃物体,返回值转为true
-            if (lostObjects.Count > 0)
-            {
-                //Stopwatch stopwatch = Stopwatch.StartNew();
-                result = true;
-                //stopwatch.Restart();
-                foreach (var item in lostObjects)
-                {
-
-                    item.PictureEndReadTime = FromUnixTimestamp((long)image.HostTimeStamp);
-                    var QutuYanshiTime = (DateTime.Now - item.PictureEndReadTime).TotalMilliseconds;
-                    if (QutuYanshiTime > 20)
-                    {
-                        //LOG.error($"结果输出延时超过了20ms,耗时{QutuYanshiTime}");
-                        Console.WriteLine($"结果输出延时超过了20ms,耗时{QutuYanshiTime}");
-                    }
-                    //噪点判定
-                    //if (item.Area < shuLiConfig.NoiseFilter_Threshold)
-                    //{
-                    //    item.StateCode = 9;
-                    //    //LOG.log(string.Format("噪点过滤,噪点面积:{0}", item.Area), 6);
-                    //    continue;
-                    //}
-                    //if(item.StartLine == item.LastSeenLine)
-                    //{
-                    //    item.MaxLength = item.MaxEndCol - item.MinStartCol;
-                    //    item.StateCode = 10;
-                    //    LOG.log(string.Format("颗粒{0}的有效高度仅一行", item.Num));
-                    //}
-                    //else
-                    //{
-                    //    if((item.LastSeenLine - item.StartLine) < shuLiConfig.MAX_Idetify_Height)
-                    //    {
-                    //        var CalculationResult = SizeCalculation(item.RowsData);
-                    //        if(CalculationResult!=null)
-                    //        {
-                    //            item.MaxLength = CalculationResult.Height;
-                    //        }
-                    //        //item.hasSignificantConcavity = CalculationResult.hasSignificantConcavity;
-                    //        //item.concavityRatio = CalculationResult.concavityRatio;
-                    //        //if(CalculationResult.hasSignificantConcavity)
-                    //        //{
-                    //        //    if(CalculationResult.concavityRatio>0.3)
-                    //        //    {
-                    //        //        item.StateCode= 11;
-                    //        //    }
-                    //        //}
-                    //    }
-                    //    else
-                    //    {
-                    //        item.StateCode = 7;
-                    //    }
-                    //}
-                    //if (shuLiConfig.PandingCode != -1)
-                    //{
-                    //    if (item.StateCode != -1)
-                    //    {
-                    //        if (item.StateCode == 8)
-                    //        {
-                    //            //LOG.log(string.Format("颗粒编号{0}:疑似叠片或缺损", item.Num));
-                    //        }
-                    //        else if (item.StateCode == 7)
-                    //        {
-                    //            //LOG.log(string.Format("颗粒编号{0}:视野被遮挡", item.Num));
-                    //        }
-                    //    }
-                    //    else if (item.Area < shuLiConfig.MinArea
-                    //        && (shuLiConfig.PandingCode == 2 || shuLiConfig.PandingCode == 1))
-                    //    {
-                    //        item.StateCode = 6;
-                    //        //LOG.log(string.Format("颗粒编号{0}:面积过小", item.Num));
-                    //        //Console.WriteLine("颗粒编号{0}:面积过小", item.Num);
-                    //    }
-                    //    else if (item.Area > shuLiConfig.MaxArea
-                    //        && (shuLiConfig.PandingCode == 2 || shuLiConfig.PandingCode == 1))
-                    //    {
-                    //        item.StateCode = 5;
-                    //        //LOG.log(string.Format("颗粒编号{0}:面积过大", item.Num));
-                    //        //Console.WriteLine("颗粒编号{0}:面积过大", item.Num);
-                    //    }
-                    //    else if (item.MaxLength < shuLiConfig.MIN_Object_LENGTH
-                    //        && (shuLiConfig.PandingCode == 2 || shuLiConfig.PandingCode == 0))
-                    //    {
-                    //        item.StateCode = 2;
-                    //        //LOG.log(string.Format("颗粒编号{0}:超短粒", item.Num));
-                    //        //Console.WriteLine("颗粒编号{0}:超短粒", item.Num);
-                    //    }
-                    //    else if (item.MaxLength > shuLiConfig.MAX_Object_LENGTH
-                    //        && (shuLiConfig.PandingCode == 2 || shuLiConfig.PandingCode == 0))
-                    //    {
-                    //        item.StateCode = 1;
-                    //        //LOG.log(string.Format("颗粒编号{0}:超长粒", item.Num));
-                    //        //Console.WriteLine("颗粒编号{0}:超长粒", item.Num);
-                    //    }
-                    //    else
-                    //    {
-                    //        item.StateCode = 0;
-                    //        //LOG.log(string.Format("颗粒编号{0}:正常粒", item.Num));
-                    //        //Console.WriteLine("颗粒编号{0}:正常粒", item.Num);
-                    //    }
-                    //}
-                    if(item.StateCode != 7&&item.StateCode!=9)
-                    {
-                        //转为历史物体,添加缺少的参数
-                        item.Num = Interlocked.Increment(ref ObjectNum);
-                        item.ChannelNO = ActiveChannel(item);
-                    }
-                    item.EndCheckTime = DateTime.Now;
-                    //if(item.StateCode != 9)
-                        OneActive.Add(item);
-                }
-                //stopwatch.Stop();
-                //if (stopwatch.ElapsedMilliseconds > 1)
-                //{
-                //    Console.WriteLine($"ShuLiClass-ProcessImageSequence:图像结果分析-结果参数补全,此次识别耗时:{stopwatch.Elapsed}");
-                //    //FaultLog.RecordErrorMessage($"ShuLiClass-ProcessImageSequence:图像结果分析-结果参数补全,此次识别耗时:{stopwatch.Elapsed}");
-                //}
-                //stopwatch.Restart();
-                if (OneActive.Count > 0)
-                {
-                    //ThreadPool.QueueUserWorkItem(_ =>
-                    //{
-                        //触发回调事件
-                        OnWorkCompleted(OneActive);
-                    //});
-                }
-               // stopwatch.Stop();
-                //if (stopwatch.ElapsedMilliseconds > 1)
-                //{
-                //    FaultLog.RecordErrorMessage($"ShuLiClass-ProcessImageSequence:图像结果分析-结果完成回调函数,此次识别耗时:{stopwatch.Elapsed}");
-                //}
-            }
-            else
-            {
-                OneActive.Clear();
-            }
-            return result;
-        }
-
-        /// <summary>
-        /// 处理图像序列的主入口
-        /// </summary>
-        /// <param name="image">图像像素数据</param>
-        /// <returns>检测到的物体总数</returns>
-        public bool ProcessImageSequence2(IFrameOut image)
-        {
-            bool result = false;
-            ReadOnlySpan<byte> spanFromArr = image.Image.PixelData.AsSpan();
-            for (int i = 0; i < image.Image.Height; i++)
-            {
-                //result = ProcessLine2(spanFromArr, image.HostTimeStamp, image.Image.Width, i);
-                result = ProcessLine(image, i);
+                ProcessLine(image, i);
                 currentLine += 1;
             }
 
@@ -391,6 +215,7 @@ namespace CCDCount.DLL
                 item.MaxLength = item.MaxEndCol - item.MinStartCol;
                 item.StateCode = 10;
                 LOG.log(string.Format("颗粒{0}的有效高度仅一行", item.Num));
+                return;
             }
             else
             {
@@ -405,14 +230,15 @@ namespace CCDCount.DLL
                 else
                 {
                     item.StateCode = 7;
+                    return;
                 }
             }
 
             // 分类处理
-            ApplyClassificationRules(item);
+            ApplyClassificationRules(ref item);
 
             // 添加到历史记录
-            if (item.StateCode != 7 && item.StateCode != 9)
+            if (item.StateCode != 7 && item.StateCode != 9 && item.StateCode != 10)
             {
                 item.Num = Interlocked.Increment(ref ObjectNum);
                 item.ChannelNO = ActiveChannel(item);
@@ -420,14 +246,17 @@ namespace CCDCount.DLL
 
             item.EndCheckTime = endTime;
 
-            if (item.StateCode != 9)
+            if (item.StateCode != 7 && item.StateCode != 9 && item.StateCode != 10)
             {
                 processedObjects.Add(item);
             }
         }
 
-        // 抽取分类规则,便于维护
-        private void ApplyClassificationRules(ActiveObjectClass item)
+        /// <summary>
+        /// 分类规则
+        /// </summary>
+        /// <param name="item"></param>
+        private void ApplyClassificationRules(ref ActiveObjectClass item)
         {
             if (shuLiConfig.PandingCode == -1) return;
 
@@ -439,7 +268,11 @@ namespace CCDCount.DLL
                 }
                 else if (item.StateCode == 7)
                 {
-                    LOG.log(string.Format("颗粒编号{0}:视野被遮挡", item.Num));
+                    LOG.log("视野被遮挡");
+                }
+                else if (item.StateCode == 9)
+                {
+                    LOG.log(string.Format("噪点", item.Num));
                 }
             }
             else if (item.Area < shuLiConfig.MinArea &&
@@ -518,41 +351,11 @@ namespace CCDCount.DLL
             //}
         }
 
-        /// <summary>
-        /// 开启识别
-        /// </summary>
-        public void StartIdentifyFuntion(int ImaageWidth)
-        {
-            UpdateIdentifyImageWidth(ImaageWidth);
-            InitChannel();
-            try
-            {
-                // 标志位置位true
-                IsIdentify = true;
-                // 打开识别线程
-                IdentifyImageProcessThread = new Thread(IdentifyImageProcess)
-                {
-                    Priority = ThreadPriority.AboveNormal
-                };
-                IdentifyImageProcessThread.Start();
-                SystemAlarm.AlarmCancel(AlarmMessageList.识别线程启动失败);
-            }
-            catch (Exception ex)
-            {
-                SystemAlarm.AlarmAlert(AlarmMessageList.识别线程启动失败,
-                    "Start thread failed!, " + ex.Message,
-                    "识别线程启动失败, " + ex.Message,
-                    "DLL:ShuLiClass-StartIdentifyFuntion");
-                //FaultLog.RecordErrorMessage("Start thread failed!, " + ex.Message);
-                throw;
-            }
-        }
-
         /// <summary>
         /// 开启识别-优化版本
         /// </summary>
         /// <param name="ImaageWidth"></param>
-        public void StartIdentifyFuntion2(int ImaageWidth)
+        public void StartIdentifyFuntion(int ImaageWidth)
         {
             UpdateIdentifyImageWidth(ImaageWidth);
             InitChannel();
@@ -560,9 +363,9 @@ namespace CCDCount.DLL
             {
                 CancellationTokenSource = new CancellationTokenSource();
                 var token = CancellationTokenSource.Token;
-
+                LOG.log(string.Format("X系数:{0},Y系数:{1}", XCoefficient, YCoefficient), 6);
                 // 启动图像处理线程
-                ProcessingTask = Task.Factory.StartNew(() => IdentifyImageProcessTask2(token),
+                ProcessingTask = Task.Factory.StartNew(() => IdentifyImageProcessTask(token),
                     token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
                 SystemAlarm.AlarmCancel(AlarmMessageList.识别线程启动失败);
             }
@@ -577,30 +380,7 @@ namespace CCDCount.DLL
             }
         }
 
-        /// <summary>
-        /// 关闭识别
-        /// </summary>
-        public void StopIdentifyFuntion()
-        {
-            try
-            {
-                // 标志位设为false
-                IsIdentify = false;
-                if (IdentifyImageProcessThread != null && IdentifyImageProcessThread.IsAlive)
-                    IdentifyImageProcessThread.Join();
-                SystemAlarm.AlarmCancel(AlarmMessageList.识别线程停止失败);
-            }
-            catch (Exception ex)
-            {
-                //FaultLog.RecordErrorMessage("Stop thread failed!, " + ex.Message);
-                SystemAlarm.AlarmAlert(AlarmMessageList.识别线程停止失败,
-                    "Stop thread failed!, " + ex.Message,
-                    "识别线程停止失败, " + ex.Message,
-                    "DLL:ShuLiClass-StopIdentifyFuntion");
-                throw;
-            }
-        }
-        public async void StopIdentifyFuntion2()
+        public async void StopIdentifyFuntion()
         {
             try
             {
@@ -630,24 +410,14 @@ namespace CCDCount.DLL
             }
         }
 
-        /// <summary>
-        /// 向识别队列添加一个数据
-        /// </summary>
-        /// <param name="items"></param>
-        public void SetOnceIdentifyImageData(IFrameOut items)
-        {
-            IFrameDatas.Enqueue(items.Clone() as IFrameOut);
-            //IFrameDatas.Enqueue(items );
-        }
 
         /// <summary>
         /// 向识别队列添加一个数据
         /// </summary>
         /// <param name="items"></param>
-        public void SetOnceIdentifyImageData2(IFrameOut items)
+        public void SetOnceIdentifyImageData(IFrameOut items)
         {
             RingBuffer_IFrameDatas.TryEnqueue(items.Clone() as IFrameOut);
-            //IFrameDatas.Enqueue(items );
         }
 
         /// <summary>
@@ -963,15 +733,12 @@ namespace CCDCount.DLL
                 }
             }
             IsPrintLightOnError = false;
-            //stopwatch.Stop();
-            //if (stopwatch.ElapsedMilliseconds > 1)
-            //{
-            //    FaultLog.RecordErrorMessage($"ShuLiClass-ProcessLine:图像连通域检测超时,此次识别耗时:{stopwatch.Elapsed}");
-            //}
-            //stopwatch.Restart();
             foreach (var region in currentRegions)
             {
-
+                if(region.End-region.Start<=3)
+                {
+                    continue;
+                }
                 // 查找全部可合并的活跃物体(有重叠+在允许间隔内)
                 _rwLock.EnterReadLock();
                 var matcheds = activeObjects.Where(o =>
@@ -991,14 +758,14 @@ namespace CCDCount.DLL
                         MaxEndCol = matcheds.Max(o => o.MaxEndCol),
                         StartLine = matcheds.Min(o => o.StartLine),
                         LastSeenLine = matcheds.Max(o => o.LastSeenLine),
-                        LastSeenLineStartCol = matcheds.Min(o => o.LastSeenLineStartCol),
-                        LastSeenLineEndCol = matcheds.Max(o => o.LastSeenLineEndCol),
+                        PreSeenLineStartCol = matcheds.Min(o => o.PreSeenLineStartCol),
+                        PreSeenLineEndCol = matcheds.Max(o => o.PreSeenLineEndCol),
                         StartCheckTime = matcheds.Min(o => o.StartCheckTime),
                         EndCheckTime = matcheds.Max(o => o.EndCheckTime),
                         Area = matcheds.Sum(o => o.Area),
                         RowsData = CopeRowsData,
                         ImageWidth = matcheds.FirstOrDefault().ImageWidth,
-                        StateCode = 8
+                        //StateCode = 8
                     };
                     _rwLock.EnterWriteLock();
                     // 从活跃区域中删除被合并的区域
@@ -1026,8 +793,22 @@ namespace CCDCount.DLL
                         EndCol = region.End,
                         RowsCol = currentLine,
                     });
-                    matched.LastSeenLineStartCol = region.Start;
-                    matched.LastSeenLineEndCol = region.End;
+                    if(matched.LastSeenLineEndCol==-1)
+                    {
+                        matched.LastSeenLineEndCol = region.End;
+                    }
+                    else
+                    {
+                        matched.LastSeenLineEndCol = Math.Max(matched.LastSeenLineEndCol, region.End);
+                    }
+                    if (matched.LastSeenLineStartCol == -1)
+                    {
+                        matched.LastSeenLineStartCol = region.Start;
+                    }
+                    else
+                    {
+                        matched.LastSeenLineStartCol = Math.Min(matched.LastSeenLineStartCol, region.Start);
+                    }
                 }
                 else
                 {
@@ -1039,8 +820,8 @@ namespace CCDCount.DLL
                         MaxEndCol = region.End,
                         StartLine = currentLine,
                         LastSeenLine = currentLine,
-                        LastSeenLineStartCol = region.Start,
-                        LastSeenLineEndCol = region.End,
+                        PreSeenLineStartCol = region.Start,
+                        PreSeenLineEndCol = region.End,
                         StartCheckTime = DateTime.Now,
                         PictureStartReadTime = FromUnixTimestamp((long)imagedata.HostTimeStamp),
                         Area = region.End - region.Start + 1,
@@ -1057,195 +838,25 @@ namespace CCDCount.DLL
                 }
             }
 
-            //stopwatch.Stop();
-            //if (stopwatch.ElapsedMilliseconds > 1)
-            //{
-            //    FaultLog.RecordErrorMessage($"ShuLiClass-ProcessLine:图像区域合并超时,此次识别耗时:{stopwatch.Elapsed}");
-            //}
-            return result;
-        }
-        private bool ProcessLine2(ReadOnlySpan<byte> image, ulong ImageHostTime, uint imageWidth, int RowNo)
-        {
-            // 缓存配置值
-            int maxGap = shuLiConfig.MAX_GAP;
-            long currentTimeLine = currentLine;
-
-            // 步骤1:检测当前行的有效区域
-            //currentRegions = FindValidRegions(image, (int)imageWidth, RowNo);
-
-            if (currentRegions.Count == 0|| currentRegions == null) return false;
-
-            if (currentRegions.Count == 1)
+            foreach (var obj in activeObjects)
             {
-                if (currentRegions[0].End - (currentRegions[0]).Start + 1 == imageWidth)
+                if(obj.LastSeenLineEndCol!=-1)
                 {
-                    if (!IsPrintLightOnError)
-                    {
-                        FaultLog.RecordLogMessage("The current effective area is the entire row. Check the field of view and light source", 6);
-                        IsPrintLightOnError = true;
-                    }
-                    return false;
+                    obj.PreSeenLineEndCol = obj.LastSeenLineEndCol;
+                    obj.LastSeenLineEndCol = -1;
                 }
-            }
-            IsPrintLightOnError = false;
-
-            // 批量处理操作列表
-            var operations = new List<OperationItem>();
-            var currentActiveObjects = new List<ActiveObjectClass>();
-
-            // 一次性获取当前活跃物体快照
-            _rwLock.EnterReadLock();
-            try
-            {
-                currentActiveObjects = new List<ActiveObjectClass>(activeObjects);
-            }
-            finally
-            {
-                _rwLock.ExitReadLock();
-            }
-
-            foreach (var region in currentRegions)
-            {
-                // 查找所有可合并的活跃物体(重叠+在允许间隔内)
-                var matcheds = currentActiveObjects.Where(o =>
-                    IsOverlapping(o, region) &&
-                    (currentTimeLine - o.LastSeenLine - 1) <= maxGap).ToList();
-
-                // 当有多个可合并的活跃物体时,将多个物体合并
-                if (matcheds.Count >= 2)
-                {
-                    // 计算聚合值(单次遍历)
-                    var aggregateResult = CalculateAggregates(matcheds);
-
-                    var mergedObject = new ActiveObjectClass
-                    {
-                        MinStartCol = aggregateResult.minStartCol,
-                        MaxEndCol = aggregateResult.maxEndCol,
-                        StartLine = aggregateResult.minStartLine,
-                        LastSeenLine = aggregateResult.maxLastSeenLine,
-                        LastSeenLineStartCol = aggregateResult.minLastSeenStartCol,
-                        LastSeenLineEndCol = aggregateResult.maxLastSeenEndCol,
-                        StartCheckTime = aggregateResult.minStartTime,
-                        EndCheckTime = aggregateResult.maxEndTime,
-                        PictureStartReadTime = aggregateResult.pictureMinReadTime,
-                        Area = aggregateResult.totalArea,
-                        RowsData = aggregateResult.mergedRowsData,
-                        ImageWidth = aggregateResult.imageWidth,
-                        StateCode = 8
-                    };
-
-                    operations.Add(new OperationItem
-                    {
-                        Type = OperationType.MergeMultiple,
-                        ObjectsToRemove = matcheds,
-                        ObjectToAdd = mergedObject
-                    });
-
-                    // 从currentActiveObjects中移除已处理的物体,避免重复处理
-                    foreach (var obj in matcheds)
-                    {
-                        currentActiveObjects.Remove(obj);
-                    }
-                }
-                else
+                if (obj.LastSeenLineStartCol != -1)
                 {
-                    // 查找单一匹配物体
-                    var matched = matcheds.FirstOrDefault();
-                    if (matched != null)
-                    {
-                        operations.Add(new OperationItem
-                        {
-                            Type = OperationType.Update,
-                            ObjectToUpdate = matched,
-                            Region = region
-                        });
-                    }
-                    else
-                    {
-                        // 创建新物体
-                        var newObject = new ActiveObjectClass
-                        {
-                            MinStartCol = region.Start,
-                            MaxEndCol = region.End,
-                            StartLine = currentTimeLine,
-                            LastSeenLine = currentTimeLine,
-                            LastSeenLineStartCol = region.Start,
-                            LastSeenLineEndCol = region.End,
-                            StartCheckTime = DateTime.Now,
-                            PictureStartReadTime = FromUnixTimestamp((long)ImageHostTime),
-                            Area = region.End - region.Start + 1,
-                            ImageWidth = IdentifyImageWidth,
-                            RowsData = new List<RowStartEndCol> {
-                                new RowStartEndCol {
-                                    StartCol = region.Start,
-                                    EndCol = region.End,
-                                    RowsCol = currentTimeLine,
-                                }
-                            }
-                        };
-                        operations.Add(new OperationItem
-                        {
-                            Type = OperationType.Add,
-                            ObjectToAdd = newObject
-                        });
-                    }
+                    obj.PreSeenLineStartCol = obj.LastSeenLineStartCol;
+                    obj.LastSeenLineStartCol = -1;
                 }
             }
-
-            currentRegions.Clear();
-            // 执行所有操作(最小化锁持有时间)
-            bool hasChanges = false;
-            if (operations.Count > 0)
-            {
-                _rwLock.EnterWriteLock();
-                try
-                {
-                    foreach (var op in operations)
-                    {
-                        switch (op.Type)
-                        {
-                            case OperationType.MergeMultiple:
-                                // 移除被合并的物体
-                                foreach (var objItem in op.ObjectsToRemove)
-                                {
-                                    activeObjects.Remove(objItem);
-                                }
-                                // 添加合并后的物体
-                                activeObjects.Add(op.ObjectToAdd);
-                                break;
-
-                            case OperationType.Update:
-                                // 更新现有物体
-                                var obj = op.ObjectToUpdate;
-                                obj.MinStartCol = Math.Min(obj.MinStartCol, op.Region.Start);
-                                obj.MaxEndCol = Math.Max(obj.MaxEndCol, op.Region.End);
-                                obj.Area += op.Region.End - op.Region.Start + 1;
-                                obj.LastSeenLine = currentTimeLine;
-                                obj.RowsData.Add(new RowStartEndCol
-                                {
-                                    StartCol = op.Region.Start,
-                                    EndCol = op.Region.End,
-                                    RowsCol = currentTimeLine,
-                                });
-                                obj.LastSeenLineStartCol = op.Region.Start;
-                                obj.LastSeenLineEndCol = op.Region.End;
-                                break;
-
-                            case OperationType.Add:
-                                activeObjects.Add(op.ObjectToAdd);
-                                break;
-                        }
-                    }
-
-                    hasChanges = true;
-                }
-                finally
-                {
-                    _rwLock.ExitWriteLock();
-                }
-            }
-
-            return hasChanges;
+            //stopwatch.Stop();
+            //if (stopwatch.ElapsedMilliseconds > 1)
+            //{
+            //    FaultLog.RecordErrorMessage($"ShuLiClass-ProcessLine:图像区域合并超时,此次识别耗时:{stopwatch.Elapsed}");
+            //}
+            return result;
         }
 
         // 辅助类定义
@@ -1265,48 +876,6 @@ namespace CCDCount.DLL
             public ValidRegionModelClass Region { get; set; }
         }
 
-        // 计算聚合值的方法
-        private (int minStartCol, int maxEndCol, long minStartLine, long maxLastSeenLine,
-                 int minLastSeenStartCol, int maxLastSeenEndCol, DateTime minStartTime,
-                 DateTime maxEndTime,DateTime pictureMinReadTime,int totalArea, List<RowStartEndCol> mergedRowsData, int imageWidth)
-        CalculateAggregates(List<ActiveObjectClass> objects)
-        {
-            int minStartCol = int.MaxValue;
-            int maxEndCol = int.MinValue;
-            long minStartLine = int.MaxValue;
-            long maxLastSeenLine = int.MinValue;
-            int minLastSeenStartCol = int.MaxValue;
-            int maxLastSeenEndCol = int.MinValue;
-            DateTime minStartTime = DateTime.MaxValue;
-            DateTime maxEndTime = DateTime.MinValue;
-            DateTime pictureMinReadTime = DateTime.MaxValue;
-            int totalArea = 0;
-            int imageWidth = objects.FirstOrDefault()?.ImageWidth ?? IdentifyImageWidth;
-
-            var mergedRowsData = new List<RowStartEndCol>();
-
-            foreach (var obj in objects)
-            {
-                minStartCol = Math.Min(minStartCol, obj.MinStartCol);
-                maxEndCol = Math.Max(maxEndCol, obj.MaxEndCol);
-                minStartLine = Math.Min(minStartLine, obj.StartLine);
-                maxLastSeenLine = Math.Max(maxLastSeenLine, obj.LastSeenLine);
-                minLastSeenStartCol = Math.Min(minLastSeenStartCol, obj.LastSeenLineStartCol);
-                maxLastSeenEndCol = Math.Max(maxLastSeenEndCol, obj.LastSeenLineEndCol);
-
-                if (obj.StartCheckTime < minStartTime) minStartTime = obj.StartCheckTime;
-                if (obj.EndCheckTime > maxEndTime) maxEndTime = obj.EndCheckTime;
-                if (obj.PictureStartReadTime<pictureMinReadTime) pictureMinReadTime = obj.PictureStartReadTime;
-
-                totalArea += obj.Area;
-                mergedRowsData.AddRange(obj.RowsData);
-            }
-
-            return (minStartCol, maxEndCol, minStartLine, maxLastSeenLine,
-                    minLastSeenStartCol, maxLastSeenEndCol, minStartTime,
-                    maxEndTime,pictureMinReadTime,totalArea, mergedRowsData, imageWidth);
-        }
-
         List<ValidRegionModelClass> regions = new List<ValidRegionModelClass>();
         /// <summary>
         /// 检测有效物体区域(横向连续黑色像素段)
@@ -1379,48 +948,6 @@ namespace CCDCount.DLL
             return new List<ValidRegionModelClass>(regions);
         }
 
-        private List<ValidRegionModelClass> FindValidRegions(ReadOnlySpan<byte> image,int imageWidth, int RowNo)
-        {
-            regions.Clear();
-            regions.Capacity = 10;
-
-            ReadOnlySpan<byte> rowSpan;
-            if (shuLiConfig.IsIdentifyRoiOpen)
-            {
-                int offset = RowNo * imageWidth + shuLiConfig.IdentifyStartX;
-                int length = Math.Min(shuLiConfig.IdentifyStopX - shuLiConfig.IdentifyStartX,
-                                     imageWidth - shuLiConfig.IdentifyStartX);
-                rowSpan = image.Slice(offset, length);
-            }
-            else
-            {
-                rowSpan = image.Slice(RowNo * imageWidth, imageWidth);
-            }
-
-            int start = -1;
-            byte threshold = (byte)shuLiConfig.RegionThreshold;
-
-            for (int i = 0; i < rowSpan.Length; i++)
-            {
-                if (rowSpan[i] < threshold)
-                {
-                    if (start == -1) start = i;
-                }
-                else if (start != -1)
-                {
-                    regions.Add(new ValidRegionModelClass { Start = start, End = i - 1 });
-                    start = -1;
-                }
-            }
-
-            if (start != -1)
-            {
-                regions.Add(new ValidRegionModelClass { Start = start, End = rowSpan.Length - 1 });
-            }
-
-            return new List<ValidRegionModelClass>(regions);
-        }
-
         /// <summary>
         /// 判断区域重叠(与活跃物体的横向坐标重叠检测)
         /// </summary>
@@ -1430,7 +957,7 @@ namespace CCDCount.DLL
         private bool IsOverlapping(ActiveObjectClass obj, ValidRegionModelClass region)
         {
             // 判断区域是否不相交的逆条件
-            return !(region.End < obj.LastSeenLineStartCol || region.Start > obj.LastSeenLineEndCol);
+            return !(region.End < obj.PreSeenLineStartCol || region.Start > obj.PreSeenLineEndCol);
         }
 
         /// <summary>
@@ -1901,14 +1428,17 @@ namespace CCDCount.DLL
         private bool TryAdd(List<ActiveObjectClass> list, ActiveObjectClass item, int maxSize)
         {
             list.Add(item);
-            Interlocked.Increment(ref _HistoryActiveNum);
-            if(item.StateCode == 0)
+            if(item.StateCode!=9&& item.StateCode != 10)
             {
-                Interlocked.Increment(ref _OkHistoryNum);
-            }
-            else
-            {
-                Interlocked.Increment(ref _NgHistoryNum);
+                Interlocked.Increment(ref _HistoryActiveNum);
+                if (item.StateCode == 0)
+                {
+                    Interlocked.Increment(ref _OkHistoryNum);
+                }
+                else
+                {
+                    Interlocked.Increment(ref _NgHistoryNum);
+                }
             }
             if (list.Count > maxSize)
             {
@@ -1926,117 +1456,10 @@ namespace CCDCount.DLL
         //图像处理线程
         public Task ProcessingTask { get; set; }
         /// <summary>
-        /// 识别图像线程
+        /// 图像处理线程运行方法
         /// </summary>
-        private void IdentifyImageProcess()
-        {
-            Stopwatch stopwatch = Stopwatch.StartNew();
-            while (IsIdentify)
-            {
-                //判断队列中是否有数据
-                if (IFrameDatas.Count() > 0)
-                {
-                    stopwatch.Restart();
-                    if (IFrameDatas.Count() > 5)
-                    {
-                        //FaultLog.RecordErrorMessage($"图像数据队列中数据过多,请及时处理!当前数据数量为:{IFrameDatas.Count()}");
-                        FaultLog.RecordErrorMessage($"There is too much data in the image data queue. Please handle it in a timely manner! The current data quantity is:{IFrameDatas.Count()}");
-                        if (IFrameDatas.Count() > 100)
-                        {
-                            SystemAlarm.AlarmAlert(AlarmMessageList.待识别队列数据堆积,
-                                $"The image data queue is blocked. Please check the configuration and images",
-                                "待识别队列数据堆积,请检查设置和图像",
-                                "DLL:ShuLIClass-IdentifyImageProcess");
-                        }
-                        else
-                        {
-                            SystemAlarm.AlarmCancel(AlarmMessageList.待识别队列数据堆积);
-                        }
-                    }
-                    IFrameDatas.TryDequeue(out IFrameOut IframeData);
-                    stopwatch.Stop();
-                    //var ShiBieLuoHouTime = (DateTime.Now - FromUnixTimestamp((long)IframeData.HostTimeStamp)).TotalMilliseconds;
-                    //// 优化: 将日志记录改为条件执行
-                    //if (ShiBieLuoHouTime > 30)
-                    //{
-                    //    LOG.error($"算法落后了超过30ms,相机取图总耗时:{ShiBieLuoHouTime}");
-                    //}
-                    if (stopwatch.ElapsedMilliseconds > 5)
-                    {
-                        FaultLog.RecordErrorMessage($"ShuLiClass-IdentifyImageProcess:Image reading timed out, this recognition took time:{stopwatch.Elapsed}");
-                    }
-                    if (IframeData != null)
-                    {
-                        //识别
-                        ProcessImageSequence2(IframeData);
-                        IframeData.Dispose();
-                    }
-                    else
-                    {
-                        continue;
-                    }
-                }
-                else
-                {
-                    Thread.Sleep(1);
-                }
-            }
-        }
-
+        /// <param name="token"></param>
         private async void IdentifyImageProcessTask(CancellationToken token)
-        {
-            Stopwatch stopwatch = Stopwatch.StartNew();
-            const int batchSize = 5; // 每批处理的最大图像数量
-            var batch = new List<IFrameOut>(batchSize); // 存储当前批次的图像
-            while (!token.IsCancellationRequested)
-            {
-                // 等待图像数据
-                await QueueSemaphore.WaitAsync(token);
-                //判断队列中是否有数据
-                if (IFrameDatas.Count() > 5)
-                {
-                    //FaultLog.RecordErrorMessage($"图像数据队列中数据过多,请及时处理!当前数据数量为:{IFrameDatas.Count()}");
-                    FaultLog.RecordErrorMessage($"There is too much data in the image data queue. Please handle it in a timely manner! The current data quantity is:{IFrameDatas.Count()}");
-                    if (IFrameDatas.Count() > 100)
-                    {
-                        SystemAlarm.AlarmAlert(AlarmMessageList.待识别队列数据堆积,
-                            $"The image data queue is blocked. Please check the configuration and images",
-                            "待识别队列数据堆积,请检查设置和图像",
-                            "DLL:ShuLIClass-IdentifyImageProcess");
-                    }
-                    else
-                    {
-                        SystemAlarm.AlarmCancel(AlarmMessageList.待识别队列数据堆积);
-                    }
-                }
-                // 收集一批图像(严格按队列顺序)
-                while (batch.Count < batchSize && IFrameDatas.TryDequeue(out IFrameOut imageData))
-                {
-                    batch.Add(imageData);
-                    if (IFrameDatas.Count > 0)
-                    {
-                        QueueSemaphore.Release(); // 提前释放信号量,唤醒其他等待线程
-                    }
-                }
-                // 顺序处理当前批次的所有图像
-                foreach (var image in batch)
-                {
-                    if (image != null)
-                    {
-                        //识别
-                        ProcessImageSequence2(image);
-                        image.Dispose();
-                    }
-                    else
-                    {
-                        continue;
-                    }
-                }
-                batch.Clear();
-            }
-        }
-
-        private async void IdentifyImageProcessTask2(CancellationToken token)
         {
             const int batchSize = 5; // 每批处理的最大图像数量
             var batch = new List<IFrameOut>(batchSize); // 存储当前批次的图像
@@ -2050,10 +1473,6 @@ namespace CCDCount.DLL
                     while (batch.Count < batchSize && RingBuffer_IFrameDatas.TryDequeue(out IFrameOut imageData))
                     {
                         batch.Add(imageData);
-                        if (RingBuffer_IFrameDatas.Count > 0)
-                        {
-                            QueueSemaphore.Release(); // 提前释放信号量,唤醒其他等待线程
-                        }
                     }
                     // 顺序处理当前批次的所有图像
                     foreach (var image in batch)
@@ -2061,7 +1480,7 @@ namespace CCDCount.DLL
                         if (image != null)
                         {
                             //识别
-                            ProcessImageSequence2(image);
+                            ProcessImageSequence(image);
                             image.Dispose();
                         }
                         else
@@ -2073,9 +1492,10 @@ namespace CCDCount.DLL
                 }
                 catch(Exception ex)
                 {
-
+                    LOG.error("ShuLiClass-IdentifyImageProcessTask:" + ex.Message);
                 }
             }
+            LOG.log("图像处理线程运行结束", 6);
         }
         #endregion
     }

+ 173 - 10
TestWork.DLL/SqlDataClass/ActionMesSqliteDataClass.cs

@@ -133,6 +133,10 @@ namespace CCDCount.DLL.SqlDataClass
                 {
                     try
                     {
+                        // 获取插入前的最大 ID
+                        var cmdGetMaxId = new SQLiteCommand("SELECT COALESCE(MAX(Id), 0) FROM ActiveObject", conn);
+                        var startId = Convert.ToInt32(cmdGetMaxId.ExecuteScalar()) + 1;
+
                         // 构建批量插入语句
                         var sqlBuilder = new StringBuilder();
                         sqlBuilder.Append(@"
@@ -160,8 +164,8 @@ namespace CCDCount.DLL.SqlDataClass
                             // 绑定参数值
                             parameters.AddRange(new object[]
                             {
-                            obj.Num, obj.MinStartCol, obj.MaxEndCol, obj.LastSeenLineStartCol,
-                            obj.LastSeenLineEndCol, obj.StartLine, obj.LastSeenLine,
+                            obj.Num, obj.MinStartCol, obj.MaxEndCol, obj.PreSeenLineStartCol,
+                            obj.PreSeenLineEndCol, obj.StartLine, obj.LastSeenLine,
                             obj.StartCheckTime.ToString("o"), obj.EndCheckTime.ToString("o"),
                             obj.Area, obj.MaxLength, obj.ChannelNO, obj.ImageWidth,
                             obj.StateCode, obj.BatchNumber, obj.hasSignificantConcavity, obj.concavityRatio
@@ -178,6 +182,8 @@ namespace CCDCount.DLL.SqlDataClass
 
                             cmd.ExecuteNonQuery();
                         }
+                        // 批量插入 RowData
+                        InsertRowDataBatch(conn, batch, startId);
 
                         transaction.Commit();
                     }
@@ -222,8 +228,8 @@ namespace CCDCount.DLL.SqlDataClass
                                 cmd.Parameters.AddWithValue("@Num", activeObject.Num);
                                 cmd.Parameters.AddWithValue("@MinStartCol", activeObject.MinStartCol);
                                 cmd.Parameters.AddWithValue("@MaxEndCol", activeObject.MaxEndCol);
-                                cmd.Parameters.AddWithValue("@LastSeenLineStartCol", activeObject.LastSeenLineStartCol);
-                                cmd.Parameters.AddWithValue("@LastSeenLineEndCol", activeObject.LastSeenLineEndCol);
+                                cmd.Parameters.AddWithValue("@LastSeenLineStartCol", activeObject.PreSeenLineStartCol);
+                                cmd.Parameters.AddWithValue("@LastSeenLineEndCol", activeObject.PreSeenLineEndCol);
                                 cmd.Parameters.AddWithValue("@StartLine", activeObject.StartLine);
                                 cmd.Parameters.AddWithValue("@LastSeenLine", activeObject.LastSeenLine);
                                 cmd.Parameters.AddWithValue("@StartCheckTime", activeObject.StartCheckTime.ToString("o"));
@@ -256,6 +262,73 @@ namespace CCDCount.DLL.SqlDataClass
             }
         }
 
+        // 批量插入 RowData 数据
+        private void InsertRowDataBatch(SQLiteConnection conn, List<ActiveObjectClass> batch, int startId)
+        {
+            // 先统计总行数,判断是否需要插入
+            var totalRows = 0;
+            foreach (var obj in batch)
+            {
+                if (obj.RowsData != null && obj.RowsData.Count > 0)
+                {
+                    totalRows += obj.RowsData.Count;
+                }
+            }
+
+            if (totalRows == 0)
+                return;
+
+            // 构建批量插入语句
+            var sqlBuilder = new StringBuilder();
+            sqlBuilder.Append(@"
+                INSERT INTO RowData (
+                ActiveObjectId, RowsCol, StartCol, EndCol
+                ) VALUES ");
+
+            var parameters = new List<object>();
+            int paramIndex = 0;
+            int currentId = startId;
+
+            foreach (var obj in batch)
+            {
+                if (obj.RowsData == null || obj.RowsData.Count == 0)
+                {
+                    currentId++;
+                    continue;
+                }
+
+                foreach (var row in obj.RowsData)
+                {
+                    sqlBuilder.Append($"(@p{paramIndex * 4}, @p{paramIndex * 4 + 1}, @p{paramIndex * 4 + 2}, @p{paramIndex * 4 + 3})");
+
+                    if (paramIndex < totalRows - 1)
+                        sqlBuilder.Append(", ");
+
+                    parameters.AddRange(new object[]
+                    {
+                        currentId,
+                        row.RowsCol,
+                        row.StartCol,
+                        row.EndCol
+                    });
+
+                    paramIndex++;
+                }
+
+                currentId++;
+            }
+
+            // 执行批量插入
+            using (var cmd = new SQLiteCommand(sqlBuilder.ToString(), conn))
+            {
+                for (int i = 0; i < parameters.Count; i++)
+                {
+                    cmd.Parameters.AddWithValue($"@p{i}", parameters[i]);
+                }
+                cmd.ExecuteNonQuery();
+            }
+        }
+
         // 插入RowData数据
         private void InsertRowData(SQLiteConnection conn, int activeObjectId, List<RowStartEndCol> rowsData)
         {
@@ -313,8 +386,8 @@ namespace CCDCount.DLL.SqlDataClass
                                     Num = Convert.ToInt32(reader["Num"]),
                                     MinStartCol = Convert.ToInt32(reader["MinStartCol"]),
                                     MaxEndCol = Convert.ToInt32(reader["MaxEndCol"]),
-                                    LastSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
-                                    LastSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
+                                    PreSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
+                                    PreSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
                                     StartLine = Convert.ToInt64(reader["StartLine"]),
                                     LastSeenLine = Convert.ToInt64(reader["LastSeenLine"]),
                                     StartCheckTime = DateTime.Parse(reader["StartCheckTime"].ToString()),
@@ -392,8 +465,8 @@ namespace CCDCount.DLL.SqlDataClass
                                     Num = Convert.ToInt32(reader["Num"]),
                                     MinStartCol = Convert.ToInt32(reader["MinStartCol"]),
                                     MaxEndCol = Convert.ToInt32(reader["MaxEndCol"]),
-                                    LastSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
-                                    LastSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
+                                    PreSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
+                                    PreSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
                                     StartLine = Convert.ToInt64(reader["StartLine"]),
                                     LastSeenLine = Convert.ToInt64(reader["LastSeenLine"]),
                                     StartCheckTime = DateTime.Parse(reader["StartCheckTime"].ToString()),
@@ -464,8 +537,8 @@ namespace CCDCount.DLL.SqlDataClass
                                             Num = Convert.ToInt32(reader["Num"]),
                                             MinStartCol = Convert.ToInt32(reader["MinStartCol"]),
                                             MaxEndCol = Convert.ToInt32(reader["MaxEndCol"]),
-                                            LastSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
-                                            LastSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
+                                            PreSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
+                                            PreSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
                                             StartLine = Convert.ToInt64(reader["StartLine"]),
                                             LastSeenLine = Convert.ToInt64(reader["LastSeenLine"]),
                                             StartCheckTime = DateTime.Parse(reader["StartCheckTime"].ToString()),
@@ -573,6 +646,96 @@ namespace CCDCount.DLL.SqlDataClass
             return result;
         }
 
+        public List<ActiveObjectClass> GetAllErrorAction()
+        {
+            List<ActiveObjectClass> activeObjects = new List<ActiveObjectClass>();
+            try
+            {
+                using (var conn = new SQLiteConnection(_connectionString))
+                {
+                    conn.Open();
+                    const string query = @"
+                        SELECT 
+                            ao.*,
+                            rd.Id AS RowId, rd.RowsCol, rd.StartCol, rd.EndCol
+                        FROM ActiveObject ao
+                        LEFT JOIN RowData rd ON ao.Id = rd.ActiveObjectId
+                        WHERE ao.StateCode != 0";
+
+                    using (var cmd = new SQLiteCommand(query, conn))
+                    {
+                        using (var reader = cmd.ExecuteReader())
+                        {
+                            int NowId = -1;
+                            ActiveObjectClass activeObject = null;
+                            var rowsData = new List<RowStartEndCol>();
+
+                            while (reader.Read())
+                            {
+                                object value = reader["Id"];
+                                if (!Convert.IsDBNull(value))
+                                {
+                                    if (NowId != Convert.ToInt32(reader["Id"]))
+                                    {
+                                        if (activeObject != null)
+                                        {
+                                            activeObjects.Add(activeObject);
+                                            activeObject = null;
+                                            rowsData = new List<RowStartEndCol>();
+                                        }
+                                        NowId = Convert.ToInt32(reader["Id"]);
+                                    }
+                                    // 只初始化主对象一次
+                                    if (activeObject == null)
+                                    {
+                                        activeObject = new ActiveObjectClass
+                                        {
+                                            Num = Convert.ToInt32(reader["Num"]),
+                                            MinStartCol = Convert.ToInt32(reader["MinStartCol"]),
+                                            MaxEndCol = Convert.ToInt32(reader["MaxEndCol"]),
+                                            PreSeenLineStartCol = Convert.ToInt32(reader["LastSeenLineStartCol"]),
+                                            PreSeenLineEndCol = Convert.ToInt32(reader["LastSeenLineEndCol"]),
+                                            StartLine = Convert.ToInt64(reader["StartLine"]),
+                                            LastSeenLine = Convert.ToInt64(reader["LastSeenLine"]),
+                                            StartCheckTime = DateTime.Parse(reader["StartCheckTime"].ToString()),
+                                            EndCheckTime = DateTime.Parse(reader["EndCheckTime"].ToString()),
+                                            Area = Convert.ToInt32(reader["Area"]),
+                                            MaxLength = Convert.ToDouble(reader["MaxLength"]),
+                                            ChannelNO = Convert.ToInt32(reader["ChannelNO"]),
+                                            ImageWidth = Convert.ToInt32(reader["ImageWidth"]),
+                                            StateCode = Convert.ToInt32(reader["StateCode"]),
+                                            BatchNumber = reader["BatchNumber"].ToString(),
+                                            RowsData = rowsData
+                                        };
+                                    }
+
+                                    // 添加行数据(确保RowData记录存在)
+                                    rowsData.Add(new RowStartEndCol
+                                    {
+                                        RowsCol = Convert.ToInt64(reader["RowsCol"]),
+                                        StartCol = Convert.ToInt32(reader["StartCol"]),
+                                        EndCol = Convert.ToInt32(reader["EndCol"])
+                                    });
+                                }
+                            }
+
+                            if (activeObject != null)
+                            {
+                                activeObjects.Add(activeObject);
+                                activeObject = null;
+                                rowsData = new List<RowStartEndCol>();
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"GetActiveObjectForPage - Error:{ex.Message}");
+            }
+            return activeObjects;
+        }
+
         // 关闭定时器并释放资源
         public void Dispose()
         {

+ 198 - 1
TestWork.DLL/Tools/AutoStartHelper.cs

@@ -15,6 +15,20 @@ namespace CCDCount.DLL.Tools
         // 应用名称,作为注册表键名
         private static readonly string AppName = "CCDCount";
 
+        /// <summary>
+        /// 获取当前可执行文件路径(带引号,用于注册表)
+        /// </summary>
+        public static string GetExecutablePathForRegistry()
+        {
+            string path = Process.GetCurrentProcess().MainModule.FileName;
+            // 如果路径包含空格,必须用双引号包裹
+            if (path.Contains(" "))
+            {
+                return $"\"{path}\"";
+            }
+            return path;
+        }
+
         /// <summary>
         /// 获取当前可执行文件路径
         /// </summary>
@@ -51,7 +65,7 @@ namespace CCDCount.DLL.Tools
                 {
                     if (!IsAutoStart())
                     {
-                        key.SetValue(AppName, GetExecutablePath());
+                        key.SetValue(AppName, GetExecutablePathForRegistry());
                     }
                 }
                 else
@@ -61,5 +75,188 @@ namespace CCDCount.DLL.Tools
                 }
             }
         }
+
+
+        private const string TaskName = "CCDCount";
+
+        /// <summary>
+        /// 检查任务是否已注册且处于启用状态
+        /// </summary>
+        /// <returns>true: 已注册且启用; false: 未注册或已禁用</returns>
+        public static bool IsTaskRegisteredAndEnabled()
+        {
+            try
+            {
+                // 查询任务状态
+                // /fo LIST 以列表格式输出
+                // /v 显示详细信息
+                string arguments = $"/query /tn \"{TaskName}\" /fo LIST /v";
+
+                ProcessStartInfo startInfo = new ProcessStartInfo
+                {
+                    FileName = "schtasks",
+                    Arguments = arguments,
+                    UseShellExecute = false,
+                    RedirectStandardOutput = true,
+                    RedirectStandardError = true,
+                    CreateNoWindow = true
+                };
+
+                using (Process process = Process.Start(startInfo))
+                {
+                    string output = process.StandardOutput.ReadToEnd();
+                    process.WaitForExit();
+
+                    if (process.ExitCode == 0)
+                    {
+                        // 检查输出中是否包含 "Status: Ready" 或 "State: Enabled"
+                        // 不同语言版本的Windows输出可能略有不同,通常检查 "Ready" 或 "Enabled"
+                        // 英文系统: "Status: Ready"
+                        // 中文系统: "状态: 就绪"
+
+                        // 更通用的方法是检查是否存在该任务名,且没有报错
+                        // 如果需要严格判断是否启用,可以解析输出中的 "Status" 行
+
+                        if (output.Contains("Ready") || output.Contains("就绪"))
+                        {
+                            return true;
+                        }
+
+                        // 如果任务是 "Disabled" (禁用) 或 "Disabled" (中文: 已禁用),则返回 false
+                        if (output.Contains("Disabled") || output.Contains("已禁用"))
+                        {
+                            return false;
+                        }
+
+                        // 其他状态视为未准备好
+                        return false;
+                    }
+                    else
+                    {
+                        // 退出码非0,通常意味着任务不存在 (ERROR: The system cannot find the file specified.)
+                        return false;
+                    }
+                }
+            }
+            catch (Exception)
+            {
+                // 发生异常时,保守地认为未注册,以便后续尝试重新注册
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 创建或更新开机自启任务
+        /// </summary>
+        public static void RegisterTask()
+        {
+            // 1. 先检查是否已经正确配置
+            if (IsTaskRegisteredAndEnabled())
+            {
+                // 可选:进一步检查路径是否一致,如果路径变了也需要更新
+                // 这里为了简化,如果已启用则直接返回,避免重复弹窗
+                Console.WriteLine("任务已存在且处于启用状态,无需操作。");
+                return;
+            }
+
+            try
+            {
+                string exePath = Process.GetCurrentProcess().MainModule.FileName;
+
+                // 构建 schtasks 命令
+                // /ru "" 表示以当前用户运行 (在某些Win11版本中,显式指定用户更稳定)
+                // /rl highest 表示以最高权限运行
+                // /sc onlogon 表示登录时触发
+                // /f 强制覆盖已存在的任务
+                string arguments = $"/create /tn \"{TaskName}\" /tr \"\\\"{exePath}\\\"\" /sc onlogon /rl highest /f";
+
+                ProcessStartInfo startInfo = new ProcessStartInfo
+                {
+                    FileName = "schtasks",
+                    Arguments = arguments,
+                    UseShellExecute = false,
+                    RedirectStandardOutput = true,
+                    RedirectStandardError = true,
+                    Verb = "runas" // 请求管理员权限
+                };
+
+                using (Process process = Process.Start(startInfo))
+                {
+                    process.WaitForExit();
+                    if (process.ExitCode == 0)
+                    {
+                        Console.WriteLine("任务计划创建/更新成功");
+                    }
+                    else
+                    {
+                        string error = process.StandardError.ReadToEnd();
+                        Console.WriteLine($"创建失败: {error}");
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"异常: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 删除开机自启任务
+        /// </summary>
+        public static void UnregisterTask()
+        {
+            // 可选:先检查是否存在,避免无意义的弹窗
+            try
+            {
+                string checkArgs = $"/query /tn \"{TaskName}\"";
+                ProcessStartInfo checkInfo = new ProcessStartInfo("schtasks", checkArgs)
+                {
+                    UseShellExecute = false,
+                    CreateNoWindow = true
+                };
+                using (var p = Process.Start(checkInfo))
+                {
+                    p.WaitForExit();
+                    if (p.ExitCode != 0)
+                    {
+                        Console.WriteLine("任务不存在,无需删除。");
+                        return;
+                    }
+                }
+            }
+            catch { }
+
+            try
+            {
+                string arguments = $"/delete /tn \"{TaskName}\" /f";
+                ProcessStartInfo startInfo = new ProcessStartInfo
+                {
+                    FileName = "schtasks",
+                    Arguments = arguments,
+                    UseShellExecute = false,
+                    RedirectStandardOutput = true,
+                    RedirectStandardError = true,
+                    Verb = "runas"
+                };
+
+                using (Process process = Process.Start(startInfo))
+                {
+                    process.WaitForExit();
+                    if (process.ExitCode == 0)
+                    {
+                        Console.WriteLine("任务删除成功");
+                    }
+                    else
+                    {
+                        string error = process.StandardError.ReadToEnd();
+                        Console.WriteLine($"删除失败: {error}");
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"删除任务失败: {ex.Message}");
+            }
+        }
     }
 }

+ 5 - 4
TestWork.DLL/Tools/ConfigManager.cs

@@ -38,13 +38,13 @@ namespace CCDCount.DLL.Tools
                 _saveConfigModel.CameraConfig.IsLoadCanfig = true;
             }
         }
-        public void SaveConfigs()
+        public void SaveConfigs(string FormulationName)
         {
             if (!Directory.Exists(".\\Config\\"))
             {
                 Directory.CreateDirectory(".\\Config\\");
             }
-            SaveCCDCountConfig();
+            SaveCCDCountConfig(FormulationName);
         }
 
         private SaveConfigModel GetCCDCountConfig()
@@ -53,6 +53,7 @@ namespace CCDCount.DLL.Tools
             if (File.Exists(".\\Config\\CCDCountConfig.xml"))
             {
                 Result = XmlStorage.DeserializeFromXml<SaveConfigModel>(".\\Config\\CCDCountConfig.xml");
+                Result.ShuLiConfigClass.IsLoadCanfig = true;
             }
             else
             {
@@ -66,9 +67,9 @@ namespace CCDCount.DLL.Tools
             }
             return Result;
         }
-        private void SaveCCDCountConfig()
+        private void SaveCCDCountConfig(string FormulationName)
         {
-
+            _saveConfigModel.ConfigName = FormulationName;
             XmlStorage.SerializeToXml(_saveConfigModel, ".\\Config\\CCDCountConfig.xml");
         }
     }

+ 128 - 6
TestWork.DLL/Tools/OnScreenKeyboardClass.cs

@@ -3,6 +3,7 @@ using System;
 using System.Diagnostics;
 using System.IO;
 using System.Runtime.InteropServices;
+using System.Threading;
 using System.Threading.Tasks;
 
 namespace CCDCount.DLL.Tools
@@ -18,7 +19,15 @@ namespace CCDCount.DLL.Tools
         [DllImport("user32.dll")]
         private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
 
+        [DllImport("user32.dll")]
+        private static extern bool SetForegroundWindow(IntPtr hWnd);
+
+        [DllImport("user32.dll")]
+        private static extern bool IsIconic(IntPtr hWnd);
+
+
         private const int SW_SHOW = 5;
+        private const int SW_RESTORE = 9;
         private const int SW_HIDE = 0;
         /// <summary>
         /// 启动软键盘(兼容Windows 10及以上版本)
@@ -34,6 +43,7 @@ namespace CCDCount.DLL.Tools
             //}
 
             // 回退到传统osk
+            //StartOnScreenKeyboardRobust();
             StartOnScreenKeyboard();
         }
 
@@ -45,11 +55,11 @@ namespace CCDCount.DLL.Tools
             try
             {
                 // 隐藏TabTip窗口
-                IntPtr tabTipHwnd = FindWindow("IPTip_Main_Window", null);
-                if (tabTipHwnd != IntPtr.Zero)
-                {
-                    ShowWindow(tabTipHwnd, SW_HIDE);
-                }
+                //IntPtr tabTipHwnd = FindWindow("IPTip_Main_Window", null);
+                //if (tabTipHwnd != IntPtr.Zero)
+                //{
+                //    ShowWindow(tabTipHwnd, SW_HIDE);
+                //}
 
                 // 隐藏OSK窗口
                 IntPtr oskHwnd = FindWindow("OSKMainClass", "屏幕键盘");
@@ -77,7 +87,20 @@ namespace CCDCount.DLL.Tools
                     IntPtr oskHwnd = FindWindow("OSKMainClass", "屏幕键盘");
                     if (oskHwnd != IntPtr.Zero)
                     {
-                        ShowWindow(oskHwnd, SW_SHOW);
+                        // 【修改点】:判断是否最小化
+                        if (IsIconic(oskHwnd))
+                        {
+                            // 如果最小化,使用 SW_RESTORE (9) 恢复窗口
+                            ShowWindow(oskHwnd, SW_RESTORE);
+                        }
+                        else
+                        {
+                            // 如果未最小化,使用 SW_SHOW (5) 显示/激活
+                            ShowWindow(oskHwnd, SW_SHOW);
+                        }
+
+                        // 确保窗口前置
+                        SetForegroundWindow(oskHwnd);
                         return;
                     }
                     else
@@ -98,6 +121,105 @@ namespace CCDCount.DLL.Tools
             }
         }
 
+        /// <summary>
+        /// 健壮的 OSK 启动方法
+        /// </summary>
+        private static void StartOnScreenKeyboardRobust()
+        {
+            try
+            {
+                // 1. 彻底清理已存在的 osk 进程,防止句柄冲突
+                KillOskProcess();
+
+                // 2. 准备启动信息
+                string oskPath = Path.Combine(Environment.SystemDirectory, "osk.exe");
+                if (!File.Exists(oskPath))
+                {
+                    throw new FileNotFoundException("未找到 osk.exe", oskPath);
+                }
+
+                ProcessStartInfo startInfo = new ProcessStartInfo
+                {
+                    FileName = oskPath,
+                    UseShellExecute = true, // 关键:使用 Shell 执行,有助于权限处理
+                    Verb = "open"
+                };
+
+                // 3. 启动进程
+                Process proc = Process.Start(startInfo);
+
+                // 4. 等待窗口出现并激活
+                // osk.exe 启动较慢,需要轮询等待窗口句柄
+                IntPtr hwnd = IntPtr.Zero;
+                int retryCount = 0;
+                const int maxRetries = 50; // 最多等待 5秒 (50 * 100ms)
+
+                while (retryCount < maxRetries)
+                {
+                    // 查找窗口类名 OSKMainClass,标题可能是 "屏幕键盘" 或 "On-Screen Keyboard" (取决于系统语言)
+                    hwnd = FindWindow("OSKMainClass", null);
+
+                    if (hwnd != IntPtr.Zero)
+                    {
+                        break;
+                    }
+
+                    Thread.Sleep(100);
+                    retryCount++;
+                }
+
+                if (hwnd != IntPtr.Zero)
+                {
+                    // 确保窗口不是最小化状态
+                    if (IsIconic(hwnd))
+                    {
+                        ShowWindow(hwnd, SW_RESTORE);
+                    }
+                    else
+                    {
+                        ShowWindow(hwnd, SW_SHOW);
+                    }
+
+                    // 尝试将窗口前置
+                    SetForegroundWindow(hwnd);
+                }
+                else
+                {
+                    System.Diagnostics.Debug.WriteLine("警告: OSK 进程已启动,但未检测到窗口句柄。可能需要管理员权限。");
+                }
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"启动 OSK 失败: {ex.Message}");
+                // 在生产环境中,建议记录日志而不是直接抛出异常,以免崩溃主程序
+            }
+        }
+
+        /// <summary>
+        /// 强制杀死所有 osk 进程
+        /// </summary>
+        private static void KillOskProcess()
+        {
+            try
+            {
+                Process[] processes = Process.GetProcessesByName("osk");
+                foreach (var p in processes)
+                {
+                    try
+                    {
+                        if (!p.HasExited)
+                        {
+                            p.Kill();
+                            p.WaitForExit(1000); // 等待进程完全退出
+                        }
+                    }
+                    catch { }
+                }
+            }
+            catch { }
+        }
+
+
         private static bool IsWindows10OrHigher()
         {
             var os = Environment.OSVersion;

+ 0 - 19
TestWork.DLL/packages.config

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="CsvHelper" version="33.0.1" targetFramework="net48" />
-  <package id="EntityFramework" version="6.4.4" targetFramework="net48" />
-  <package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
-  <package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net48" />
-  <package id="Microsoft.CSharp" version="4.7.0" targetFramework="net48" />
-  <package id="NModbus" version="3.0.81" targetFramework="net48" />
-  <package id="Stub.System.Data.SQLite.Core.NetFramework" version="1.0.119.0" targetFramework="net48" />
-  <package id="System.Buffers" version="4.4.0" targetFramework="net48" />
-  <package id="System.Data.SQLite" version="1.0.119.0" targetFramework="net48" />
-  <package id="System.Data.SQLite.Core" version="1.0.119.0" targetFramework="net48" />
-  <package id="System.Data.SQLite.EF6" version="1.0.119.0" targetFramework="net48" />
-  <package id="System.Data.SQLite.Linq" version="1.0.119.0" targetFramework="net48" />
-  <package id="System.Memory" version="4.5.0" targetFramework="net48" />
-  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net48" />
-  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net48" />
-  <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
-</packages>

+ 19 - 0
TestWork.MODEL/PlcModel/PlcAlarmModelClass.cs

@@ -79,5 +79,24 @@ namespace CCDCount.MODEL.PlcModel
         /// 缺瓶信号
         /// </summary>
         public bool MissingBottleSignal { get; set; }
+
+        /// <summary>
+        /// 心跳报警
+        /// </summary>
+        public bool PLCCameraHeartErrorSignal { get; set; }
+
+        /// <summary>
+        /// 视觉未启动报警
+        /// </summary>
+        public bool CameraNotRunSignal { get; set; }
+
+        /// <summary>
+        /// 颗粒缓存超限报警
+        /// </summary>
+        public bool ParticleCacheOverflowSignal { get; set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public bool PLCConnecting { get; set; }
     }
 }

+ 16 - 0
TestWork.MODEL/PlcModel/PlcParaModelClass.cs

@@ -243,5 +243,21 @@ namespace CCDCount.MODEL.PlcModel
         /// 装瓶数量
         /// </summary>
         public ushort BottleCounting { get; set; }
+        /// <summary>
+        /// 缺瓶停机开始时间
+        /// </summary>
+        public ushort MissBottleReSestart { get; set; }
+        /// <summary>
+        /// 拦放瓶时间
+        /// </summary>
+        public ushort BottleStopPassTime {  get; set; }
+        /// <summary>
+        /// 报警时间
+        /// </summary>
+        public ushort BuzzerTime {  get; set; }
+        /// <summary>
+        /// 缓存震台速比
+        /// </summary>
+        public ushort CacheDecelerateProportion {  get; set; }
     }
 }

+ 0 - 66
TestWork.MODEL/PlcModel/PlcStaticModelClass.cs

@@ -1,66 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CCDCount.MODEL.PlcModel
-{
-    public class PlcStaticModelClass
-    {
-        /// <summary>
-        /// 使能完成
-        /// </summary>
-        public bool EnableCompletion { get; set; }
-
-        /// <summary>
-        /// 归零完成
-        /// </summary>
-        public bool ReturnToZeroCompletion { get; set; }
-
-        /// <summary>
-        /// 停止完成
-        /// </summary>
-        public bool StopCompletion { get; set; }
-
-        /// <summary>
-        /// 速度运行
-        /// </summary>
-        public bool SpeedRunning { get; set;}
-
-        /// <summary>
-        /// 回零中
-        /// </summary>
-        public bool ReturnToZero { get; set;}
-
-        /// <summary>
-        /// 中转阀开定位完成 
-        /// </summary>
-        public bool TransferValveOpenCompletion { get; set;}
-
-        /// <summary>
-        /// 中转阀关定位完成
-        /// </summary>
-        public bool TransferValveCloseCompletion { get; set;}
-
-        /// <summary>
-        /// 允许数据交换
-        /// </summary>
-        public bool AllowsDataExchange { get; set;}
-
-        /// <summary>
-        /// 暂停获取数据
-        /// </summary>
-        public bool PauseDataExchange { get; set;}
-
-        /// <summary>
-        /// 缓存计数延时完成
-        /// </summary>
-        public bool CacheCountDelayed { get; set;}
-
-        /// <summary>
-        /// 使能
-        /// </summary>
-        public bool Enable { get; set;}
-    }
-}

+ 11 - 2
TestWork.MODEL/ShuLiModel/ActiveObjectClass.cs

@@ -28,11 +28,20 @@ namespace CCDCount.MODEL.ShuLiModel
         /// <summary>
         /// 上一行起始列坐标
         /// </summary>
-        public int LastSeenLineStartCol { get; set; }
+        public int PreSeenLineStartCol { get; set; }
         /// <summary>
         /// 上一行结束列坐标
         /// </summary>
-        public int LastSeenLineEndCol { get; set; }
+        public int PreSeenLineEndCol { get; set; }
+
+        /// <summary>
+        /// 最后一行起始列坐标
+        /// </summary>
+        public int LastSeenLineStartCol { get; set; } = -1;
+        /// <summary>
+        /// 最后一行结束列坐标
+        /// </summary>
+        public int LastSeenLineEndCol { get; set; } = -1;
         /// <summary>
         /// 最开始出现的行号
         /// </summary>

+ 10 - 2
WpfSwitchLanguage/Language/String_Chinese.xaml

@@ -58,6 +58,8 @@
     <system:String x:Key="Pause">暂停</system:String>
     <system:String x:Key="PreviousOne">上一张</system:String>
     <system:String x:Key="NextOne">下一张</system:String>
+    <system:String x:Key="PreviousErrorOne">上一异常</system:String>
+    <system:String x:Key="NextErrorOne">下一异常</system:String>
     <system:String x:Key="Jump">跳转</system:String>
     <system:String x:Key="SwitchTo">跳转至</system:String>
     <system:String x:Key="Sheets">张</system:String>
@@ -154,7 +156,7 @@
     <system:String x:Key="MachineManualUp">整机上升</system:String>
     <system:String x:Key="MachineManualDown">整机下降</system:String>
     <system:String x:Key="FunnelValveManualControl">漏斗</system:String>
-    <system:String x:Key="MachineAirLockValve">气锁开</system:String>
+    <system:String x:Key="MachineAirLockValve">气锁开</system:String>
     <system:String x:Key="FillingValveCacheSpeed">中转阀缓存速度:</system:String>
     <system:String x:Key="FillingValveCachePosition">中转阀缓存位置:</system:String>
     <system:String x:Key="InBottleSpeed">进瓶速度:</system:String>
@@ -163,7 +165,7 @@
     <system:String x:Key="MachineDelayFillingValveOpenTime">中转阀打开延时:</system:String>
     <system:String x:Key="MachineDelayFillingValveCloseTime">中转阀关闭延时:</system:String>
     <system:String x:Key="MachineDelayInBottleTime">进瓶延时:</system:String>
-    <system:String x:Key="ValveDelytime">气阀开延时:</system:String>
+    <system:String x:Key="ValveDelytime">闸板开延时:</system:String>
     <system:String x:Key="MissingDelaytime">缺瓶检测时间:</system:String>
     <system:String x:Key="BottleJamDelaytime">堵瓶检测时间:</system:String>
     <system:String x:Key="EliminateCylinderDelayTime">剔废气缸延时时间:</system:String>
@@ -183,4 +185,10 @@
     <system:String x:Key="BatchFilter">批次选择:</system:String>
     <system:String x:Key="RecordingInterval">记录间隔:</system:String>
     <system:String x:Key="MaterialShortageStoppageDelayTime">缺料停机延时:</system:String>
+    <system:String x:Key="BottleStopper">拦瓶</system:String>
+    <system:String x:Key="BottlePass">放瓶</system:String>
+    <system:String x:Key="MissBottleRestartTime">缺瓶停机开始时间:</system:String>
+    <system:String x:Key="BottleStopPassTime">拦放瓶时间:</system:String>
+    <system:String x:Key="BuzzerTime">报警时间:</system:String>
+    <system:String x:Key="CacheDecelerateProportion">缓存减速比:</system:String>
 </ResourceDictionary>

+ 8 - 0
WpfSwitchLanguage/Language/String_English.xaml

@@ -58,6 +58,8 @@
     <system:String x:Key="Pause">Pause</system:String>
     <system:String x:Key="PreviousOne">Previous One</system:String>
     <system:String x:Key="NextOne">Next One</system:String>
+    <system:String x:Key="PreviousErrorOne">Previous One Error</system:String>
+    <system:String x:Key="NextErrorOne">Next One Error</system:String>
     <system:String x:Key="Jump">Switch</system:String>
     <system:String x:Key="SwitchTo">SwitchTo</system:String>
     <system:String x:Key="Sheets">Sheets</system:String>
@@ -183,4 +185,10 @@
     <system:String x:Key="BatchFilter">Batch Filter:</system:String>
     <system:String x:Key="RecordingInterval">RecordingInterval:</system:String>
     <system:String x:Key="MaterialShortageStoppageDelayTime">Material Shortage Stoppage Delay Time:</system:String>
+    <system:String x:Key="BottleLockOpen">BottleLockOpen</system:String>
+    <system:String x:Key="BottleLockClose">BottleLockClose</system:String>
+    <system:String x:Key="MissBottleRestartTime">Miss Bottle Restart Time:</system:String>
+    <system:String x:Key="BottleStopPassTime">Bottle Stop Pass Time</system:String>
+    <system:String x:Key="BuzzerTime">Buzzer Time</system:String>
+    <system:String x:Key="CacheDecelerateProportion">Cache Decelerate Proportion</system:String>
 </ResourceDictionary>

+ 80 - 0
WpfSwitchLanguage/PlcMessageShowBindingClass.cs

@@ -1240,6 +1240,86 @@ namespace CCDCountWpf
             }
         }
 
+        /// <summary>
+        /// 缺瓶停机开始时间
+        /// </summary>
+        private ushort missBottleRestart;
+        public ushort MissBottleRestart
+        {
+            get { return missBottleRestart; }
+            set
+            {
+                ushort oldValue = missBottleRestart;
+                if (PlcSettingMessageBus.pLCManagement.WriteMissingBottleReStartTime(value))
+                {
+                    missBottleRestart = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"MissBottleRestart:{oldValue}->{value}");
+                }
+                OnPropertyChanged("MissBottleRestart");
+            }
+        }
+
+        /// <summary>
+        /// 拦放瓶时间
+        /// </summary>
+        private ushort bottleStopPassTime;
+        public ushort BottleStopPassTime
+        {
+            get { return bottleStopPassTime; }
+            set
+            {
+                ushort oldValue = bottleStopPassTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteBottleStopPassTime(value))
+                {
+                    bottleStopPassTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"BottleStopPassTime:{oldValue}->{value}");
+                }
+                OnPropertyChanged("BottleStopPassTime");
+            }
+        }
+
+        /// <summary>
+        /// 报警时间
+        /// </summary>
+        private ushort buzzerTime;
+        public ushort BuzzerTime
+        {
+            get { return buzzerTime; }
+            set
+            {
+                ushort oldValue = buzzerTime;
+                if (PlcSettingMessageBus.pLCManagement.WriteBuzzerTime(value))
+                {
+                    buzzerTime = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"BuzzerTime:{oldValue}->{value}");
+                }
+                OnPropertyChanged("BuzzerTime");
+            }
+        }
+
+        /// <summary>
+        /// 报警时间
+        /// </summary>
+        private ushort cacheDecelerateProportion;
+        public ushort CacheDecelerateProportion
+        {
+            get { return cacheDecelerateProportion; }
+            set
+            {
+                ushort oldValue = cacheDecelerateProportion;
+                if (PlcSettingMessageBus.pLCManagement.WriteCacheDecelerateProportion(value))
+                {
+                    cacheDecelerateProportion = value;
+                    if (oldValue != value)
+                        FaultLog.RecordValueChangeMessage($"CacheDecelerateProportion:{oldValue}->{value}");
+                }
+                OnPropertyChanged("CacheDecelerateProportion");
+            }
+        }
+
         //数据绑定核心实现
         public event PropertyChangedEventHandler PropertyChanged;
 

+ 23 - 5
WpfSwitchLanguage/Style/Styles.xaml

@@ -11,19 +11,37 @@
             </Setter.Value>
         </Setter>
     </Style>
-    
+
     <Style x:Key="BtnColor" TargetType="Button">
-        <!--<Setter Property="Background" Value="#FF8E44AD"/>-->
         <Setter Property="Background" Value="#FF95A5A6"/>
-        <!--<Setter Property="Background" Value="#FF27AE60 "/>-->
         <Setter Property="Foreground" Value="White"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Border Background="{TemplateBinding Background}" 
+                        BorderBrush="{TemplateBinding BorderBrush}" 
+                        BorderThickness="{TemplateBinding BorderThickness}">
+                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                    </Border>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
     </Style>
 
     <Style x:Key="BtnColor2" TargetType="Button">
         <Setter Property="Background" Value="#FFF39C12"/>
-        <!--<Setter Property="Background" Value="#FF2980B9"/>-->
-        <!--<Setter Property="Background" Value="#FF27AE60 "/>-->
         <Setter Property="Foreground" Value="White"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Border Background="{TemplateBinding Background}" 
+                        BorderBrush="{TemplateBinding BorderBrush}" 
+                        BorderThickness="{TemplateBinding BorderThickness}">
+                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                    </Border>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
     </Style>
 
     <Style x:Key="MianBackGround" TargetType="Grid">

+ 13 - 0
WpfSwitchLanguage/WpfFrom/LoadingWindow.xaml

@@ -0,0 +1,13 @@
+<Window x:Class="CCDCountWpf.WpfFrom.LoadingWindow"
+        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="LoadingWindow" Height="100" Width="200
+        ">
+    <Grid>
+        <TextBlock Text="Loading..." HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="36"/>
+    </Grid>
+</Window>

+ 32 - 0
WpfSwitchLanguage/WpfFrom/LoadingWindow.xaml.cs

@@ -0,0 +1,32 @@
+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>
+    /// LoadingWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class LoadingWindow : Window
+    {
+        public LoadingWindow()
+        {
+            InitializeComponent();
+            this.WindowStyle = WindowStyle.None;
+            this.AllowsTransparency = true;
+            //this.Background = Brushes.Transparent;
+            // 设置为最顶层窗口
+            this.Topmost = true;
+        }
+    }
+}

+ 7 - 7
WpfSwitchLanguage/WpfFrom/MainWindow.xaml

@@ -25,25 +25,25 @@
                 </StackPanel>
             </Button>
             <StackPanel Grid.Column="1" x:Name="HeardPanel" Orientation="Horizontal">
-                <Button x:Name="MainPageBtn" Width="80" Background="{x:Null}" Click="MainPageBtn_Click">
+                <Button x:Name="MainPageBtn" Width="80" Background="{x:Null}" Click="MainPageBtn_Click" TouchDown="MainPageBtn_TouchDown">
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                         <Image  Source="/FromImage/审计信息审计_白.png" Width="40" Height="40" VerticalAlignment="Top" />
                         <TextBlock Text="{DynamicResource ProductionInterface}" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" TextWrapping="Wrap" />
                     </StackPanel>
                 </Button>
-                <Button x:Name="HistoryDataBtn" Width="80" Background="{x:Null}" Click="HistoryDataBtn_Click">
+                <Button x:Name="HistoryDataBtn" Width="80" Background="{x:Null}" Click="HistoryDataBtn_Click" TouchDown="HistoryDataBtn_TouchDown">
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                         <Image  Source="/FromImage/数据_白.png" Width="40" Height="40" />
                         <TextBlock Text="{DynamicResource HistoricalData}" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" TextWrapping="Wrap" />
                     </StackPanel>
                 </Button>
-                <Button x:Name="SettingBtn" Width="80" Background="{x:Null}" Click="SettingBtn_Click">
+                <Button x:Name="SettingBtn" Width="80" Background="{x:Null}" Click="SettingBtn_Click" TouchDown="SettingBtn_TouchDown">
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                         <Image  Source="/FromImage/相机小_白.png" Width="40" Height="40" />
                         <TextBlock Text="{DynamicResource CameraSettings}" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" TextWrapping="Wrap" />
                     </StackPanel>
                 </Button>
-                <Button x:Name="PlcSettingBtn" Width="80" Background="{x:Null}" Click="PlcSettingBtn_Click">
+                <Button x:Name="PlcSettingBtn" Width="80" Background="{x:Null}" Click="PlcSettingBtn_Click" TouchDown="PlcSettingBtn_TouchDown">
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                         <Image  Source="/FromImage/PLC信息管理_白.png" Width="40" Height="40" />
                         <TextBlock Text="{DynamicResource ParameterSettings}" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" TextWrapping="Wrap" />
@@ -55,19 +55,19 @@
                         <TextBlock Text="{DynamicResource OperationTest}" FontSize="10" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" Foreground="White" Padding="0,5,0,0" TextWrapping="Wrap" />
                     </StackPanel>
                 </Button>-->
-                <Button x:Name="ErrorMessageShowBtn" Width="80" Background="{x:Null}" Click="ErrorMessageShowBtn_Click">
+                <Button x:Name="ErrorMessageShowBtn" Width="80" Background="{x:Null}" Click="ErrorMessageShowBtn_Click" TouchDown="ErrorMessageShowBtn_TouchDown">
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                         <Image  Source="/FromImage/故障_白.png" Width="40" Height="40" />
                         <TextBlock Text="{DynamicResource ErrorPage}" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" />
                     </StackPanel>
                 </Button>
-                <Button x:Name="AuditTrailShowBtn" Width="80" Background="{x:Null}" Click="AuditTrailShowBtn_Click">
+                <Button x:Name="AuditTrailShowBtn" Width="80" Background="{x:Null}" Click="AuditTrailShowBtn_Click" TouchDown="AuditTrailShowBtn_TouchDown">
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                         <Image  Source="/FromImage/审计信息审计_白.png" Width="40" Height="40" />
                         <TextBlock Text="{DynamicResource AuditTrail}" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" Foreground="White" TextWrapping="Wrap" />
                     </StackPanel>
                 </Button>
-                <Button x:Name="UserMessageBtn" Width="80" Background="{x:Null}" Click="UserMessageBtn_Click">
+                <Button x:Name="UserMessageBtn" Width="80" Background="{x:Null}" Click="UserMessageBtn_Click" TouchDown="UserMessageBtn_TouchDown">
                     <StackPanel Orientation="Vertical">
                         <Image  Source="/FromImage/用户管理_白.png" Width="40" Height="40" />
                         <TextBlock Text="{DynamicResource UserManagement}" FontSize="10" FontWeight="Bold" Margin="0,4,0,0" HorizontalAlignment="Center" Foreground="White" TextWrapping="Wrap" />

+ 285 - 121
WpfSwitchLanguage/WpfFrom/MainWindow.xaml.cs

@@ -5,6 +5,7 @@ using CCDCount.MODEL.CameraClass;
 using CCDCount.MODEL.ConfigModel;
 using CCDCount.MODEL.PlcModel;
 using CCDCountWpf.Language;
+using CCDCountWpf.WpfPage;
 using LogClass;
 using MvCameraControl;
 using System;
@@ -16,6 +17,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Windows;
+using System.Windows.Controls;
 using System.Windows.Media.Imaging;
 
 namespace CCDCountWpf
@@ -26,7 +28,7 @@ namespace CCDCountWpf
     public partial class MainWindow : Window
     {
         #region 变量与实例
-        Uri ShowUri = null;
+        //Uri ShowUri = null;
         bool IsShow = false;
         SystemMonitor monitor = new SystemMonitor();
         Stopwatch SystemRunTime = new Stopwatch();
@@ -54,14 +56,15 @@ namespace CCDCountWpf
             SDKSystem.Initialize();
             LOG.log("初始化相机中", 6);
             InitCameraIdentify();
+            LOG.log("初始化PLC参数管理功能", 6);
+            InitPlcManger();
             LOG.log("启动界面更新线程中", 6);
             StartUpdataShowDataThread();
             LOG.log("相机列表显示", 6);
             InitCamComboboxValue();
-            LOG.log("初始化PLC参数管理功能", 6);
-            InitPlcManger();
-            LOG.log("更新数据界面参数展示", 6);
-            UpdatePlcPara();
+
+            //LOG.log("更新数据界面参数展示", 6);
+            //UpdatePlcPara();
         }
 
 
@@ -96,73 +99,99 @@ namespace CCDCountWpf
         /// <param name="e"></param>
         private void MainPageBtn_Click(object sender, RoutedEventArgs e)
         {
-            ShowUri = new Uri("WpfPage\\MainPage.xaml", UriKind.Relative);
-            ShowFrame.Navigate(ShowUri);
+            MainWindowsShowPage("Main");
+            //ShowUri = new Uri("WpfPage\\MainPage.xaml", UriKind.Relative);
+            //ShowFrame.Navigate(ShowUri);
+        }
+        /// <summary>
+        /// 主界面按钮触屏按下事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void MainPageBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
+        {
+            e.Handled = true;
+            MainWindowsShowPage("Main");
         }
 
         private void SettingBtn_Click(object sender, RoutedEventArgs e)
         {
-            ShowUri = new Uri("WpfPage\\SettingPage.xaml", UriKind.Relative);
-            ShowFrame.Navigate(ShowUri);
+            MainWindowsShowPage("Camera");
+            //ShowUri = new Uri("WpfPage\\SettingPage.xaml", UriKind.Relative);
+            //ShowFrame.Navigate(ShowUri);
+        }
+
+        private void SettingBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
+        {
+            e.Handled = true;
+            MainWindowsShowPage("Camera");
         }
 
         private void ErrorMessageShowBtn_Click(object sender, RoutedEventArgs e)
         {
-            ShowUri = new Uri("WpfPage\\MessagePage.xaml", UriKind.Relative);
-            ShowFrame.Navigate(ShowUri);
+            MainWindowsShowPage("Error");
+            //ShowUri = new Uri("WpfPage\\MessagePage.xaml", UriKind.Relative);
+            //ShowFrame.Navigate(ShowUri);
         }
 
-        private void PlcSettingBtn_Click(object sender, RoutedEventArgs e)
+        private void ErrorMessageShowBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs 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状态");
-                    }
-                }
-            }
+            e.Handled = true;
+            MainWindowsShowPage("Error");
         }
 
+        private void PlcSettingBtn_Click(object sender, RoutedEventArgs e)
+        {
+            MainWindowsShowPage("PLC");
+            //if(SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+            //{
+            //    MessageBox.Show("PLC Connecting,Please Wait");
+            //    return;
+            //}
+            //if(PlcSettingMessageBus.pLCManagement!=null && 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 != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            //        {
+            //            ShowUri = new Uri("WpfPage\\PlcSettingPage.xaml", UriKind.Relative);
+            //            ShowFrame.Navigate(ShowUri);
+            //        }
+            //    }
+            //}
+        }
+        private void PlcSettingBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
+        {
+            e.Handled = true;
+            MainWindowsShowPage("PLC");
+        }
         private void HistoryDataBtn_Click(object sender, RoutedEventArgs e)
         {
-            ShowUri = new Uri("WpfPage\\HistoryDataPage.xaml", UriKind.Relative);
-            ShowFrame.Navigate(ShowUri);
+            MainWindowsShowPage("History");
+            //ShowUri = new Uri("WpfPage\\HistoryDataPage.xaml", UriKind.Relative);
+            //ShowFrame.Navigate(ShowUri);
         }
 
+        private void HistoryDataBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
+        {
+            e.Handled = true;
+            MainWindowsShowPage("History");
+        }
         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("请先登录");
-            }
+            MainWindowsShowPage("User");
+        }
+        private void UserMessageBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
+        {
+            e.Handled = true;
+            MainWindowsShowPage("User");
         }
 
         /// <summary>
@@ -174,7 +203,7 @@ namespace CCDCountWpf
         {
             StopSystemRunTime();
 
-            configManager.SaveConfigs();
+            configManager.SaveConfigs(ShowMessageBus.ShowBinding.FormulationName);
             SDKSystem.Finalize();
             if (MessageBus.NowSettingLoadMainThread != null)
             {
@@ -194,37 +223,17 @@ namespace CCDCountWpf
             OnScreenKeyboard.KeyBoardShow();
         }
 
-        private void PlcOperationBtn_Click(object sender, RoutedEventArgs e)
+        private void AuditTrailShowBtn_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状态");
-                    }
-                }
-            }
+            MainWindowsShowPage("Audit");
+            //ShowUri = new Uri("WpfPage\\AuditTrailPage.xaml", UriKind.Relative);
+            //ShowFrame.Navigate(ShowUri);
         }
 
-        private void AuditTrailShowBtn_Click(object sender, RoutedEventArgs e)
+        private void AuditTrailShowBtn_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
         {
-            ShowUri = new Uri("WpfPage\\AuditTrailPage.xaml", UriKind.Relative);
-            ShowFrame.Navigate(ShowUri);
+            e.Handled = true;
+            MainWindowsShowPage("Audit");
         }
 
         private void SwitchLanguageBtn_Click(object sender, RoutedEventArgs e)
@@ -253,9 +262,9 @@ namespace CCDCountWpf
 
             MessageBus.NowSettingLoadMainThread.FormulationName = configManager.SaveConfigModel.ConfigName;
             MessageBus.NowSettingLoadMainThread.IsLoadFormulation = configManager.SaveConfigModel.IsFormulation;
-            MessageBus.NowSettingLoadMainThread.ConnectModbus("127.0.0.1");
             LOG.log("尝试通讯连接", 6);
-            //MessageBus.NowSettingLoadMainThread.ConnectModbus("192.168.0.88");
+            //MessageBus.NowSettingLoadMainThread.ConnectModbus("127.0.0.1");
+            //MessageBus.NowSettingLoadMainThread.ConnectModbus("192.168.1.88");
             LOG.log("加载相机", 6);
             MessageBus.NowSettingLoadMainThread.LoadCamera();
         }
@@ -275,53 +284,61 @@ namespace CCDCountWpf
                 while (IsShow)
                 {
                     renderSW.Restart();
-                    await Task.Run(() =>
-                    {
-                        UpdataShuLiShowData();
-                        UpdateMonitorMessage();
-                        UpdateFaultLogMessage();
-                        UpdateFaultErrorMessage();
-                    });
-                    await Application.Current.Dispatcher.InvokeAsync(() =>
+
+                    try
                     {
-                        if (MessageBus.NowSettingLoadMainThread == null)
+                        await Task.Run(() =>
                         {
-                            LOG.log(string.Format("{0}:当前未加载识别流程", "IdentifyCameraForm-StartShowImageThread"));
-                            Thread.Sleep(100);
-                            return;
-                        }
-                        else
+                            UpdataShuLiShowData();
+                            UpdateMonitorMessage();
+                            UpdateFaultLogMessage();
+                            UpdateFaultErrorMessage();
+                        });
+                        await Application.Current.Dispatcher.InvokeAsync(() =>
                         {
-                            //MessageBus.NowSettingLoadMainThread.GetShowImage(1000, out Bitmap image1);
-                            MessageBus.NowSettingLoadMainThread.GetShowImage(1000, configManager.SaveConfigModel.CameraConfig.Width, out Bitmap image1);
-                            if (image1 == null)
+                            if (MessageBus.NowSettingLoadMainThread == null)
                             {
-                                //LOG.log(string.Format("{0}:相机一获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
+                                LOG.log(string.Format("{0}:当前未加载识别流程", "IdentifyCameraForm-StartShowImageThread"));
+                                Thread.Sleep(100);
                                 return;
                             }
-                            ThumbnailImage1 = ConvertToBitmapImage(image1);
-                            ShowMessageBus.ShowBinding.BitmapImage = ThumbnailImage1;
-                        }
-
-                        if (MessageBus.NowSettingLoadMainThread != null)
-                        {
-                            if (MessageBus.NowSettingLoadMainThread.IsDebug)
+                            else
                             {
-                                Bitmap Splicebitmap = MessageBus.NowSettingLoadMainThread.GetCamImageOnce();
-                                if (Splicebitmap != null)
+                                //MessageBus.NowSettingLoadMainThread.GetShowImage(1000, out Bitmap image1);
+                                MessageBus.NowSettingLoadMainThread.GetShowImage(1000, configManager.SaveConfigModel.CameraConfig.Width, out Bitmap image1);
+                                if (image1 == null)
                                 {
-                                    ShowMessageBus.ShowBinding.DebugImage = ConvertToBitmapImage(Splicebitmap);
+                                    //LOG.log(string.Format("{0}:相机一获取图片为空", "IdentifyCameraForm-StartShowImageThread"));
+                                    return;
                                 }
+                                ThumbnailImage1 = ConvertToBitmapImage(image1);
+                                ShowMessageBus.ShowBinding.BitmapImage = ThumbnailImage1;
                             }
-                            else
+
+                            if (MessageBus.NowSettingLoadMainThread != null)
                             {
-                                if (ThumbnailImage1 != null)
+                                if (MessageBus.NowSettingLoadMainThread.IsDebug)
+                                {
+                                    Bitmap Splicebitmap = MessageBus.NowSettingLoadMainThread.GetCamImageOnce();
+                                    if (Splicebitmap != null)
+                                    {
+                                        ShowMessageBus.ShowBinding.DebugImage = ConvertToBitmapImage(Splicebitmap);
+                                    }
+                                }
+                                else
                                 {
-                                    ShowMessageBus.ShowBinding.DebugImage = ThumbnailImage1;
+                                    if (ThumbnailImage1 != null)
+                                    {
+                                        ShowMessageBus.ShowBinding.DebugImage = ThumbnailImage1;
+                                    }
                                 }
                             }
-                        }
-                    });
+                        });
+                    }
+                    catch (Exception ex)
+                    {
+                        LOG.error("MainWindow-StartUpdataShowDataThread:" + ex.Message);
+                    }
                     //进行精准20帧控制
                     int elapsed = (int)renderSW.ElapsedMilliseconds;
                     //Console.WriteLine(elapsed);
@@ -381,6 +398,7 @@ namespace CCDCountWpf
         /// </summary>
         private void UpdataShuLiShowData()
         {
+            ushort BottingCount = 0;
             if (MessageBus.NowSettingLoadMainThread == null) return;
             if (MessageBus.NowSettingLoadMainThread.ShuLiState)
             {
@@ -405,8 +423,11 @@ namespace CCDCountWpf
             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();
+            if(PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                PlcSettingMessageBus.pLCManagement.ReadBottingCount(out BottingCount);
+                ShowMessageBus.ShowBinding.BottingCountSpeed = PlcSettingMessageBus.pLCManagement.BottingSpeed.ToString();
+            }
             ShowMessageBus.ShowBinding.BottingCount = BottingCount;
         }
 
@@ -595,6 +616,42 @@ namespace CCDCountWpf
                 {
                     SystemAlarm.AlarmCancel(AlarmMessageList.缺瓶停机);
                 }
+
+                if (alarm.PLCCameraHeartErrorSignal)
+                {
+                    SystemAlarm.AlarmAlert(AlarmMessageList.心跳异常,
+                        "Heart Error",
+                        "心跳异常",
+                        "MainWindow-UpdatePlcAlarmMessage");
+                }
+                else
+                {
+                    SystemAlarm.AlarmCancel(AlarmMessageList.心跳异常);
+                }
+
+                if (alarm.CameraNotRunSignal)
+                {
+                    SystemAlarm.AlarmAlert(AlarmMessageList.视觉未启动,
+                        "VisionNotRunSignal",
+                        "视觉未启动",
+                        "MainWindow-UpdatePlcAlarmMessage");
+                }
+                else
+                {
+                    SystemAlarm.AlarmCancel(AlarmMessageList.视觉未启动);
+                }
+
+                if (alarm.ParticleCacheOverflowSignal)
+                {
+                    SystemAlarm.AlarmAlert(AlarmMessageList.颗粒缓存超限,
+                        "ParticleCacheOverflow",
+                        "颗粒缓存超限",
+                        "MainWindow-UpdatePlcAlarmMessage");
+                }
+                else
+                {
+                    SystemAlarm.AlarmCancel(AlarmMessageList.颗粒缓存超限);
+                }
             }
         }
 
@@ -640,10 +697,29 @@ namespace CCDCountWpf
         /// <summary>
         /// 初始化PLC管理(包括PLC的数据信息更新线程)
         /// </summary>
-        public void InitPlcManger()
+        public async void InitPlcManger()
         {
-            PlcSettingMessageBus.pLCManagement = new PLCManagementClass("127.0.0.1");
-            //PlcSettingMessageBus.pLCManagement = new PLCManagementClass("192.168.0.88");
+            await Task.Run(() => {
+                //string ipAddress = "192.168.1.88";
+                string ipAddress = "127.0.0.1";
+                SystemAlarm.AlarmAlert(AlarmMessageList.PLC连接中,
+                    $"PLC Connecting, target IP:{ipAddress}",
+                    $"PLC连接中, IP地址:{ipAddress}",
+                    "DLL:MainThreadClass-InitPlcManger");
+                PlcSettingMessageBus.pLCManagement = new PLCManagementClass(ipAddress);
+                SystemAlarm.AlarmCancel(AlarmMessageList.PLC连接中);
+                UpdatePlcPara();
+                UpdateCameraState();
+            });
+            
+        }
+
+        public void UpdateCameraState()
+        {
+            if(PlcSettingMessageBus.pLCManagement!=null&&PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                PlcSettingMessageBus.pLCManagement.WriteCameraRunState(0);
+            }
         }
 
         private void UpdatePlcPara()
@@ -756,6 +832,14 @@ namespace CCDCountWpf
                 ParaValue.EliminateCylinderHoldingTime;
             PlcSettingMessageBus.PlcMessageShowBindage.MaterialShortageStoppageDelayTime =
                 ParaValue.MaterialShortageStoppageDelayTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart =
+                ParaValue.MissBottleReSestart;
+            PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime =
+                ParaValue.BottleStopPassTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime =
+                ParaValue.BuzzerTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion =
+                ParaValue.CacheDecelerateProportion;
         }
 
         private void StartSystemRunTime()
@@ -808,6 +892,86 @@ namespace CCDCountWpf
             this.Width = SystemParameters.PrimaryScreenWidth;
             this.Height = SystemParameters.PrimaryScreenHeight;
         }
+
+        private void MainWindowsShowPage(string PageName)
+        {
+                Page pageToNavigate = null;
+
+                switch (PageName)
+                {
+                    case "Main":
+                        pageToNavigate = new MainPage(); // 替换为你实际的页面类名
+                        break;
+                    case "History":
+                        pageToNavigate = new HistoryDataPage();
+                        break;
+                    case "Camera":
+                        pageToNavigate = new SettingPage();
+                        break;
+                    case "PLC":
+                        if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+                        {
+                            MessageBox.Show("PLC Connecting,Please Wait");
+                            return;
+                        }
+                        if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+                        {
+
+                            pageToNavigate = new PlcSettingPage();
+                            //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 != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+                                {
+                                    pageToNavigate = new PlcSettingPage();
+                                    //ShowUri = new Uri("WpfPage\\PlcSettingPage.xaml", UriKind.Relative);
+                                    //ShowFrame.Navigate(ShowUri);
+                                }
+                            }
+                        }
+                        break;
+                    case "Error":
+                        pageToNavigate = new MessagePage();
+                        break;
+                    case "Audit":
+                        pageToNavigate = new AuditTrailPage();
+                        break;
+                    case "User":
+                        if (MessageBus.NowLoginUserMessage != null)
+                        {
+                            if (!MessageBus.NowLoginUserMessage.IsAdmin)
+                            {
+                                MessageBox.Show("权限不足");
+                            }
+                            else
+                            {
+                                pageToNavigate = new UserManagementPage();
+                                //ShowUri = new Uri("WpfPage\\UserManagementPage.xaml", UriKind.Relative);
+                                //ShowFrame.Navigate(ShowUri);
+                            }
+                        }
+                        else
+                        {
+                            MessageBox.Show("请先登录");
+                        }
+                        break;
+                }
+
+                if (pageToNavigate != null)
+                {
+                    // 确保在主线程执行导航
+                    Dispatcher.Invoke(() =>
+                    {
+                        ShowFrame.Navigate(pageToNavigate);
+                    });
+                }
+        }
         #endregion
     }
 }

+ 1 - 0
WpfSwitchLanguage/WpfFrom/StartWindow.xaml

@@ -13,6 +13,7 @@
         <Image Source="/FromImage/ScreenShot_2026-03-10_083012_432.png" Margin="0,120,0,120"/>
         <Label Content="{DynamicResource SoftWareTitle}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,30,0,0" FontSize="48" Foreground="#FF0072BF"/>
         <Button x:Name="SystemExit" Style="{StaticResource BtnColor}" Content="{DynamicResource SystemExit}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="150" Height="80" Margin="30,0,0,20" FontSize="20" Click="SystemExit_Click" />
+        <Button x:Name="SwitchLanguage" Style="{StaticResource BtnColor}" Content="{DynamicResource SwitchLanguageText}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="150" Height="80" Margin="200,0,0,20" FontSize="20" Click="SwitchLanguage_Click"/>
         <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
             <Button x:Name="LoginInBtd" Content="{DynamicResource UserLogin}" Style="{StaticResource BtnColor}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="150" Height="80" Margin="0,0,30,20" Loaded="LoginInBtd_Loaded" Click="LoginInBtd_Click" FontSize="20"></Button>
             <Button x:Name="EnterSystemBtn" Content="{DynamicResource EnterSystem}" Style="{StaticResource BtnColor}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="150" Height="80" Margin="0,0,30,20" Click="EnterSystemBtn_Click" FontSize="20"></Button>

+ 35 - 5
WpfSwitchLanguage/WpfFrom/StartWindow.xaml.cs

@@ -1,4 +1,6 @@
-using System;
+using CCDCountWpf.Language;
+using CCDCountWpf.WpfFrom;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -73,6 +75,12 @@ namespace CCDCountWpf
         private void LoginInBtd_Click(object sender, RoutedEventArgs e)
         {
             UserLoginWindow userLoginWindow = new UserLoginWindow();
+            // 设置窗口启动位置为手动
+            userLoginWindow.WindowStartupLocation = WindowStartupLocation.Manual;
+            // 水平居中
+            userLoginWindow.Left = (SystemParameters.PrimaryScreenWidth - userLoginWindow.Width) / 2;
+            // 垂直靠上(例如屏幕高度的 10% 位置)
+            userLoginWindow.Top = SystemParameters.PrimaryScreenHeight * 0.1;
             userLoginWindow.ShowDialog();
             if (MessageBus.NowLoginUserMessage == null)
             {
@@ -86,11 +94,26 @@ namespace CCDCountWpf
             }
         }
 
-        private void EnterSystemBtn_Click(object sender, RoutedEventArgs e)
+        private async void EnterSystemBtn_Click(object sender, RoutedEventArgs e)
         {
-            MainWindow mainWindow = new MainWindow();
-            this.Close();
-            mainWindow.Show();
+            var loadwin = new LoadingWindow { Owner = this };
+            loadwin.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+            loadwin.Show();
+            try
+            {
+                await Dispatcher.InvokeAsync(() =>
+                {
+                    MainWindow mainWindow = new MainWindow();
+                    mainWindow.Show();
+                    this.Close();
+                });
+            }
+            finally
+            {
+                await Dispatcher.InvokeAsync(() => {
+                    loadwin.Close();
+                });
+            }
         }
 
         private void SystemExit_Click(object sender, RoutedEventArgs e)
@@ -102,11 +125,18 @@ namespace CCDCountWpf
                 _timer = null;
             }
             this.Close();
+            Environment.Exit(0);
         }
 
         private void Timer_Tick(object sender,EventArgs e)
         {
             ShowMessageBus.ShowBinding.ShowTimer = DateTime.Now.ToString("HH:mm:ss");
         }
+
+        private void SwitchLanguage_Click(object sender, RoutedEventArgs e)
+        {
+            MessageBus.LanguageIndex++;
+            LanguageManager.ChangeLanguage(LanguageManager.LanguageList[MessageBus.LanguageIndex % LanguageManager.LanguageList.Count]);
+        }
     }
 }

+ 1 - 1
WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml

@@ -5,7 +5,7 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:CCDCountWpf"
         mc:Ignorable="d"
-        Title="UserLoginWindow" Height="340" Width="450"
+        Title="UserLoginWindow" Height="330" Width="450"
         WindowStartupLocation="CenterScreen" Icon="/FromImage/mmexport1752891278116.jpg" KeyDown="Window_KeyDown">
     <!--WindowStyle="None" AllowsTransparency="True"-->
     <Grid Background="#FF2C3E50">

+ 9 - 6
WpfSwitchLanguage/WpfFrom/UserLoginWindow.xaml.cs

@@ -25,8 +25,12 @@ namespace CCDCountWpf
         public UserLoginWindow()
         {
             InitializeComponent();
-            AutoStartHelper.SetAutoStart(true);
-            //SetupFullScreen();
+            //AutoStartHelper.SetAutoStart(true);
+            AutoStartHelper.RegisterTask();
+            // 隐藏标题栏和边框
+            //this.WindowStyle = WindowStyle.None;
+            // 禁止调整大小
+            this.ResizeMode = ResizeMode.NoResize;
         }
 
         private void UserLoginBtn_Click(object sender, RoutedEventArgs e)
@@ -45,7 +49,7 @@ namespace CCDCountWpf
         private void UserCancelBtn_Click(object sender, RoutedEventArgs e)
         {
             this.Close();
-            Environment.Exit(0);
+            OnScreenKeyboard.KeyBoardHide();
         }
 
         private void Window_KeyDown(object sender, KeyEventArgs e)
@@ -60,12 +64,12 @@ namespace CCDCountWpf
 
         private void UserNameTbx_GotFocus(object sender, RoutedEventArgs e)
         {
-            //OnScreenKeyboard.Show();
+            OnScreenKeyboard.KeyBoardShow();
         }
 
         private void UserPassTbx_GotFocus(object sender, RoutedEventArgs e)
         {
-            //OnScreenKeyboard.Show();
+            OnScreenKeyboard.KeyBoardShow();
         }
 
         private void KeyBoardBtn_Click(object sender, RoutedEventArgs e)
@@ -78,6 +82,5 @@ namespace CCDCountWpf
             MessageBus.LanguageIndex++;
             LanguageManager.ChangeLanguage(LanguageManager.LanguageList[MessageBus.LanguageIndex % LanguageManager.LanguageList.Count]);
         }
-
     }
 }

+ 20 - 2
WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml

@@ -26,9 +26,27 @@
             <TextBlock Text="{DynamicResource BatchSelection}" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="1" TextAlignment="Center" Margin="0,0,200,0" Width="110"/>
             <ComboBox 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" SelectionChanged="BatchNumRecordComBox_SelectionChanged" Grid.Column="1" Margin="0,0,15,0"/>
         </Grid>
-        <Border Grid.Row="1" BorderBrush="Black" BorderThickness="1" Margin="2,2,2,2">
+        <Grid Grid.Row="1" Margin="2,2,2,2">
             <Image x:Name="ShowBox" Source="{Binding HistoryImage}" Margin="0,0,0,0"/>
-        </Border>
+            <Button x:Name="PreviousErrorBtn" Content="{DynamicResource PreviousErrorOne}" Height="40" Width="100" Margin="0,0,30,60" Padding="1,1,1,1" VerticalAlignment="Bottom" BorderThickness="1" Background="#FF0123FF" Foreground="White" Cursor="Hand" HorizontalAlignment="Right" Click="PreviousErrorBtn_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="NextErrorBtn" Content="{DynamicResource NextErrorOne}" Height="40" Width="100" Margin="0,0,30,10" Padding="1,1,1,1" VerticalAlignment="Bottom" BorderThickness="1" Background="#FF0123FF" Foreground="White" Cursor="" HorizontalAlignment="Right" Click="NextErrorBtn_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>
+        </Grid>
         <Border x:Name="PageChangeBorder" Grid.Row="2" Margin="2,2,2,2" VerticalAlignment="Center" HorizontalAlignment="Center" Background="#FF0087FF" 
                     CornerRadius="8"
                     BorderBrush="Gray"

+ 81 - 7
WpfSwitchLanguage/WpfPage/HistoryDataPage.xaml.cs

@@ -30,6 +30,9 @@ namespace CCDCountWpf.WpfPage
     public partial class HistoryDataPage : Page
     {
         private static ActionMesSqliteDataClass actionMesSqliteDataClass = null;
+        List<ActiveObjectClass> ErrorActive = null;
+        List<ActiveObjectClass> NowPageError = null;
+        int NowErrorNum = 0;
         int DataStartLine = 0;
         private int PageHeight = 2000;
         public HistoryDataPage()
@@ -37,7 +40,7 @@ namespace CCDCountWpf.WpfPage
             InitializeComponent();
             DataContext = ShowMessageBus.ShowBinding;
             InitBatchItems();
-            //UpDateShowBinding();
+            UpDateShowBinding();
         }
 
         private void PreviousBtn_Click(object sender, RoutedEventArgs e)
@@ -98,6 +101,21 @@ namespace CCDCountWpf.WpfPage
                         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));
 
+                        if(item.StateCode!=0)
+                        {
+                            string ErrorMessage = "";
+                            if (item.StateCode == 1)
+                                ErrorMessage = "LONG";
+                            else if (item.StateCode == 2)
+                                ErrorMessage = "SHORT";
+                            else if (item.StateCode == 5)
+                                ErrorMessage = "BIG";
+                            else if (item.StateCode == 6)
+                                ErrorMessage = "SMALL";
+                            g.DrawString(ErrorMessage, font, System.Drawing.Brushes.Black, new System.Drawing.Point(roix - 20 * item.Num.ToString().Length, roiy - 50));
+                        }
+
+                        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);
@@ -121,6 +139,7 @@ namespace CCDCountWpf.WpfPage
             });
             stopwatch.Stop();
             Console.WriteLine($"{stopwatch.ElapsedMilliseconds}ms");
+            NowPageError = ShowResult.Where(o => o.StateCode != 0).OrderBy(o => o.Num).ToList();
         }
 
         // Bitmap 转 BitmapImage 的辅助方法
@@ -179,7 +198,7 @@ namespace CCDCountWpf.WpfPage
         /// </summary>
         private void InitBatchItems(DateTime Mintime, DateTime MaxTime)
         {
-            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\ActiveObjectData\\Cam{MessageBus.NowSettingLoadMainThread.cameraConfig.CamerNo}";
             if (!Directory.Exists(folderPath))
             {
                 // 创建文件夹
@@ -189,7 +208,7 @@ namespace CCDCountWpf.WpfPage
             {
                 // 使用 DirectoryInfo 获取文件并按修改时间排序
                 DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
-                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+                FileInfo[] files = dirInfo.GetFiles("*.db", SearchOption.AllDirectories);
 
                 // 按照修改时间排序(最新的在前)
                 var sortedFiles = files.Where(f => f.CreationTime > Mintime && f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
@@ -209,7 +228,7 @@ namespace CCDCountWpf.WpfPage
         /// </summary>
         private void InitBatchItemsByMinTime(DateTime Mintime)
         {
-            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\ActiveObjectData\\Cam{MessageBus.NowSettingLoadMainThread.cameraConfig.CamerNo}";
             if (!Directory.Exists(folderPath))
             {
                 // 创建文件夹
@@ -219,7 +238,7 @@ namespace CCDCountWpf.WpfPage
             {
                 // 使用 DirectoryInfo 获取文件并按修改时间排序
                 DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
-                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+                FileInfo[] files = dirInfo.GetFiles("*.db", SearchOption.AllDirectories);
 
                 // 按照修改时间排序(最新的在前)
                 var sortedFiles = files.Where(f => f.CreationTime > Mintime).OrderByDescending(f => f.LastWriteTime).ToArray();
@@ -239,7 +258,7 @@ namespace CCDCountWpf.WpfPage
         /// </summary>
         private void InitBatchItemsByMaxTime(DateTime MaxTime)
         {
-            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\BatchData";
+            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}DATA\\ActiveObjectData\\Cam{MessageBus.NowSettingLoadMainThread.cameraConfig.CamerNo}";
             if (!Directory.Exists(folderPath))
             {
                 // 创建文件夹
@@ -249,7 +268,7 @@ namespace CCDCountWpf.WpfPage
             {
                 // 使用 DirectoryInfo 获取文件并按修改时间排序
                 DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
-                FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
+                FileInfo[] files = dirInfo.GetFiles("*.db", SearchOption.AllDirectories);
 
                 // 按照修改时间排序(最新的在前)
                 var sortedFiles = files.Where(f => f.CreationTime < MaxTime.AddDays(1)).OrderByDescending(f => f.LastWriteTime).ToArray();
@@ -314,6 +333,7 @@ namespace CCDCountWpf.WpfPage
                 DataStartLine = StartLine;
                 ShowMessageBus.ShowBinding.HistoryImageNum = 1;
                 UpDateShowBinding();
+                ErrorActive = actionMesSqliteDataClass.GetAllErrorAction().OrderBy(o=>o.Num).ToList();
             }
         }
 
@@ -322,5 +342,59 @@ namespace CCDCountWpf.WpfPage
             BatchNumRecordMinTime.SelectedDate = DateTime.Today;
             BatchNumRecordMaxTime.SelectedDate = DateTime.Today;
         }
+
+        private void PreviousErrorBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (ErrorActive != null)
+            {
+                if(NowErrorNum-1<0)
+                {
+                    MessageBox.Show("已经是第一粒");
+                }
+                else
+                {
+                    if(NowPageError.Count>0)
+                    {
+                        int LastErrNum = NowPageError.Where(o => o.StateCode != 0).OrderBy(o => o.Num).First().Num;
+                        NowErrorNum = ErrorActive.FindIndex(o => o.Num == LastErrNum);
+                        if(NowErrorNum-1>=0) NowErrorNum--;
+                        ShowMessageBus.ShowBinding.HistoryImageNum = ((int)(ErrorActive[NowErrorNum].StartLine - DataStartLine) / PageHeight) + 1;
+                    }
+                    else
+                    {
+                        ShowMessageBus.ShowBinding.HistoryImageNum = ((int)(ErrorActive[NowErrorNum].StartLine - DataStartLine) / PageHeight) + 1;
+                        if (NowErrorNum - 1 >= 0) NowErrorNum--;
+                    } 
+                    UpDateShowBinding();
+                }
+            }
+        }
+
+        private void NextErrorBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if (ErrorActive != null)
+            {
+                if (NowErrorNum+1 >= ErrorActive.Count)
+                {
+                    MessageBox.Show("已经是最后一粒");
+                }
+                else
+                {
+                    if (NowPageError.Count > 0)
+                    {
+                        int LastErrNum = NowPageError.Where(o => o.StateCode != 0).OrderBy(o => o.Num).Last().Num;
+                        NowErrorNum = ErrorActive.FindIndex(o => o.Num == LastErrNum);
+                        if (NowErrorNum + 1 <= ErrorActive.Count - 1) NowErrorNum++;
+                        ShowMessageBus.ShowBinding.HistoryImageNum = ((int)(ErrorActive[NowErrorNum].StartLine - DataStartLine) / PageHeight) + 1;
+                    }
+                    else
+                    {
+                        ShowMessageBus.ShowBinding.HistoryImageNum = ((int)(ErrorActive[NowErrorNum].StartLine - DataStartLine) / PageHeight) + 1;
+                        if (NowErrorNum + 1 <= ErrorActive.Count - 1) NowErrorNum++;
+                    }
+                    UpDateShowBinding();
+                }
+            }
+        }
     }
 }

+ 2 - 2
WpfSwitchLanguage/WpfPage/MainPage.xaml

@@ -350,7 +350,7 @@
                     <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
                         <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                             <TextBlock Text="{DynamicResource CurrentFormula}" FontWeight="Bold" FontSize="20" Margin="10,0,0,0" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" Width="170" TextAlignment="Center"/>
-                            <TextBox x:Name="FormulationName" Text="{Binding FormulationName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="160" Height="40"  Foreground="White" Background="{x:Null}" KeyDown="TextBox_KeyDown" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                            <TextBox x:Name="FormulationName" Text="{Binding FormulationName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" Width="160" Height="40"  Foreground="White" Background="{x:Null}" KeyDown="TextBox_KeyDown" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" GotFocus="FormulationName_GotFocus"/>
                             <Button x:Name="SaveFormulationBtn" Content="{DynamicResource SaveFormula}" BorderThickness="1" HorizontalAlignment="Center" Margin="20,0,0,0" VerticalAlignment="Center" Width="140" Height="50" Style="{StaticResource BtnColor}" FontWeight="Bold" FontSize="20" Cursor="Hand" Click="SaveFormulationBtn_Click">
                                 <Button.Template>
                                     <ControlTemplate TargetType="Button">
@@ -457,7 +457,7 @@
                 <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
                     <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                         <TextBlock Text="{DynamicResource ProductionBatch}" FontSize="20" Margin="0,0,20,0" VerticalAlignment="Center" Foreground="White" Width="170" TextAlignment="Center"/>
-                        <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"/>
+                        <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" GotFocus="BatchNumberTbx_GotFocus"/>
                     </StackPanel>
                     <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
                         <Button x:Name="StartIdentifyBtn" Content="{DynamicResource Start}" BorderThickness="1" HorizontalAlignment="Right" Margin="0,0,20,0" VerticalAlignment="Top" Width="100" Height="60" Style="{StaticResource BtnColor}" FontWeight="Bold" FontSize="20" Cursor="Hand" Click="StartIdentifyBtn_Click">

+ 197 - 54
WpfSwitchLanguage/WpfPage/MainPage.xaml.cs

@@ -1,6 +1,8 @@
 
 using CCDCount.DLL;
+using CCDCount.DLL.AlarmTools;
 using CCDCount.DLL.SqlDataClass;
+using CCDCount.DLL.Tools;
 using CCDCount.MODEL.AuditTrailModel;
 using CCDCount.MODEL.ConfigModel;
 using CCDCountWpf.Language;
@@ -209,165 +211,296 @@ namespace CCDCountWpf.WpfPage
             if (PlcSettingMessageBus.pLCManagement.IsConnect)
             {
                 PlcSettingMessageBus.pLCManagement.MachineRunToTrue();
+                PlcSettingMessageBus.pLCManagement.WriteCameraRunState(1);
             }
         }
 
         private void StopIdentifyBtn_Click(object sender, RoutedEventArgs e)
         {
             StopCameraIdentify();
-            LOG.log("停止相机成功");
-            //StopBatchRecord();
+            LOG.log("停止相机成功",6);
+            StopBatchRecord();
             StartIdentifyBtn.IsEnabled = true;
             StartIdentifyBtn.Opacity = 1;
             StopIdentifyBtn.IsEnabled = false;
             StopIdentifyBtn.Opacity = 0.5;
-            //if (PlcSettingMessageBus.pLCManagement.IsConnect)
-            //{
-            //    PlcSettingMessageBus.pLCManagement.MachineStopToTrue();
-            //}
+            if (PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                PlcSettingMessageBus.pLCManagement.MachineStopToTrue();
+                PlcSettingMessageBus.pLCManagement.WriteCameraRunState(0);
+            }
         }
 
         private void BottingMaterialCylinderVibrationTableHighSpeedValueUpUpBtn_Click(object sender, RoutedEventArgs e)
         {
-            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed + 10) >
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+            {
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed += 10;
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed += 1;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed -= 1;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1H_FillingSpeed -= 10;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+            {
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed += 10;
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+            {
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed += 1;
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+            {
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed -= 1;
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable2H_FillingSpeed -= 10;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed += 10;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
+            {
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed += 1;
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed -= 1;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable3H_FillingSpeed -= 10;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet += 5;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet += 1;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet -= 1;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                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)
+            if (SystemAlarm.CheckAlarmStatic(AlarmMessageList.PLC连接中))
             {
-                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet -= 5;
+                MessageBox.Show("PLC Connecting,Please Wait");
+                return;
+            }
+            if (PlcSettingMessageBus.pLCManagement != null && PlcSettingMessageBus.pLCManagement.IsConnect)
+            {
+                if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet - 5) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet)
+                {
+                    PlcSettingMessageBus.PlcMessageShowBindage.BottValueSet -= 5;
+                }
             }
         }
 
@@ -577,5 +710,15 @@ namespace CCDCountWpf.WpfPage
                 MessageColumn.Binding = new Binding("AlarmEnMess");
             }
         }
+
+        private void BatchNumberTbx_GotFocus(object sender, RoutedEventArgs e)
+        {
+            OnScreenKeyboard.KeyBoardShow();
+        }
+
+        private void FormulationName_GotFocus(object sender, RoutedEventArgs e)
+        {
+            OnScreenKeyboard.KeyBoardShow();
+        }
     }
 }

+ 155 - 111
WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml

@@ -29,7 +29,7 @@
                 <RowDefinition Height="*"/>
             </Grid.RowDefinitions>
             <Grid Grid.Row="0">
-                <Button Grid.Column="1" x:Name="ReloadBtn" Height="60" Width="100" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,20,0" Click="ReloadBtn_Click"  Style="{StaticResource BtnColor}">
+                <Button Grid.Column="1" x:Name="ReloadBtn" Height="60" Width="100" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,20,0" Style="{StaticResource BtnColor}" Click="ReloadBtn_Click">
                     <TextBlock Text="{DynamicResource RefreshParameters}" TextWrapping="Wrap" TextAlignment="Center"/>
                 </Button>
                 <Button Grid.Column="1" x:Name="DataResetBtn" HorizontalAlignment="Right" Height="60" Width="100" PreviewMouseLeftButtonDown="DataResetBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="DataResetBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Margin="0,10,140,0"  Style="{StaticResource BtnColor}">
@@ -79,118 +79,124 @@
             </GroupBox>
             <GroupBox Grid.Row="1" x:Name="ServoAdjustmentGrid" Header="{DynamicResource ServoAdjustment}" BorderThickness="1,1,1,1" Margin="5,155,5,0" FontSize="18" BorderBrush="#FF433B98" Foreground="White" Visibility="Collapsed">
                 <Grid>
-                    <Label x:Name="ScrewAdjustmentTitleLab" FontSize="16" VerticalAlignment="Top" HorizontalAlignment="Left" Content="{DynamicResource ScrewAdjustment}" Margin="10,2,0,0" Foreground="White"/>
-                    <Button x:Name="ScrewJogFwdBtn" HorizontalAlignment="Left" Margin="30,30,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="ScrewJogFwdBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ScrewJogFwdBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource ScrewJogFwd}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
-                    </Button>
-                    <Button x:Name="ScrewJogRevBtn" HorizontalAlignment="Left" Margin="190,30,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="ScrewJogRevBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ScrewJogRevBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource ScrewJogRev}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
-                    </Button>
-                    <Button x:Name="ScrewHomeBtn" HorizontalAlignment="Left" Margin="30,85,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="ScrewHomeBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top"  Style="{StaticResource BtnColor}" PreviewMouseLeftButtonUp="ScrewHomeBtn_PreviewMouseLeftButtonUp">
-                        <TextBlock Text="{DynamicResource ScrewSetHome}" FontSize="17"/>
-                    </Button>
-                    <Button x:Name="PassABottleBtn" HorizontalAlignment="Left" Margin="190,85,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="PassABottleBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top"  Style="{StaticResource BtnColor}" PreviewMouseLeftButtonUp="PassABottleBtn_PreviewMouseLeftButtonUp">
-                        <TextBlock Text="{DynamicResource PassABottle}" FontSize="17"/>
-                    </Button>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,25,510,0">
-                        <TextBlock Text="{DynamicResource BottlePosSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="BottlePosSpeedUpUpBtn" Content="++" Width="50" Click="BottlePosSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
-                        <Button x:Name="BottlePosSpeedUpBtn" Content="+" Width="50" Click="BottlePosSpeedUpBtn_Click" Style="{StaticResource BtnColor}"/>
-                        <TextBox Text="{Binding BottlePosSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="BottlePosSpeedDownBtn" Content="-" Width="50" Click="BottlePosSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
-                        <Button x:Name="BottlePosSpeedDownDownBtn" Content="--" Width="50" Click="BottlePosSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}"/>
-                    </StackPanel>
-                    <StackPanel Height="50" Orientation="Horizontal" Margin="0,25,30,0" HorizontalAlignment="Right" VerticalAlignment="Top">
-                        <TextBlock Text="{DynamicResource BottlePosPosition}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="BottlePosPositionUpUpBtn" Content="++" Width="50" Click="BottlePosPositionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="BottlePosPositionUpBtn" Content="+" Width="50" Click="BottlePosPositionUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding BottlePosPosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="BottlePosPositionDownBtn" Content="-" Width="50" Click="BottlePosPositionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
-                        <Button x:Name="BottlePosPositionDownDownBtn" Content="--" Width="50" Click="BottlePosPositionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,85,30,0">
-                        <TextBlock Text="{DynamicResource ScrewJogSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="ScrewJogSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="ScrewJogSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="ScrewJogSpeedUpBtn" Content="+" Width="50" Height="50" Click="ScrewJogSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding ScrewJogSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="ScrewJogSpeedDownBtn" Content="-" Width="50" Click="ScrewJogSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="ScrewJogSpeedDownDownBtn" Content="--" Width="50" Click="ScrewJogSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <Rectangle Height="1" Fill="LightGray" Margin="5,143,5,0" VerticalAlignment="Top"/>
+                    <Grid VerticalAlignment="Top" Visibility="Collapsed">
+                        <Label x:Name="ScrewAdjustmentTitleLab" FontSize="16" VerticalAlignment="Top" HorizontalAlignment="Left" Content="{DynamicResource ScrewAdjustment}" Margin="10,2,0,0" Foreground="White"/>
+                        <Button x:Name="ScrewJogFwdBtn" HorizontalAlignment="Left" Margin="30,30,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="ScrewJogFwdBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ScrewJogFwdBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource ScrewJogFwd}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
+                        </Button>
+                        <Button x:Name="ScrewJogRevBtn" HorizontalAlignment="Left" Margin="190,30,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="ScrewJogRevBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="ScrewJogRevBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource ScrewJogRev}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
+                        </Button>
+                        <Button x:Name="ScrewHomeBtn" HorizontalAlignment="Left" Margin="30,85,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="ScrewHomeBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top"  Style="{StaticResource BtnColor}" PreviewMouseLeftButtonUp="ScrewHomeBtn_PreviewMouseLeftButtonUp">
+                            <TextBlock Text="{DynamicResource ScrewSetHome}" FontSize="17"/>
+                        </Button>
+                        <Button x:Name="PassABottleBtn" HorizontalAlignment="Left" Margin="190,85,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="PassABottleBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top"  Style="{StaticResource BtnColor}" PreviewMouseLeftButtonUp="PassABottleBtn_PreviewMouseLeftButtonUp">
+                            <TextBlock Text="{DynamicResource PassABottle}" FontSize="17"/>
+                        </Button>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,25,510,0">
+                            <TextBlock Text="{DynamicResource BottlePosSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="BottlePosSpeedUpUpBtn" Content="++" Width="50" Click="BottlePosSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
+                            <Button x:Name="BottlePosSpeedUpBtn" Content="+" Width="50" Click="BottlePosSpeedUpBtn_Click" Style="{StaticResource BtnColor}"/>
+                            <TextBox Text="{Binding BottlePosSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="BottlePosSpeedDownBtn" Content="-" Width="50" Click="BottlePosSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
+                            <Button x:Name="BottlePosSpeedDownDownBtn" Content="--" Width="50" Click="BottlePosSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}"/>
+                        </StackPanel>
+                        <StackPanel Height="50" Orientation="Horizontal" Margin="0,25,30,0" HorizontalAlignment="Right" VerticalAlignment="Top">
+                            <TextBlock Text="{DynamicResource BottlePosPosition}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="BottlePosPositionUpUpBtn" Content="++" Width="50" Click="BottlePosPositionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BottlePosPositionUpBtn" Content="+" Width="50" Click="BottlePosPositionUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding BottlePosPosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="BottlePosPositionDownBtn" Content="-" Width="50" Click="BottlePosPositionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
+                            <Button x:Name="BottlePosPositionDownDownBtn" Content="--" Width="50" Click="BottlePosPositionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,85,30,0">
+                            <TextBlock Text="{DynamicResource ScrewJogSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="ScrewJogSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="ScrewJogSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="ScrewJogSpeedUpBtn" Content="+" Width="50" Height="50" Click="ScrewJogSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding ScrewJogSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="ScrewJogSpeedDownBtn" Content="-" Width="50" Click="ScrewJogSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="ScrewJogSpeedDownDownBtn" Content="--" Width="50" Click="ScrewJogSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                    </Grid>
+                    <Rectangle Height="1" Fill="LightGray" Margin="5,143,5,0" VerticalAlignment="Top" Visibility="Collapsed"/>
 
-                    <Label x:Name="FillingValveTitleLab" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="16" Content="{DynamicResource FillingValveAdjustment}" Margin="10,146,0,0" Foreground="White"/>
-                    <Button x:Name="FillingValveManualOpenBtn" HorizontalAlignment="Left" Margin="30,178,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveManualOpenBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveManualOpenBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}" FontSize="17">
-                        <TextBlock Text="{DynamicResource FillingValveManualOpen}" TextWrapping="Wrap" TextAlignment="Center"/>
-                    </Button>
-                    <Button x:Name="FillingValveManualCloseBtn" HorizontalAlignment="Left" Margin="190,178,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveManualCloseBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveManualCloseBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource FillingValveManualClose}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
-                    </Button>
-                    <Button x:Name="FillingValveJogFwdBtn" HorizontalAlignment="Left" Margin="30,233,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveJogFwdBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveJogFwdBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource FillingValveJogFw}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
-                    </Button>
-                    <Button x:Name="FillingValveJogRevBtn" HorizontalAlignment="Left" Margin="190,233,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveJogRevBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveJogRevBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource FillingValveJogRev}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
-                    </Button>
-                    <Button x:Name="FillingValveHomeBtn" HorizontalAlignment="Left" Margin="30,288,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveHomeBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top" Style="{StaticResource BtnColor}" PreviewMouseLeftButtonUp="FillingValveHomeBtn_PreviewMouseLeftButtonUp">
-                        <TextBlock Text="{DynamicResource FillingValveSetHome}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
-                    </Button>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,175,30,0">
-                        <TextBlock Text="{DynamicResource FillingValveOpenPosition}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="FillingValveOpenPositionUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveOpenPositionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValveOpenPositionUpBtn" Content="+" Width="50" Height="50" Click="FillingValveOpenPositionUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding FillingValveOpenPosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="FillingValveOpenPositionDownBtn" Content="-" Width="50" Click="FillingValveOpenPositionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValveOpenPositionDownDownBtn" Content="--" Width="50" Click="FillingValveOpenPositionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,175,510,0" VerticalAlignment="Top">
-                        <TextBlock Text="{DynamicResource FillingValveOpenSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="FillingValveOpenSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveOpenSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
-                        <Button x:Name="FillingValveOpenSpeedUpBtn" Content="+" Width="50" Height="50" Click="FillingValveOpenSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding FillingValveOpenSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="FillingValveOpenSpeedDownBtn" Content="-" Width="50" Click="FillingValveOpenSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValveOpenSpeedDownDownBtn" Content="--" Width="50" Click="FillingValveOpenSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,235,510,0">
-                        <TextBlock Text="{DynamicResource FillingValveCloseSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="FillingValveCloseSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveCloseSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValveCloseSpeedUpBtn" Content="+" Width="50" Height="50" Click="FillingValveCloseSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding FillingValveCloseSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="FillingValveCloseSpeedDownBtn" Content="-" Width="50" Click="FillingValveCloseSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
-                        <Button x:Name="FillingValveCloseSpeedDownDownBtn" Content="--" Width="50" Click="FillingValveCloseSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,235,30,0" VerticalAlignment="Top">
-                        <TextBlock Text="{DynamicResource FillingValveClosePosition}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="FillingValveClosePositionUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveClosePositionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValveClosePositionUpBtn" Content="+" Width="50" Height="50" Click="FillingValveClosePositionUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding FillingValveClosePosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="FillingValveClosePositionDownBtn" Content="-" Width="50" Click="FillingValveClosePositionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValveClosePositionDownDownBtn" Content="--" Width="50" Click="FillingValveClosePositionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,295,30,0" VerticalAlignment="Top">
-                        <TextBlock Text="{DynamicResource FillingValueJogSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="FillingValueJogSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValueJogSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValueJogSpeedUpBtn" Content="+" Width="50" Height="50" Click="FillingValueJogSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding FillingValveJogSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="FillingValueJogSpeedDownBtn" Content="-" Width="50" Click="FillingValueJogSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="FillingValueJogSpeedDownDownBtn" Content="--" Width="50" Click="FillingValueJogSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
-                    <Rectangle Height="1" Fill="LightGray" Margin="5,355,5,0" VerticalAlignment="Top"/>
+                    <Grid VerticalAlignment="Top">
+                        <Label x:Name="FillingValveTitleLab" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="16" Content="{DynamicResource FillingValveAdjustment}" Margin="10,0,0,0" Foreground="White"/>
+                        <Button x:Name="FillingValveManualOpenBtn" HorizontalAlignment="Left" Margin="30,32,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveManualOpenBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveManualOpenBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}" FontSize="17">
+                            <TextBlock Text="{DynamicResource FillingValveManualOpen}" TextWrapping="Wrap" TextAlignment="Center"/>
+                        </Button>
+                        <Button x:Name="FillingValveManualCloseBtn" HorizontalAlignment="Left" Margin="190,32,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveManualCloseBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveManualCloseBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource FillingValveManualClose}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
+                        </Button>
+                        <Button x:Name="FillingValveJogFwdBtn" HorizontalAlignment="Left" Margin="30,87,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveJogFwdBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveJogFwdBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource FillingValveJogFw}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
+                        </Button>
+                        <Button x:Name="FillingValveJogRevBtn" HorizontalAlignment="Left" Margin="190,87,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveJogRevBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FillingValveJogRevBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top" Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource FillingValveJogRev}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
+                        </Button>
+                        <Button x:Name="FillingValveHomeBtn" HorizontalAlignment="Left" Margin="30,142,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="FillingValveHomeBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top" Style="{StaticResource BtnColor}" PreviewMouseLeftButtonUp="FillingValveHomeBtn_PreviewMouseLeftButtonUp">
+                            <TextBlock Text="{DynamicResource FillingValveSetHome}" TextWrapping="Wrap" TextAlignment="Center" FontSize="17"/>
+                        </Button>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,29,30,0">
+                            <TextBlock Text="{DynamicResource FillingValveOpenPosition}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="FillingValveOpenPositionUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveOpenPositionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValveOpenPositionUpBtn" Content="+" Width="50" Height="50" Click="FillingValveOpenPositionUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding FillingValveOpenPosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="FillingValveOpenPositionDownBtn" Content="-" Width="50" Click="FillingValveOpenPositionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValveOpenPositionDownDownBtn" Content="--" Width="50" Click="FillingValveOpenPositionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,29,510,0" VerticalAlignment="Top">
+                            <TextBlock Text="{DynamicResource FillingValveOpenSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="FillingValveOpenSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveOpenSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
+                            <Button x:Name="FillingValveOpenSpeedUpBtn" Content="+" Width="50" Height="50" Click="FillingValveOpenSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding FillingValveOpenSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="FillingValveOpenSpeedDownBtn" Content="-" Width="50" Click="FillingValveOpenSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValveOpenSpeedDownDownBtn" Content="--" Width="50" Click="FillingValveOpenSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,89,510,0">
+                            <TextBlock Text="{DynamicResource FillingValveCloseSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="FillingValveCloseSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveCloseSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValveCloseSpeedUpBtn" Content="+" Width="50" Height="50" Click="FillingValveCloseSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding FillingValveCloseSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="FillingValveCloseSpeedDownBtn" Content="-" Width="50" Click="FillingValveCloseSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0"/>
+                            <Button x:Name="FillingValveCloseSpeedDownDownBtn" Content="--" Width="50" Click="FillingValveCloseSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,89,30,0" VerticalAlignment="Top">
+                            <TextBlock Text="{DynamicResource FillingValveClosePosition}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="FillingValveClosePositionUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValveClosePositionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValveClosePositionUpBtn" Content="+" Width="50" Height="50" Click="FillingValveClosePositionUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding FillingValveClosePosition,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="FillingValveClosePositionDownBtn" Content="-" Width="50" Click="FillingValveClosePositionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValveClosePositionDownDownBtn" Content="--" Width="50" Click="FillingValveClosePositionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,149,30,0" VerticalAlignment="Top">
+                            <TextBlock Text="{DynamicResource FillingValueJogSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="FillingValueJogSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="FillingValueJogSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValueJogSpeedUpBtn" Content="+" Width="50" Height="50" Click="FillingValueJogSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding FillingValveJogSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="FillingValueJogSpeedDownBtn" Content="-" Width="50" Click="FillingValueJogSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="FillingValueJogSpeedDownDownBtn" Content="--" Width="50" Click="FillingValueJogSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                    </Grid>
 
-                    <Label x:Name="BeltsTitleLab" FontSize="16" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,355,0,0" Content="{DynamicResource BeltsAdjustment}" Foreground="White"/>
-                    <Button x:Name="MachineManualBeltsBtn" HorizontalAlignment="Left" Margin="30,390,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="MachineManualBeltsBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource MachineManualBelts}" TextWrapping="Wrap" TextAlignment="Center"/>
-                    </Button>
-                    <Button x:Name="BeltsJogBtn" HorizontalAlignment="Left" Margin="190,390,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="BeltsJogBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="BeltsJogBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
-                        <TextBlock Text="{DynamicResource BeltsJog}" TextWrapping="Wrap" TextAlignment="Center"/>
-                    </Button>
-                    <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,390,30,0" VerticalAlignment="Top">
-                        <TextBlock Text="{DynamicResource BeltsSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
-                        <Button x:Name="BeltsSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="BeltsSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="BeltsSpeedUpBtn" Content="+" Width="50" Height="50" Click="BeltsSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
-                        <TextBox Text="{Binding BeltsSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
-                        <Button x:Name="BeltsSpeedDownBtn" Content="-" Width="50" Click="BeltsSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
-                        <Button x:Name="BeltsSpeedDownDownBtn" Content="--" Width="50" Click="BeltsSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
-                    </StackPanel>
+                    <Rectangle Height="1" Fill="LightGray" Margin="5,209,5,0" VerticalAlignment="Top"/>
+                    <Grid VerticalAlignment="Top" Margin="0,209,0,0">
+                        <Label x:Name="BeltsTitleLab" FontSize="16" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,0,0,0" Content="{DynamicResource BeltsAdjustment}" Foreground="White"/>
+                        <Button x:Name="MachineManualBeltsBtn" HorizontalAlignment="Left" Margin="30,35,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="MachineManualBeltsBtn_PreviewMouseLeftButtonDown" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource MachineManualBelts}" TextWrapping="Wrap" TextAlignment="Center"/>
+                        </Button>
+                        <Button x:Name="BeltsJogBtn" HorizontalAlignment="Left" Margin="190,35,0,0" Height="50" Width="150" PreviewMouseLeftButtonDown="BeltsJogBtn_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="BeltsJogBtn_PreviewMouseLeftButtonUp" VerticalAlignment="Top"  Style="{StaticResource BtnColor}">
+                            <TextBlock Text="{DynamicResource BeltsJog}" TextWrapping="Wrap" TextAlignment="Center"/>
+                        </Button>
+                        <StackPanel Height="50" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,35,30,0" VerticalAlignment="Top">
+                            <TextBlock Text="{DynamicResource BeltsSpeed}" FontSize="16" Margin="5,0,10,0" VerticalAlignment="Center" Width="120" TextWrapping="Wrap" TextAlignment="Center" Foreground="White"/>
+                            <Button x:Name="BeltsSpeedUpUpBtn" Content="++" Width="50" Height="50" Click="BeltsSpeedUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BeltsSpeedUpBtn" Content="+" Width="50" Height="50" Click="BeltsSpeedUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding BeltsSpeed,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="100" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="BeltsSpeedDownBtn" Content="-" Width="50" Click="BeltsSpeedDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BeltsSpeedDownDownBtn" Content="--" Width="50" Click="BeltsSpeedDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                    </Grid>
                 </Grid>
             </GroupBox>
 
@@ -250,6 +256,12 @@
                         <Button x:Name="MachineAirLockValveBtn" HorizontalAlignment="Left" Height="80" Width="140" PreviewMouseLeftButtonDown="MachineAirLockValveBtn_PreviewMouseLeftButtonDown" Style="{StaticResource BtnColor}" >
                             <TextBlock Text="{DynamicResource MachineAirLockValve}" TextWrapping="Wrap" TextAlignment="Center"/>
                         </Button>
+                        <Button x:Name="BottleStopperBtn" HorizontalAlignment="Left" Height="80" Width="140" Style="{StaticResource BtnColor}" PreviewMouseLeftButtonDown="BottleStopperBtn_PreviewMouseLeftButtonDown" >
+                            <TextBlock Text="{DynamicResource BottleStopper}" TextWrapping="Wrap" TextAlignment="Center"/>
+                        </Button>
+                        <Button x:Name="BottlePassBtn" HorizontalAlignment="Left" Height="80" Width="140" Style="{StaticResource BtnColor}" PreviewMouseLeftButtonDown="BottlePassBtn_PreviewMouseLeftButtonDown" >
+                            <TextBlock Text="{DynamicResource BottlePass}" TextWrapping="Wrap" TextAlignment="Center"/>
+                        </Button>
                         <Button x:Name="DoorOpenAlarmShieldingBtn" HorizontalAlignment="Left" Height="80" Width="140" PreviewMouseLeftButtonDown="DoorOpenAlarmShieldingBtn_PreviewMouseLeftButtonDown" Style="{StaticResource BtnColor}" >
                             <TextBlock Text="{DynamicResource DoorOpenAlarmShielding}" TextWrapping="Wrap" TextAlignment="Center"/>
                         </Button>
@@ -376,6 +388,38 @@
                             <Button x:Name="MaterialShortageStoppageDelayTimeDownBtn" Content="-" Width="45" Click="MaterialShortageStoppageDelayTimeDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
                             <Button x:Name="MaterialShortageStoppageDelayTimeDownDownBtn" Content="--" Width="45" Click="MaterialShortageStoppageDelayTimeDownDownBtn_Click" Style="{StaticResource BtnColor}" />
                         </StackPanel>
+                        <StackPanel Height="45" Orientation="Horizontal">
+                            <TextBlock Text="{DynamicResource MissBottleRestartTime}" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center" Width="150" TextWrapping="Wrap" Foreground="White"/>
+                            <Button x:Name="MissBottleRestartTimeUpUpBtn" Content="++" Width="45" Click="MissBottleRestartTimeUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="MissBottleRestartTimeUpBtn" Content="+" Width="45" Click="MissBottleRestartTimeUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding MissBottleRestart,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="90" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="MissBottleRestartTimeDownBtn" Content="-" Width="45" Click="MissBottleRestartTimeDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="MissBottleRestartTimeDownDownBtn" Content="--" Width="45" Click="MissBottleRestartTimeDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="45" Orientation="Horizontal">
+                            <TextBlock Text="{DynamicResource BottleStopPassTime}" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center" Width="150" TextWrapping="Wrap" Foreground="White"/>
+                            <Button x:Name="BottleStopPassTimeUpUpBtn" Content="++" Width="45" Click="BottleStopPassTimeUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BottleStopPassTimeUpBtn" Content="+" Width="45" Click="BottleStopPassTimeUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding BottleStopPassTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="90" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="BottleStopPassTimeDownBtn" Content="-" Width="45" Click="BottleStopPassTimeDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BottleStopPassTimeDownDownBtn" Content="--" Width="45" Click="BottleStopPassTimeDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="45" Orientation="Horizontal">
+                            <TextBlock Text="{DynamicResource BuzzerTime}" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center" Width="150" TextWrapping="Wrap" Foreground="White"/>
+                            <Button x:Name="BuzzerTimeUpUpBtn" Content="++" Width="45" Click="BuzzerTimeUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BuzzerTimeUpBtn" Content="+" Width="45" Click="BuzzerTimeUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding BuzzerTime,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="90" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="BuzzerTimeDownBtn" Content="-" Width="45" Click="BuzzerTimeDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="BuzzerTimeDownDownBtn" Content="--" Width="45" Click="BuzzerTimeDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
+                        <StackPanel Height="45" Orientation="Horizontal">
+                            <TextBlock Text="{DynamicResource CacheDecelerateProportion}" FontSize="16" Margin="5,0,0,0" VerticalAlignment="Center" Width="150" TextWrapping="Wrap" Foreground="White"/>
+                            <Button x:Name="CacheDecelerateProportionUpUpBtn" Content="++" Width="45" Click="CacheDecelerateProportionUpUpBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="CacheDecelerateProportionUpBtn" Content="+" Width="45" Click="CacheDecelerateProportionUpBtn_Click" Style="{StaticResource BtnColor}" />
+                            <TextBox Text="{Binding CacheDecelerateProportion,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" FontSize="16" Width="90" KeyDown="TextBox_KeyDown" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="{x:Null}" Foreground="White"/>
+                            <Button x:Name="CacheDecelerateProportionDownBtn" Content="-" Width="45" Click="CacheDecelerateProportionDownBtn_Click" Style="{StaticResource BtnColor}" Margin="0,0,5,0" />
+                            <Button x:Name="CacheDecelerateProportionDownDownBtn" Content="--" Width="45" Click="CacheDecelerateProportionDownDownBtn_Click" Style="{StaticResource BtnColor}" />
+                        </StackPanel>
                     </WrapPanel>
                 </ScrollViewer>
             </GroupBox>

+ 290 - 46
WpfSwitchLanguage/WpfPage/PlcSettingPage.xaml.cs

@@ -1,8 +1,10 @@
 using CCDCount.DLL;
+using CCDCountWpf.WpfFrom;
 using System;
 using System.Drawing;
 using System.Globalization;
 using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
@@ -943,12 +945,6 @@ namespace CCDCountWpf.WpfPage
                 PlcSettingMessageBus.PlcMessageShowBindage.EliminateCylinderHoldingTime -= 1;
             }
         }
-
-        private void ReloadBtn_Click(object sender, RoutedEventArgs e)
-        {
-            UpdatePlcPara();
-            UpdateDoorOpenAlarmShieldingBtnStatic();
-        }
         private void UpdatePlcPara()
         {
             var ParaValue = PlcSettingMessageBus.pLCManagement.ReadAllPara();
@@ -1059,39 +1055,16 @@ namespace CCDCountWpf.WpfPage
                 ParaValue.EliminateCylinderHoldingTime;
             PlcSettingMessageBus.PlcMessageShowBindage.MaterialShortageStoppageDelayTime =
                 ParaValue.MaterialShortageStoppageDelayTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart =
+                ParaValue.MissBottleReSestart;
+            PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime = 
+                ParaValue.BottleStopPassTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime = 
+                ParaValue.BuzzerTime;
+            PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion = 
+                ParaValue.CacheDecelerateProportion;
         }
 
-        /// <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)
         {
             if(PlcSettingMessageBus.pLCManagement.SwitchValveManualControl(0,out bool ValveState))
@@ -1223,41 +1196,71 @@ namespace CCDCountWpf.WpfPage
         private void ScrewHomeBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.ScrewHomeToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void ScrewHomeBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.ScrewHomeToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void ScrewJogFwdBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.ScrewJogFwdToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void ScrewJogFwdBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.ScrewJogFwdToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void ScrewJogRevBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.ScrewJogRevToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void ScrewJogRevBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.ScrewJogRevToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void FillingValveManualOpenBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveManualOpenToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
+        }
+
+        private void FillingValveManualOpenBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualOpenToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void FillingValveManualCloseBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveManualCloseToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
+        }
+
+        private void FillingValveManualCloseBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            PlcSettingMessageBus.pLCManagement.FillingValveManualCloseToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void FillingValveManualCacheBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
@@ -1268,62 +1271,86 @@ namespace CCDCountWpf.WpfPage
         private void FillingValveJogFwdBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveJogFwdToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void FillingValveJogFwdBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveJogFwdToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void FillingValveJogRevBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveJogRevToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void FillingValveJogRevBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveJogRevToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void FillingValveHomeBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveHomeToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
 
         private void FillingValveHomeBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.FillingValveHomeToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void BeltsJogBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.BeltsJogToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void BeltsJogBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.BeltsJogToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void MachineManualUpBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.MachineManualUpToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void MachineManualUpBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.MachineManualUpToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void MachineManualDownBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.MachineManualDownToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void MachineManualDownBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.MachineManualDownToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void FunnelValveManualControlBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
@@ -1374,24 +1401,19 @@ namespace CCDCountWpf.WpfPage
             }
         }
 
-        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();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void DataResetBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.DataResetToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void ShakeTable1_TestBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
@@ -1533,6 +1555,39 @@ namespace CCDCountWpf.WpfPage
             }
         }
 
+
+        private void BottleStopperBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            if(PlcSettingMessageBus.pLCManagement.BottleStopperSwitch(out bool ValveState))
+            {
+                var ThisButton = (Button)sender;
+                if (ValveState)
+                {
+                    ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
+                }
+                else
+                {
+                    ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
+                }
+            }
+        }
+
+        private void BottlePassBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            if (PlcSettingMessageBus.pLCManagement.BottlePassSwitch(out bool ValveState))
+            {
+                var ThisButton = (Button)sender;
+                if (ValveState)
+                {
+                    ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
+                }
+                else
+                {
+                    ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
+                }
+            }
+        }
+
         private void ShakeTable1_TestSpeedUpUpBtn_Click(object sender, RoutedEventArgs e)
         {
             if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.ShakeTable1_TestSpeed + 10) >
@@ -2128,21 +2183,29 @@ namespace CCDCountWpf.WpfPage
         private void PassABottleBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.PassABottleToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void PassABottleBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.PassABottleToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void AxisResetBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.AxisResetToTrue();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
         }
 
         private void AxisResetBtn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
         {
             PlcSettingMessageBus.pLCManagement.AxisResetToFalse();
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
         }
 
         private void DoorOpenAlarmShieldingBtn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
@@ -2212,5 +2275,186 @@ namespace CCDCountWpf.WpfPage
                 PlcSettingMessageBus.PlcMessageShowBindage.MaterialShortageStoppageDelayTime -= 10;
             }
         }
+
+        private async void ReloadBtn_Click(object sender, RoutedEventArgs e)
+        {
+            var ThisButton = (Button)sender;
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor2");
+            var loadwin = new LoadingWindow();
+            loadwin.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+            loadwin.Show();
+            try
+            {
+                await Task.Run(() =>
+                {
+                    UpdatePlcPara();
+                });
+                await Dispatcher.InvokeAsync(() =>
+                {
+                    UpdateDoorOpenAlarmShieldingBtnStatic();
+                });
+            }
+            finally
+            {
+                await Dispatcher.InvokeAsync(() => {
+                    loadwin.Close();
+                });
+            }
+            ThisButton.Style = (Style)Application.Current.FindResource("BtnColor");
+        }
+
+        private void MissBottleRestartTimeUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart += 10;
+            }
+        }
+
+        private void MissBottleRestartTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart += 1;
+            }
+        }
+
+        private void MissBottleRestartTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart -= 1;
+            }
+        }
+
+        private void MissBottleRestartTimeDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart &&
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart - 10 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.MissBottleRestart -= 10;
+            }
+        }
+
+        private void BottleStopPassTimeUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime += 10;
+            }
+        }
+
+        private void BottleStopPassTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime += 1;
+            }
+        }
+
+        private void BottleStopPassTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime - 1) <
+                 PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime &&
+                 PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime -= 1;
+            }
+        }
+
+        private void BottleStopPassTimeDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime - 10 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BottleStopPassTime -= 10;
+            }
+        }
+
+        private void BuzzerTimeUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime += 10;
+            }
+        }
+
+        private void BuzzerTimeUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime += 1;
+            }
+        }
+
+        private void BuzzerTimeDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime - 1 > 0)
+            {   
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime -= 1;
+            }
+        }
+
+        private void BuzzerTimeDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime &&
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime - 10 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.BuzzerTime -= 10;
+            }
+        }
+
+        private void CacheDecelerateProportionUpUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion + 10) >
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion + 10 <= 100)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion += 10;
+            }
+        }
+
+        private void CacheDecelerateProportionUpBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion + 1) >
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion + 1 <= 100)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion += 1;
+            }
+        }
+
+        private void CacheDecelerateProportionDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion - 1) <
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion - 1 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion -= 1;
+            }
+        }
+
+        private void CacheDecelerateProportionDownDownBtn_Click(object sender, RoutedEventArgs e)
+        {
+            if ((ushort)(PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion - 10) <
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion &&
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion - 10 > 0)
+            {
+                PlcSettingMessageBus.PlcMessageShowBindage.CacheDecelerateProportion -= 10;
+            }
+        }
     }
 }

+ 12 - 5
WpfSwitchLanguage/WpfPage/SettingPage.xaml.cs

@@ -223,11 +223,18 @@ namespace CCDCountWpf.WpfPage
             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)).ToString();
-            ShowMessageBus.ShowBinding.MIN_OBJECT_LENGTH = ((int)(paravalue.MinLength)).ToString();
+            if(paravalue!=null)
+            {
+                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)).ToString();
+                ShowMessageBus.ShowBinding.MIN_OBJECT_LENGTH = ((int)(paravalue.MinLength)).ToString();
+            }
+            else
+            {
+                MessageBox.Show("Train Error");
+            }
         }
         private void TextBox_KeyDown(object sender, KeyEventArgs e)
         {

+ 7 - 0
WpfSwitchLanguage/WpfSwitchLanguage.csproj

@@ -104,6 +104,9 @@
     <Compile Include="WpfFrom\ChangeUserWindow.xaml.cs">
       <DependentUpon>ChangeUserWindow.xaml</DependentUpon>
     </Compile>
+    <Compile Include="WpfFrom\LoadingWindow.xaml.cs">
+      <DependentUpon>LoadingWindow.xaml</DependentUpon>
+    </Compile>
     <Compile Include="WpfFrom\SplashWindow.xaml.cs">
       <DependentUpon>SplashWindow.xaml</DependentUpon>
     </Compile>
@@ -154,6 +157,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="WpfFrom\LoadingWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="WpfFrom\SplashWindow.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>