Parcourir la source

优化多相机切换,图像结果显示

刘彬 il y a 6 mois
Parent
commit
a6e6bdbabd

+ 1 - 0
App.config

@@ -7,6 +7,7 @@
   <startup>
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
   </startup>
+	
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>

+ 1 - 0
App.xaml.cs

@@ -2,6 +2,7 @@
 using LampInspectionMachine.Log4xml;
 using LampInspectionMachine.Model;
 using LampInspectionMachine.Views;
+using log4net.Config;
 using Prism.Ioc;
 using Prism.Unity;
 using System.ComponentModel;

+ 33 - 13
Cameralibs/HKCamera/MvCamera.cs

@@ -454,7 +454,7 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
         /// <returns></returns>
         public ICogImage Grab()
         {
-                    m_MyCamera.StreamGrabber.StartGrabbing();
+            m_MyCamera.StreamGrabber.StartGrabbing();
             m_MyCamera.Parameters.SetEnumValueByString("AcquisitionMode", "Continuous");
             m_MyCamera.Parameters.SetEnumValueByString("TriggerMode", "Off");
             m_MyCamera.Parameters.SetFloatValue("ExposureTime", 5000); // 单位μs
@@ -540,7 +540,13 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
             m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true };
             m_hReceiveThread.Start();
         }
-
+        /// <summary>
+        /// 开始触发模式采集图像
+        /// </summary>
+        public void StartTriggerGrabbing()
+        {
+            m_MyCamera.StreamGrabber.StartGrabbing();
+        }
         /// <summary>
         /// 停止采集图像
         /// </summary>
@@ -631,9 +637,8 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
 
 
             // 直接转换为CogImage,避免不必要的内存拷贝
-            image = ConvertToICogImage(pImage.Width, pImage.Height,
+            image = ConvertToICogImage(pImage.Height,pImage.Width, 
                                      pImage.PixelDataPtr, pixelType);
-
             ////2.申请 byte[] 
             //byte[] m_BufForDriver1 = new byte[pImage.ImageSize];
 
@@ -755,10 +760,13 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
             }
             if (mode)
             {
+                // ch:注册回调函数 | en:Register image callback
+                m_MyCamera.StreamGrabber.FrameGrabedEvent += FrameGrabedEventHandler;
                 return SetTriggerSource(triggerSource);
             }
             else
             {
+                m_MyCamera.StreamGrabber.FrameGrabedEvent -= FrameGrabedEventHandler;
                 nRet = m_MyCamera.Parameters.SetEnumValueByString("AcquisitionMode", "Continuous");
                 if (nRet != MvError.MV_OK)
                 {
@@ -859,10 +867,7 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
                 try
                 {
                     IFrameOut frameOut = null;
-                  
-
-                    int nRet = m_MyCamera.StreamGrabber.GetImageBuffer(5000, out frameOut);
-
+                    int nRet = m_MyCamera.StreamGrabber.GetImageBuffer(500, out frameOut);
                     double time1 = sw.Elapsed.TotalMilliseconds;
                     Console.WriteLine($"获取图像:{time1}ms");
                     if ( nRet == MvError.MV_OK )
@@ -877,7 +882,6 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
                         TotalTime = sw.Elapsed;
                         Thread.Sleep(5);
                     }
-                   
                 }
                 catch (Exception ex)
                 {
@@ -918,10 +922,6 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
                     CogImage8Grey cogImage8Grey = new CogImage8Grey();
                     cogImage8Grey.SetRoot(cogImage8Root);
                     cogImage = cogImage8Grey.ScaleImage((int)nWidth, (int)nHeight);
-
-
-
-
                     System.GC.Collect();
                 }
                 else
@@ -1093,6 +1093,26 @@ namespace LampInspectionMachine.Cameralibs.HKCamera
         {
             PropertyChanged?.Invoke(this, args);
         }
+
+        public bool CheckGrabImageCallbackEventIsHas(Action<ICogImage> action)
+        {
+            if ( GrabImageCallbackEvent == null ) return false;
+            return GrabImageCallbackEvent.GetInvocationList().Contains(action);
+        }
+
+        public bool CheckImageCallbackEventIsHas(Action<ICogImage, TimeSpan, string> action)
+        {
+            if ( ImageCallbackEvent == null ) return false;
+            return ImageCallbackEvent.GetInvocationList().Contains(action);
+        }
+
+        public bool CheckCameraConnectChangedEventIsHas(Action<Guid, bool> action)
+        {
+            if ( CameraConnectChangedEvent == null ) return false;
+            return CameraConnectChangedEvent.GetInvocationList().Contains(action);
+        }
+
+       
         #endregion
     }
 }

+ 164 - 0
Core/FileHelper.cs

@@ -0,0 +1,164 @@
+using LampInspectionMachine.Model;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace LampInspectionMachine.Core
+{
+    public static class FileHelper
+    {
+        /// <summary>
+        /// 写入Json文件
+        /// </summary>
+        /// <param name="obj">对象</param>
+        /// <param name="path">文件路径</param>
+        public static void WriteJsonFile(object obj, string path)
+        {
+            if ( !Directory.Exists(Path.GetDirectoryName(path)) )
+            {
+                Directory.CreateDirectory(Path.GetDirectoryName(path));
+            }
+            using ( StreamWriter sw = new StreamWriter(path) )
+            {
+                string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
+                sw.Write(JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented));
+            }
+        }
+
+        /// <summary>
+        /// 读取Json文件
+        /// </summary>
+        /// <typeparam name="T">对象</typeparam>
+        /// <param name="path">文件路径</param>
+        /// <returns></returns>
+        /// <exception cref="Exception"></exception>
+        public static T ReadJsonFile<T>(string path)
+        {
+            if ( File.Exists(path) )
+            {
+                string buffer;
+                using ( StreamReader sr = new StreamReader(path) )
+                {
+                    buffer = sr.ReadToEnd();
+                }
+                return JsonConvert.DeserializeObject<T>(buffer);
+            }
+            else
+            {
+                throw new Exception($"文件不存在:[{path}]");
+            }
+        }
+
+        /// <summary>
+        /// 写入文件
+        /// </summary>
+        /// <param name="content">对象</param>
+        /// <param name="path">文件路径</param>
+        public static void WriteFile(string content, string path)
+        {
+            if ( !Directory.Exists(Path.GetDirectoryName(path)) )
+            {
+                Directory.CreateDirectory(Path.GetDirectoryName(path));
+            }
+            using ( StreamWriter sw = new StreamWriter(path) )
+            {
+                sw.Write(content);
+            }
+        }
+
+        /// <summary>
+        /// 读取文件
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        /// <exception cref="Exception"></exception>
+        public static string ReadFile(string path)
+        {
+            if ( File.Exists(path) )
+            {
+                string buffer;
+                using ( StreamReader sr = new StreamReader(path) )
+                {
+                    buffer = sr.ReadToEnd();
+                }
+                return buffer;
+            }
+            else
+            {
+                throw new Exception($"文件不存在:[{path}]");
+            }
+        }
+
+        /// <summary>
+        /// 读取软件设置参数
+        /// </summary>
+        /// <returns></returns>
+        public static List<CameraInfo> ReadApplicationConfiguration()
+        {
+            try
+            {
+                if ( File.Exists(FilePath.ApplicationConfigurationPath) )
+                {
+                    var config = FileHelper.ReadJsonFile<List<CameraInfo>>(FilePath.ApplicationConfigurationPath);
+                    return config;
+                }
+                else
+                {
+                    var config= new List<CameraInfo>();
+                    FileHelper.WriteJsonFile(config, FilePath.ApplicationConfigurationPath);
+                    return config;
+                }
+            }
+            catch ( Exception )
+            {
+                return new List<CameraInfo>();
+            }
+        }
+
+        /// <summary>
+        /// 保存软件设置参数
+        /// </summary>
+        /// <param name="config"></param>
+        public static void SaveApplicationConfiguration(List<CameraInfo> config)
+        {
+            try
+            {
+                //config.DT = DateTime.Now;
+                FileHelper.WriteJsonFile(config, FilePath.ApplicationConfigurationPath);
+            }
+            catch ( Exception )
+            {
+
+            }
+        }
+
+        /// <summary>
+        /// 检测文件名是否合规
+        /// </summary>
+        /// <param name="filename"></param>
+        /// <returns></returns>
+        public static bool CheckFileName(string filename)
+        {
+            //
+            // 定义文件名合法性的正则表达式
+            string pattern = @"^[^-\\/:*?""<>|\x00-\x1F]*$"; // 匹配不包含非法字符的文件名
+
+            // 使用正则表达式进行匹配
+            if ( Regex.IsMatch(filename, pattern) )
+            {
+                //Console.WriteLine("输入的名称符合文件名命名规则,并且不包含非法字符。");
+                return true;
+            }
+            else
+            {
+                //Console.WriteLine("输入的名称不符合文件名命名规则,或者包含非法字符。");
+                return false;
+            }
+        }
+    }
+}

+ 138 - 0
Core/FilePath.cs

@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LampInspectionMachine.Core
+{/// <summary>
+ /// 应用一些配置文件路径
+ /// </summary>
+    public static class FilePath
+    {
+        /// <summary>
+        /// 用户权限数据库路径
+        /// </summary>
+        public static string UserDbPath = "..//Database File//User.db";
+
+        /// <summary>
+        /// 生产记录数据库路径
+        /// </summary>
+        public static string ProductionRecordsDbPath = "..//Database File//ProductionRecords.db";
+
+        /// <summary>
+        /// 帮助文件夹路径
+        /// </summary>
+        public static string HelpPath = "..//Help";
+
+        /// <summary>
+        /// 校准文件夹路径
+        /// </summary>
+        public static string CalibrationPath = "..//Calibration";
+
+        /// <summary>
+        /// 软件设置参数文件
+        /// </summary>
+        public static string ApplicationConfigurationPath = "..//Config//ApplicationConfigurationPath.cfg";
+
+        /// <summary>
+        /// 相机配置文件路径
+        /// </summary>
+        public static string CamerasConfigurationPath = "..//Config//CameraConfigurationPath.cfg";
+
+        /// <summary>
+        /// 机器人配置文件路径
+        /// </summary>
+        public static string RobotsConfigurationPath = "..//Config//RobotsConfiguration.cfg";
+
+        /// <summary>
+        /// Feeder配置文件路径
+        /// </summary>
+        public static string FeedersConfigurationPath = "..//Config//FeedersConfiguration.cfg";
+
+        /// <summary>
+        /// 后台TCP/ip配置文件路径
+        /// </summary>
+        public static string BgTcpIpConfigurationPath = "..//Config//BgTcpIpConfiguration.cfg";
+
+        /// <summary>
+        /// 后台Modbus TCP配置文件路径
+        /// </summary>
+        public static string BgModbusTcpConfigurationPath = "..//Config//BgModbusTcpConfiguration.cfg";
+
+        /// <summary>
+        /// 扫码枪配置文件路径
+        /// </summary>
+        public static string BgScanCodeConfigurationPath = "..//Config//BgScanCodeConfigurationPath.cfg";
+
+        /// <summary>
+        /// MES上传配置文件路径
+        /// </summary>
+        public static string BgHttpMESConfigurationPath = "..//Config//BgHttpMESConfigurationPath.cfg";
+
+        /// <summary>
+        /// 字体大小配置文件路径
+        /// </summary>
+        public static string FontSizeConfigurationPath = "..//Config//FontSizeConfiguration.cfg";
+
+        /// <summary>
+        /// 语言配置文件路径
+        /// </summary>
+        public static string LanguageConfigurationPath = "..//Config//LanguageConfiguration.cfg";
+
+        /// <summary>
+        /// 软件配置文件路径
+        /// </summary>
+        public static string DeviceConfigurationPath = "..//Config//DeviceConfiguration.cfg";
+
+        /// <summary>
+        /// 用户点动集合配置文件路径
+        /// </summary>
+        public static string UserInchingConfigurationPath = "..//Config//UserInchingConfiguration.cfg";
+
+        /// <summary>
+        /// 所有产品文件夹路径
+        /// </summary>
+        public static string ProductsPath = "..//Products";
+
+        /// <summary>
+        /// 视觉方案工具文件夹路径
+        /// </summary>
+        public static string VisionTemplatePath = "..//Vision Template";
+
+        /// <summary>
+        /// 产品模板文件夹路径
+        /// </summary>
+        public static string ProductTemplatePath = "..//Product Template";
+
+        /// <summary>
+        /// 简单模式模板流程路径
+        /// </summary>
+        public static string SimpleProcedurePath = "..//Vision Template//TemplateToolBlock.vpp";
+
+        /// <summary>
+        /// 相机校准模板工具组
+        /// </summary>
+        public static string CalibrationToolblockPath = "..//Vision Template//Calibration.vpp";
+
+        /// <summary>
+        /// Feeder清料任务文件路径
+        /// </summary>
+        public static string FeedersClearTaskPath = "..//Config//FeedersClearTask.cfg";
+
+        /// <summary>
+        /// 视觉处理模板脚本路径
+        /// </summary>
+        public static string ScriptVisionTemplatePath = "..//Script Template//Vision Template.cs";
+
+        /// <summary>
+        /// 后台模板脚本路径
+        /// </summary>
+        public static string ScriptBackgroundTemplatePath = "..//Script Template//Background Template.cs";
+
+        /// <summary>
+        /// 后台脚本存放文件夹
+        /// </summary>
+        public static string BackgroundScriptPath = "..//Background Script";
+    }
+}

+ 228 - 104
Core/Management.cs

@@ -40,6 +40,8 @@ using LampInspectionMachine.Cameralibs.HKCamera;
 using Newtonsoft.Json.Linq;
 using OpenCvSharp.Dnn;
 using LampInspectionMachine.Interfaces;
+using System.IO;
+using LampInspectionMachine.KHLplc;
 
 namespace LampInspectionMachine.Core
 {
@@ -50,25 +52,17 @@ namespace LampInspectionMachine.Core
 
 
         private CameraView cameraView;
-        private ICogImage image = new CogImage8Grey();
-        private WriteableBitmap writeable;
-
-        public WriteableBitmap Writeable { get => writeable; set { SetProperty(ref writeable, value); } }
-        public ICogImage Image
+        private ShowRender render = new ShowRender();
+        public ShowRender Render
         {
-            get => image;
+            get => render;
             set
             {
-                SetProperty(ref image, value);
+                SetProperty(ref render, value);
             }
         }
-
-        // 使用泛型委托
-        public event EventHandler<ICogImage> PropertyChanged;
-
-        // 或者自定义委托
-        public delegate void ChangeEventHandler(ICogImage e);
-        public event ChangeEventHandler OnChange;
+        private KHLCommunicate _kHLCommunicate;
+        public KHLCommunicate KHLCommunicate { get => _kHLCommunicate; set => _kHLCommunicate = value; }
 
         public CameraService CameraService { get; set; }
 
@@ -82,12 +76,13 @@ namespace LampInspectionMachine.Core
         /// <summary>
         /// 当前相机配置
         /// </summary>
-       public CameraInfo CurrCamConfig { get => _CurrCamConfig; set { SetProperty(ref _CurrCamConfig, value); } }
+       public CameraInfo CurrCamConfig { get => _CurrCamConfig;
+            set { SetProperty(ref _CurrCamConfig, value); } }
 
         /// <summary>
         /// 相机配置列表
         /// </summary>
-        public ObservableCollection<CameraInfo> CamConfigs { get => _CamConfigs; set { SetProperty(ref _CamConfigs, value); } }
+        public List<CameraInfo> CamConfigs { get => _CamConfigs; set { SetProperty(ref _CamConfigs, value); } }
 
       //  public bool IsTriggerModel { get => _isTriggerModel; set { SetProperty(ref _isTriggerModel, value); } }
 
@@ -99,19 +94,29 @@ namespace LampInspectionMachine.Core
      //   public List<CogToolBlock> CamTemplateS { get => _CamTemplateS; set => _CamTemplateS = value; }
 
         public event Action<int> ToolBlockSwitched;
+
+        public event Action<int> ToolBlockCatched;
+
+
+        private int _CurrIndex=0;
+        /// <summary>
+        /// 当前选中的视觉方案id
+        /// </summary>
+        public int CurrIndex { get => _CurrIndex; set => _CurrIndex = value; }
         /// <summary>
         /// 当前选中相机的SN
         /// </summary>
         public string CurrCameraSn { get => _CurrCameraSn; 
             set { SetProperty(ref _CurrCameraSn, value); } }
 
-        public List<VisionProManager> VisionProManagers { get => _visionProManagers; set { SetProperty(ref _visionProManagers, value); } }
+        public ObservableCollection<VisionProManager> VisionProManagers { get => _visionProManagers; set { SetProperty(ref _visionProManagers, value); } }
 
         public VisionProManager Currvision { get => _Currvision; set => _Currvision =  value ; }
+  
 
-        private ObservableCollection<CameraInfo> _CamConfigs = new ObservableCollection<CameraInfo>();
+        private List<CameraInfo> _CamConfigs = new List<CameraInfo>();
 
-        private List<VisionProManager>  _visionProManagers=new List<VisionProManager>();
+        private ObservableCollection<VisionProManager>  _visionProManagers=new ObservableCollection<VisionProManager>();
 
       //  private List<CogToolBlock> _CamTemplateS = new List<CogToolBlock>();
 
@@ -135,8 +140,13 @@ namespace LampInspectionMachine.Core
 
         }
 
+        public async void ConnectPlc() 
+        {
+            KHLCommunicate = new KHLCommunicate();
+            await KHLCommunicate.ConnPlc();
+        }
 
-
+      
 
         /// <summary>
         /// 获取相机列表
@@ -145,6 +155,7 @@ namespace LampInspectionMachine.Core
         {
             CameraService = new CameraService();
             CameraList = FindLoadCamera();
+            CamConfigs=  FileHelper.ReadApplicationConfiguration();
             if (CamConfigs.Count == 0)
             {
                 CamConfigs.Add(new CameraInfo() { CameraName="相机1", Id=new Guid(), SerialNumber="", VppIndex=0, VppFileName = "Cam1.vpp" });
@@ -156,13 +167,14 @@ namespace LampInspectionMachine.Core
                 CamConfigs.Add(new CameraInfo() { CameraName = "相机7", Id = new Guid(), SerialNumber = "", VppIndex = 6, VppFileName = "Cam7.vpp" });
                 CamConfigs.Add(new CameraInfo() { CameraName = "相机8", Id = new Guid(), SerialNumber = "", VppIndex = 7, VppFileName = "Cam8.vpp" });
             }
+            LogHelper.Info("加载配置文件完成");
         }
 
 
         public void SaveCameraDevice()
         {
-
-
+            FileHelper.SaveApplicationConfiguration(CamConfigs);
+            LogHelper.Info("保存配置完成");
         }
         /// <summary>
         /// 初始化相机管理
@@ -170,25 +182,34 @@ namespace LampInspectionMachine.Core
         public void InitTemplates(TipService tipService,Management management)
         {
             tipService.ShowMsg("相机模板加载2%");
-            for ( int i = 0; i < 1; i++ )
+            for ( int i = 0; i < CamConfigs.Count; i++ )
             {
                
                 CogToolBlock cogToolBlock = (CogToolBlock)CogSerializer.LoadObjectFromFile(Environment.CurrentDirectory + $"\\Vpp\\{CamConfigs[i].VppFileName}");
                 VisionProManager vision=new VisionProManager();
                 ICamera myCamera;
                 myCamera = CreateCamera(CamConfigs[i]);
-                if ( myCamera.IsConnected) 
+                if (myCamera!=null&& myCamera.IsConnected) 
                 {
-                    myCamera.ImageCallbackEvent += vision.CamCallBack;
-                    myCamera.GrabImageCallbackEvent += vision.ImageCallback;
+                    if(myCamera.CheckImageCallbackEventIsHas(vision.CamCallBack))
+                    myCamera.ImageCallbackEvent -= vision.CamCallBack;
+                    if ( !myCamera.CheckGrabImageCallbackEventIsHas(vision.ImageCallback) )
+                        myCamera.GrabImageCallbackEvent += vision.ImageCallback;
+                    myCamera.CameraConnectChangedEvent += vision.CameraConnectChangedEvent;
+                    vision.IsConnected = true;
                 }
                 vision.Camera= myCamera;
+                vision.PlcData.PlcToPcCodeIndex = (uint)(100 + i);
+                vision.PlcData.PcToPlcCompleted = (uint)(200 + i);
+                vision.PlcData.PcToPlcResult = (uint)(300 + i);
+                vision.PlcData.PcToPlcCodeIndex= (uint)(400 + i);
                 vision.CogToolBlock = cogToolBlock;
                 vision.CameraInfo = CamConfigs[ i ];
                 vision.Management=management;
                 VisionProManagers.Add(vision);
                 tipService.ShowMsg($"相机模板加载{(i+1)*10+2}%");
             }
+            LogHelper.Info("模板加载完成");
             tipService.Tcolse();
         }
 
@@ -201,11 +222,17 @@ namespace LampInspectionMachine.Core
             {
                 CurrCamera.StopGrabbing();
                 LogHelper.Info($"软触发配置写入");
-                CurrCamera.SetTriggerMode(false,7) ;
+                CurrCamera.SetTriggerMode(false, 7);
+                if ( !CurrCamera.CheckImageCallbackEventIsHas(Currvision.CamCallBack) )
+                    CurrCamera.ImageCallbackEvent += Currvision.CamCallBack;
                 CurrCamConfig.TriggerMode = false;
                 LogHelper.Info($"软触发取图");
                 CurrCamera.Grab();
             }
+            else 
+            {
+                System.Windows.Forms.MessageBox.Show("相机未打开");
+            }
         }
 
 
@@ -213,30 +240,139 @@ namespace LampInspectionMachine.Core
         /// 连续采集写入
         /// </summary>
         public void SoftTrigger__Continue()
-        {  CurrCamera.StopGrabbing();
-            //MyCamera.SetTriggerModeOff();
-            //CurrCamConfig.TriggerMode = false;
-            //MyCamera.SetTriggerSoftware();
-            //if (MyCamera.CheckImageCallbackEvent(CamCallBack))
-            //    MyCamera.ImageCallbackEvent += CamCallBack;
-            //if (!MyCamera.CheckImageCallbackEvent(CamVisionProCallBack))
-            //    MyCamera.ImageCallbackEvent -= CamVisionProCallBack;
-            LogHelper.Info($"连续采集启动");
-            CurrCamera.StartGrabbing();
+        {
+            if ( CurrCamera!=null&& CurrCamera.IsConnected )
+            {
+                CurrCamera.StopGrabbing();
+                CurrCamera.SetTriggerMode(false, 7);
+                CurrCamConfig.TriggerMode = false;
+                if ( !CurrCamera.CheckImageCallbackEventIsHas(Currvision.CamCallBack) )
+                    CurrCamera.ImageCallbackEvent += Currvision.CamCallBack;
+                LogHelper.Info($"连续采集启动");
+                CurrCamera.StartGrabbing();
+            }
+            else
+            {
+                System.Windows.Forms.MessageBox.Show("相机未打开");
+            }
+        }
+
+
+        /// <summary>
+        /// 单张图片测试
+        /// </summary>
+        public void ImageTrigger()
+        {
+            OpenFileDialog openFileDialog = new OpenFileDialog();
+            if ( openFileDialog.ShowDialog() == DialogResult.OK )
+            {
+                // 加载图像文件
+                using ( var bitmap = new Bitmap(openFileDialog.FileName) )
+                {
+                    // 转换为VisionPro图像格式
+                    ICogImage icogImage = new CogImage8Grey(bitmap);
+
+                    // 设置输入参数
+                   Currvision.CogToolBlock.Inputs[0].Value = icogImage;
+
+                    // 执行处理
+                    Currvision.CogToolBlock.Run();
+
+                    // 获取输出结果
+                    if (Currvision.CogToolBlock.RunStatus.Result == CogToolResultConstants.Accept)
+                    {
+
+                        CogToolBlockTerminalCollection outputCollection = Currvision.CogToolBlock.Outputs;
+                        ICogRecord record = null;
+                        foreach (CogToolBlockTerminal item in outputCollection)
+                        {
+                            if (item.Value is ICogRecord)
+                                record = item.Value as ICogRecord;
+                        }
+                        ICogImage cogImage = (ICogImage)Currvision.CogToolBlock.Inputs["Image"].Value;
+                        if (cogImage == null)
+                        {
+
+                            Render = new ShowRender()
+                            {
+                                Graphic = outputCollection["Graphic"].Value as CogGraphicCollection,
+                                Image = icogImage,
+                                Record = record
+                            };
+                        }
+                    }
+                    else
+                    {
+                        Render = new ShowRender()
+                        {
+
+                            Image = icogImage
+
+                        };
+                    }
+
+
+                }
+            }
         }
 
 
+        /// <summary>
+        /// 图片轮询测试
+        /// </summary>
+        public async Task ImageTrigger__Continue()
+        {
+            try
+            {
+                FolderBrowserDialog openFileDialog = new FolderBrowserDialog();
+                if ( openFileDialog.ShowDialog() == DialogResult.OK )
+                {
+                    DirectoryInfo folder = new DirectoryInfo(openFileDialog.SelectedPath);
+                    FileInfo[] files = folder.GetFiles("*.bmp", SearchOption.AllDirectories);
+
+                    Task.Run(() =>
+                    {
+                        foreach ( FileInfo file in files )
+                        {
+                            // 加载图像文件
+                            using ( var bitmap = new Bitmap(file.FullName) )
+                            {
+                                // 转换为VisionPro图像格式
+                                ICogImage cogImage = new CogImage8Grey(bitmap);
+
+                                Currvision.ImageCallback(cogImage);
+                            }
+                        }
+
+                    });
+                   
+                }
+            }
+            catch 
+            {
+            
+            
+            }
+
+           
+        }
+        
+
         public void SetHardTrigger_CallBack()
         {
-            LogHelper.Info($"硬触发模式 启动");
-            //MyCamera.SetTriggerModeOn();
-            //CurrCamConfig.TriggerMode = true;
-            //MyCamera.SetTriggerSoftware(0);
-            //if (!MyCamera.CheckImageCallbackEvent(CamCallBack))
-            //    MyCamera.ImageCallbackEvent -= CamCallBack;
-            //if (MyCamera.CheckImageCallbackEvent(CamVisionProCallBack))
-            //    MyCamera.ImageCallbackEvent += CamVisionProCallBack;
-            CurrCamera.StartGrabbing();
+            if ( CurrCamera != null && CurrCamera.IsConnected )
+            {
+                LogHelper.Info($"硬触发模式 启动");
+                CurrCamera.ImageCallbackEvent -= Currvision.CamCallBack;
+                CurrCamera.SetTriggerMode(true, 0);
+                CurrCamConfig.TriggerMode = true;
+                CurrCamera.StartGrabbing();
+            }
+            else 
+            {
+
+                System.Windows.Forms.MessageBox.Show("相机未打开");
+            }
         }
         /// <summary>
         /// 查找相机
@@ -265,49 +401,63 @@ namespace LampInspectionMachine.Core
 
         public bool InitCamera()
         {
-            ICamera myCamera;
-            if ( CurrCamera!=null&& CurrCamera.IsConnected )
+            try
             {
-                CurrCamera.CloseDevice();
-                myCamera = CameraService.GetCamera(CurrCamera.ID);
-                bool res = myCamera.OpenDevice();
-
-                if ( !res )
+                ICamera myCamera;
+                if ( CurrCamera != null && CurrCamera.IsConnected )
                 {
-                    myCamera.CloseDevice();
-                    myCamera = null;
-                    return false;
+                    CurrCamera.CloseDevice();
+                    myCamera = CameraService.GetCamera(CurrCamera.ID);
+                    bool res = myCamera.OpenDevice();
+
+                    if ( !res )
+                    {
+                        myCamera.CloseDevice();
+                        myCamera = null;
+                        return false;
+                    }
+                    else
+                    {
+                        CurrCamera = myCamera;
+                        CurrCamConfig.SerialNumber = myCamera.SerialNumber;
+                        if ( myCamera.IsConnected )
+                        {
+                            if ( !myCamera.CheckImageCallbackEventIsHas(Currvision.CamCallBack) )
+                                myCamera.ImageCallbackEvent += Currvision.CamCallBack;
+                            if ( !myCamera.CheckGrabImageCallbackEventIsHas(Currvision.ImageCallback) )
+                                myCamera.GrabImageCallbackEvent += Currvision.ImageCallback;
+                            if ( !myCamera.CheckCameraConnectChangedEventIsHas(Currvision.CameraConnectChangedEvent) )
+                                myCamera.CameraConnectChangedEvent += Currvision.CameraConnectChangedEvent;
+                            
+                        }
+                        return true;
+                    }
                 }
                 else
                 {
+                    CurrCamera = null;
+                    myCamera = CreateCamera(new CameraInfo() { SerialNumber = CurrCameraSn });
                     CurrCamera = myCamera;
                     CurrCamConfig.SerialNumber = myCamera.SerialNumber;
-                    if ( myCamera.IsConnected )
+                    if ( myCamera != null&&  myCamera.IsConnected )
                     {
-                        myCamera.ImageCallbackEvent -= Currvision.CamCallBack;
-                        myCamera.GrabImageCallbackEvent -= Currvision.ImageCallback;
-                        myCamera.ImageCallbackEvent += Currvision.CamCallBack;
-                        myCamera.GrabImageCallbackEvent += Currvision.ImageCallback;
+                        if ( !myCamera.CheckImageCallbackEventIsHas(Currvision.CamCallBack) )
+                            myCamera.ImageCallbackEvent += Currvision.CamCallBack;
+                        if ( !myCamera.CheckGrabImageCallbackEventIsHas(Currvision.ImageCallback) )
+                            myCamera.GrabImageCallbackEvent += Currvision.ImageCallback;
+                        if ( !myCamera.CheckCameraConnectChangedEventIsHas(Currvision.CameraConnectChangedEvent) )
+                            myCamera.CameraConnectChangedEvent += Currvision.CameraConnectChangedEvent;
+                        Currvision.IsConnected = true;
                     }
                     return true;
                 }
             }
-            else 
+            catch 
             {
+                CurrCamera?.CloseDevice();
                 CurrCamera = null;
-                myCamera=CreateCamera(new CameraInfo() { SerialNumber=CurrCameraSn });
-                CurrCamera = myCamera;
-                CurrCamConfig.SerialNumber = myCamera.SerialNumber;
-                if ( myCamera.IsConnected )
-                {
-                    myCamera.ImageCallbackEvent -= Currvision.CamCallBack;
-                    myCamera.GrabImageCallbackEvent -= Currvision.ImageCallback;
-                    myCamera.ImageCallbackEvent += Currvision.CamCallBack;
-                    myCamera.GrabImageCallbackEvent += Currvision.ImageCallback;
-                }
-                return true;
+            return false;
             }
-            
 
         }
 
@@ -470,43 +620,17 @@ namespace LampInspectionMachine.Core
             cogToolBlock1 = VisionProManagers[index].CogToolBlock;
             CurrCamera= VisionProManagers[ index ].Camera;
             CurrCamConfig = VisionProManagers[ index ].CameraInfo;
-
+            
             ToolBlockSwitched?.Invoke(index); // 触发事件,传递索引参数。
         }
-
-        /// <summary>
-        /// 相机连接或者断开时
-        /// </summary>
-        /// <param name="id"></param>
-        /// <param name="state"></param>
-        private void Management_CameraConnectChangedEvent(Guid id, bool state)
+        public void OnSaveSwitchToolBlock(int index)
         {
-            // var sta = Status.FirstOrDefault(s => s.ID == id);
-            //  var camera = DeviceConfig.Cameras.FirstOrDefault(c => c.Id == id);
-            //if ( sta != null && camera != null )
-            //{
-            //    if ( state )
-            //    {
-            //        App.Current.Dispatcher.Invoke(new Action(() =>
-            //        {
-            //            sta.Message = $"{camera.CameraName}{connected}";
-            //            sta.Background = new SolidColorBrush(Colors.Green);
-            //        }));
-
-            //    }
-            //    else
-            //    {
-            //        App.Current.Dispatcher.Invoke(new Action(() =>
-            //        {
-            //            sta.Message = $"{camera.CameraName}{disconnected1}";
-            //            sta.Background = new SolidColorBrush(Colors.Red);
-            //        }));
-            //    }
-            //}
+            ToolBlockCatched?.Invoke(index);
         }
 
 
 
+
     }
 
 

+ 142 - 7
Core/VisionProManager.cs

@@ -18,27 +18,54 @@ using System.Linq;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading;
+using Prism.Mvvm;
 using System.Threading.Tasks;
 using System.Windows.Forms;
+using System.Diagnostics;
+using LampInspectionMachine.KHLplc;
 
 namespace LampInspectionMachine.Core
 {
-    public class VisionProManager
+    public class VisionProManager:BindableBase
     {
 
         private ICamera _camera;
 
+        private PlcData _plcData=new PlcData();
+
         private CogToolBlock _cogToolBlock;
+        
+        private  readonly object _lock = new object();
+
+        private bool  _IsConnected;
 
         private  CameraInfo _cameraInfo;
         private Management _management;
 
+        private ShowRender render=new ShowRender();
         public ICamera Camera { get => _camera; set => _camera = value; }
         public CogToolBlock CogToolBlock { get => _cogToolBlock; set => _cogToolBlock = value; }
-        public CameraInfo CameraInfo { get => _cameraInfo; set => _cameraInfo = value; }
+        public CameraInfo CameraInfo { get => _cameraInfo; set { SetProperty(ref _cameraInfo, value); } }
         public Management Management { get => _management; set => _management =  value ; }
+        public ShowRender Render
+        {
+            get => render; 
+            set
+            {
+                SetProperty(ref render, value);
+            }
 
+        }
+
+        public bool IsConnected
+        {
+            get => _IsConnected; set
+            {
+                SetProperty(ref _IsConnected, value);
+            }
+        }
 
+        public PlcData PlcData { get => _plcData; set => _plcData = value; }
 
         /// <summary>
         ///调试图像显示
@@ -48,8 +75,32 @@ namespace LampInspectionMachine.Core
         {
             try
             {
-                
-                if (Management!=null)Management.Image = image;
+                if ( Management != null )
+                {
+                    Management.Render = new ShowRender()
+                    {
+                        Image = image,
+
+                    };
+                    
+
+                    if ( CogToolBlock != null )
+                    {
+                        lock ( _lock )
+                        {
+                            App.Current.Dispatcher.BeginInvoke(new Action(() =>
+                            {
+                                CogToolBlock.Inputs["Image"].Value = image;
+                            }));
+                            //CogToolBlock.Run();
+                            //CogImage = ( ICogImage ) CogToolBlock.Outputs[ 6 ].Value;
+                            //if ( CogImage==null ) 
+                            //{
+                            //    CogImage = image;
+                            //}
+                        }
+                    }
+                }
             }
             finally
             {
@@ -62,15 +113,99 @@ namespace LampInspectionMachine.Core
         /// </summary>
         public void ImageCallback(ICogImage image)
         {
+            ImageCallbackAsync(image).ConfigureAwait(false) ;
+        }
+
+        public async Task ImageCallbackAsync(ICogImage image) 
+        {
+
             if ( CogToolBlock != null )
             {
-                CogToolBlock.Inputs[ 0 ].Value = image;
-                CogToolBlock.Run();
+                try
+                {
+                    lock (_lock)
+                    {
+                        Guid guid = Guid.NewGuid();
+                        int resCode = Management.KHLCommunicate.ReadInt(PlcData.PlcToPcCodeIndex);
+                        LogHelper.CameraInfo(guid.ToString()+$"\r产品码:{resCode}");
+                        CogToolBlock.Inputs["Image"].Value = image;
+                        CogToolBlock.Run();
+                        LogHelper.CameraInfo(guid.ToString() + $"\r产品码:{resCode}[{CameraInfo.CameraName}]运行流程:{CogToolBlock.RunStatus.ProcessingTime:F1}ms");
+                        if (CogToolBlock.RunStatus.Result == CogToolResultConstants.Accept)
+                        {
+                            CogToolBlockTerminalCollection outputCollection = CogToolBlock.Outputs;
+                            ICogRecord record = null;
+                            foreach (CogToolBlockTerminal item in outputCollection)
+                            {
+                                if (item.Value is ICogRecord)
+                                    record = item.Value as ICogRecord;
+                            }
+                            ICogImage cogImage = (ICogImage)CogToolBlock.Inputs["Image"].Value;
+                            if (cogImage != null)
+                            {
+
+                                Render = new ShowRender()
+                                {
+                                    Graphic = outputCollection["Graphics"].Value as CogGraphicCollection,
+                                    Image = image,
+                                    Record = record,
+                                    Result = (bool)(outputCollection["Result"].Value),
+                                };
+                              
+                               
+                            }
+
+
+                        }
+                        else
+                        {
+                            Render = new ShowRender()
+                            {
+
+                                Image = image,
+                                Result=false
+                            };
+                          
+                        }
+
+
+                        LogHelper.CameraInfo(guid.ToString() + $"\r产品码:{resCode}[{CameraInfo.CameraName}]流程结果:{Render.Result}");
+                        int Result = Render.Result ? 1 : 0;
+                        while (Management.KHLCommunicate.IsConnected)
+                        {
+                            if (Management.KHLCommunicate.ReadInt(PlcData.PcToPlcCompleted) == 0)
+                            {
+                                Management.KHLCommunicate.WriteInt(PlcData.PcToPlcCodeIndex, 1, new int[] { resCode });
+                                Management.KHLCommunicate.WriteInt(PlcData.PcToPlcResult, 1, new int[] { Result });
+                                Management.KHLCommunicate.WriteInt(PlcData.PcToPlcCompleted,1,new int[] {1});
+                                break;
+                            }
+                        }
+                        LogHelper.CameraInfo(guid.ToString() + $"\r产品码:{resCode} 回复完成");
+                    }
+                }
+                catch (Exception ex)
+                {
+
+                    LogHelper.Info("Plc交互出错");
+                }
             }
-           // Image = ( ICogImage ) cogToolBlock.Outputs[ 6 ].Value;
+            await Task.CompletedTask;
+
+        }
+
+        /// <summary>
+        /// 相机连接或者断开时
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="state"></param>
+        public void CameraConnectChangedEvent(Guid id, bool state)
+        {
+            IsConnected = state;
         }
 
 
+       
 
     }
 

+ 11 - 0
Interfaces/ICamera.cs

@@ -87,6 +87,8 @@ namespace LampInspectionMachine.Interfaces
         /// </summary>
         void StartGrabbing();
 
+        void StartTriggerGrabbing();
+
         /// <summary>
         /// 停止实时采集图像
         /// </summary>
@@ -164,5 +166,14 @@ namespace LampInspectionMachine.Interfaces
         /// 相机连接状态变更时
         /// </summary>
         event Action<Guid, bool> CameraConnectChangedEvent;
+
+       bool CheckGrabImageCallbackEventIsHas(Action<ICogImage>  action);
+
+
+       bool CheckImageCallbackEventIsHas(Action<ICogImage, TimeSpan, string> action);
+
+
+
+        bool CheckCameraConnectChangedEventIsHas(Action<Guid, bool> action);
     }
 }

+ 71 - 38
KHLPLC/KHLCommunicate.cs

@@ -7,6 +7,7 @@ using KHST = LampInspectionMachine.KHLplc.KvStruct;
 using System.Threading.Tasks;
 using LampInspectionMachine.Log4xml;
 using System.Windows.Controls;
+using System.Threading;
 
 namespace LampInspectionMachine.KHLplc
 {
@@ -15,38 +16,56 @@ namespace LampInspectionMachine.KHLplc
         byte[] readBuf = new byte[2048];
         byte[] writeBuf = new byte[2048];
         private bool  isConnected=false;
-        private bool  isNormal=false;
         private int sock=0;
+       
 
         public bool IsConnected { get => isConnected; set => isConnected = value; }
-        public bool IsNormal { get => isNormal; set => isNormal =  value ; }
 
-        public bool ConnPlc()
+
+
+        public KHLCommunicate() 
         {
-            int err = 0;
-            err = KHL.KHLInit();
-            if ( err != 0 )
-            {
-                LogHelper.Info("plc连接初始化错误:" + err);
-                IsConnected = false;
-                IsNormal=false;
-                return false;
-            }
-            err = KHL.KHLConnect("192.168.0.10", 8500, 3000, KHLSockType.SOCK_TCP, ref sock);
-            if ( err != 0 )
+
+            
+
+
+        }
+        public async Task ConnPlc()
+        {
+            while (true)
             {
-                LogHelper.Info("plc连接错误:" + err);
-                IsConnected = false;
-                IsNormal = false;
-                return false;
+                int err = 0;
+                err = KHL.KHLInit();
+                if (err != 0)
+                {
+                    LogHelper.Info("plc连接初始化错误:" + err);
+                    IsConnected = false;
+                    Thread.Sleep(1000);
+                    continue;
+                }
+                err = KHL.KHLConnect("192.168.1.10", 8500, 3000, KHLSockType.SOCK_TCP, ref sock);
+                if (err != 0)
+                {
+                    LogHelper.Info("plc连接错误:" + err);
+                    IsConnected = false;
+
+                    Thread.Sleep(1000);
+                    continue;
+                }
+                IsConnected = true;
+
+                LogHelper.Info("plc连接成功");
+
+                break;
             }
-            IsConnected = true;
-            IsNormal = true;
-            LogHelper.Info("plc连接成功");
-            return true;
 
         }
 
+
+
+         
+        
+
         public bool[] ReadBool(uint topno, ushort offset, uint bitnum)
         {
             if ( IsConnected )
@@ -56,9 +75,9 @@ namespace LampInspectionMachine.KHLplc
                 int err = KHL.KHLReadDevicesAsBits(sock, KHLDevType.DEV_EM, topno, offset, bitnum, readBuf);
                 if ( err != 0 )
                 {
-                    IsNormal = false;
+                  
                     LogHelper.Info("plc连接读取错误:" + err);
-                    return rdBool;
+                    throw new Exception("plc连接读取错误");
                 }
 
                 KHST.ByteToBool(ref rdBool, readBuf, rdBool.Length, 0, 0);
@@ -81,9 +100,9 @@ namespace LampInspectionMachine.KHLplc
                 int err = KHL.KHLWriteDevicesAsBits(sock, KHLDevType.DEV_ZF, topno, offset, bitnum, writeBuf);
                 if ( err != 0 )
                 {
-                    IsNormal = false;
+                   
                     LogHelper.Info("plc连接读取错误:" + err);
-                    return false;
+                    throw new Exception("plc连接读取错误");
                 }
                 return true;
             }
@@ -96,9 +115,9 @@ namespace LampInspectionMachine.KHLplc
             int err = KHL.KHLReadDevicesAsWords(sock, KHLDevType.DEV_EM, topno, wordnum, readBuf);
             if ( err != 0 )
             {
-                IsNormal = false;
+               
                 LogHelper.Info("plc连接读取错误:" + err);
-                return rdUshort;
+                throw new Exception("plc连接读取错误");
             }
             KHST.ByteToUshort(ref rdUshort, readBuf, rdUshort.Length, 0);
             return rdUshort;
@@ -111,37 +130,51 @@ namespace LampInspectionMachine.KHLplc
             int err = KHL.KHLWriteDevicesAsWords(sock, KHLDevType.DEV_ZF, topno, wordnum, writeBuf);
             if ( err != 0 )
             {
-                IsNormal = false;
+                
                 LogHelper.Info("plc连接读取错误:" + err);
-                return false;
+                throw new Exception("plc连接读取错误");
             }
             return true;
         }
-
+        public int ReadInt(uint topno)
+        {
+            int[] rdint = new int[1];
+            int err = KHL.KHLReadDevicesAsWords(sock, KHLDevType.DEV_EM, topno, 1, readBuf);
+            if (err != 0)
+            {
+               
+                LogHelper.Info("plc连接读取错误:" + err);
+                throw new Exception("plc连接读取错误");
+            }
+            KHST.ByteToInt(ref rdint, readBuf, rdint.Length, 0);
+            return rdint[0];
+        }
         public int[] ReadInt(uint topno, uint wordnum)
         {
             int[] rdint = new int[wordnum];
             int err = KHL.KHLReadDevicesAsWords(sock, KHLDevType.DEV_EM, topno, wordnum, readBuf);
             if ( err != 0 )
             {
-                IsNormal = false;
+              
                 LogHelper.Info("plc连接读取错误:" + err);
-                return rdint;
+                throw new Exception("plc连接读取错误");
             }
             KHST.ByteToInt(ref rdint, readBuf, rdint.Length, 0);
             return rdint;
         }
 
-        public bool WriteInt(uint topno, uint wordnum)
+
+
+        public bool WriteInt(uint topno, uint wordnum, int[] rdInt)
         {
-            ushort[] rdUshort = new ushort[wordnum];
-            KHST.UshortToByte(ref writeBuf, rdUshort, rdUshort.Length, 0);
+            
+            KHST.IntToByte(ref writeBuf, rdInt, rdInt.Length, 0);
             int err = KHL.KHLWriteDevicesAsWords(sock, KHLDevType.DEV_ZF, topno, wordnum, writeBuf);
             if ( err != 0 )
             {
-                IsNormal = false;
+               
                 LogHelper.Info("plc连接读取错误:" + err);
-                return false;
+                throw new Exception("plc连接读取错误");
             }
             return true;
         }

+ 9 - 1
LampInspectionMachine.csproj

@@ -29,6 +29,7 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -215,6 +216,8 @@
     <Compile Include="Cameralibs\CameraService.cs" />
     <Compile Include="Cameralibs\CameraType.cs" />
     <Compile Include="Cameralibs\HKCamera\MvCamera.cs" />
+    <Compile Include="Core\FileHelper.cs" />
+    <Compile Include="Core\FilePath.cs" />
     <Compile Include="Interfaces\ICamera.cs" />
     <Compile Include="Core\Management.cs" />
     <Compile Include="Core\TipService.cs" />
@@ -227,8 +230,11 @@
     <Compile Include="Log4xml\LogHelper.cs" />
     <Compile Include="Model\AppData.cs" />
     <Compile Include="Model\CameraInfo.cs" />
+    <Compile Include="Model\PlcData.cs" />
     <Compile Include="Model\ProjectData.cs" />
+    <Compile Include="Model\ShowRender.cs" />
     <Compile Include="Model\Users.cs" />
+    <Compile Include="ValueConverters\BoolToColorConverter.cs" />
     <Compile Include="ValueConverters\EnumToBoolConverter.cs" />
     <Compile Include="ViewModels\CameraViewModel.cs" />
     <Compile Include="ViewModels\MainWindowViewModel.cs" />
@@ -284,7 +290,9 @@
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
     </EmbeddedResource>
-    <None Include="Log4xml\log4net.config" />
+    <None Include="Log4xml\log4net.config">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
     <None Include="packages.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>

+ 31 - 0
Log4xml/LogHelper.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Linq;
 
 
 namespace LampInspectionMachine.Log4xml
@@ -8,6 +9,9 @@ namespace LampInspectionMachine.Log4xml
         public delegate void LogChangHandler(Log log);
 
         public static LogChangHandler logChangHandler;
+
+        
+
         // #region 执行日志
         private static readonly log4net.ILog infologger = log4net.LogManager.GetLogger("LogInfo");
         /// <summary>
@@ -23,6 +27,26 @@ namespace LampInspectionMachine.Log4xml
                 logChangHandler?.Invoke(new Log() { Time = DateTime.Now.ToString("yyyy-MM-dd:HH:mm:ss"), Msg = message });
             }
         }
+
+
+
+        // #region 执行日志
+        private static readonly log4net.ILog camerainfologger = log4net.LogManager.GetLogger("CameraLogInfo");
+        /// <summary>
+        /// 相机日志
+        /// </summary>
+        /// <param name="message">日志内容</param>
+        public static void CameraInfo(string message)
+        {
+            // 可以改成type typeof(类)
+            if (camerainfologger.IsInfoEnabled)
+            {
+                camerainfologger.Info(message);
+                logChangHandler?.Invoke(new Log() { Time = DateTime.Now.ToString("yyyy-MM-dd:HH:mm:ss"), Msg = message });
+            }
+        }
+
+
         private static log4net.ILog alarmlog4net =log4net.LogManager.GetLogger("AlarmLogInfo");
         /// <summary>
         /// 警告日志
@@ -52,6 +76,13 @@ namespace LampInspectionMachine.Log4xml
 
         }
 
+        public static bool CheckLogChangHandler(LogChangHandler handler) 
+        {
+            return logChangHandler.GetInvocationList().Contains(handler);
+
+
+        }
+
 
     }
 

+ 29 - 0
Log4xml/log4net.config

@@ -27,6 +27,30 @@
 				</layout>
 			</appender>
 
+
+			<!-- Agv日志文件-->
+			<appender name="CameraInfoFileAppender" type="log4net.Appender.RollingFileAppender">
+				<!-- RollingFileAppender以FileAppender为基础 -->
+				<File value="Log\CameraInfoLog" />
+				<!--<file value="${TMP}\LOGS\" /> tmp为环境变量里的路径值,未配置环境变量地址就生成在temp中,log-file.txt为文件名 -->
+				<param name="AppendToFile" value="true" />
+				<!-- 指定是追加到还是覆盖掉已有的日志文件 -->
+				<!--<lockingModel type="log4net.Appender.FileAppender+InterProcessLock" />-->
+				<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
+				<!-- 启用最小锁定格式以允许多个进程可以写入同一个文件-->
+				<param name="RollingStyle" value="Composite" />
+				<!--按照何种方式产生多个日志文件(指明文件名是变动的,日期[Date],文件大小[Size],混合[Composite])-->
+				<StaticLogFileName value="false" />
+				<DatePattern value="yyyy\\MM\\dd\\yyyy-MM-dd'.txt'" />
+				<MaxSizeRollBackups value="-1" />
+				<!-- 最多个数为-1无限个-->
+				<MaximumFileSize value="2MB" />
+				<layout type="log4net.Layout.PatternLayout">
+					<conversionPattern value="时间:%date___描述:%message%newline" />
+
+				</layout>
+			</appender>
+
 			<!-- 报警日志文件 -->
 			<appender name="AlarmInfoFileAppender" type="log4net.Appender.RollingFileAppender">
 				<!-- RollingFileAppender以FileAppender为基础 -->
@@ -77,6 +101,11 @@
 				<appender-ref ref="InfoFileAppender" />
 			</logger>
 
+			<logger name="CameraLogInfo">
+				<level value="INFO" />
+				<appender-ref ref="CameraInfoFileAppender" />
+			</logger>
+			
 			<logger name="AlarmLogInfo">
 				<level value="WARN" />
 				<appender-ref ref="AlarmInfoFileAppender" />

+ 2 - 1
Model/CameraInfo.cs

@@ -47,7 +47,8 @@ namespace LampInspectionMachine.Model
 
         private int _VppIndex=0;
 
-        public bool TriggerMode { get => triggerMode; set { SetProperty(ref triggerMode, value); } }
+        public bool TriggerMode { get => triggerMode; 
+            set { SetProperty(ref triggerMode, value); } }
         public TriggerSource TriggeSource { get => triggeSource; set { SetProperty(ref triggeSource, value); } }
         public TriggerPolarity TriggerPolarity { get => triggerPolarity; set { SetProperty(ref triggerPolarity, value); } }
         public ulong ExpouseTime { get => expouseTime; set { SetProperty(ref expouseTime, value); } }

+ 49 - 0
Model/PlcData.cs

@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace LampInspectionMachine.Model
+{
+    public class PlcData
+    {
+
+        public PlcData()
+        {
+        
+        
+        }
+
+
+
+
+        private uint _PlcToPcCodeIndex = 100;
+        /// <summary>
+        /// plc 给产品编码
+        /// </summary>
+        public uint PlcToPcCodeIndex { get => _PlcToPcCodeIndex; set => _PlcToPcCodeIndex = value; }
+
+
+        private uint _PcToPlcCodeIndex = 100;
+        /// <summary>
+        /// plc 给产品编码
+        /// </summary>
+        public uint PcToPlcCodeIndex { get => _PcToPlcCodeIndex; set => _PcToPlcCodeIndex = value; }
+
+        private uint _PcToPlcResult = 100;
+        /// <summary>
+        /// Pc回复 产品拍照结果
+        /// </summary>
+        public uint PcToPlcResult { get => _PcToPlcResult; set => _PcToPlcResult = value; }
+
+
+        private uint _PcToPlcCompleted =100;
+        /// <summary>
+        /// Pc回复 完成
+        /// </summary>
+        public uint PcToPlcCompleted { get => _PcToPlcCompleted; set => _PcToPlcCompleted = value; }
+
+    }
+}

+ 119 - 0
Model/ShowRender.cs

@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Prism.Mvvm;
+
+namespace LampInspectionMachine.Model
+{
+    public class ShowRender : BindableBase
+    {
+        private Guid _id;
+
+        public Guid Id
+        {
+            get { return _id; }
+            set { SetProperty(ref _id, value); }
+        }
+
+        private string _CameraName;
+
+        public string CameraName
+        {
+            get { return _CameraName; }
+            set { SetProperty(ref _CameraName, value); }
+        }
+
+        private Cognex.VisionPro.ICogImage _Image;
+
+        public Cognex.VisionPro.ICogImage Image
+        {
+            get { return _Image; }
+            set { SetProperty(ref _Image, value); }
+        }
+
+
+        private Cognex.VisionPro.CogGraphicCollection _Graphic;
+
+        public Cognex.VisionPro.CogGraphicCollection Graphic
+        {
+            get { return _Graphic; }
+            set { SetProperty(ref _Graphic, value); }
+        }
+
+        private Cognex.VisionPro.ICogRecord _Record;
+
+        public Cognex.VisionPro.ICogRecord Record
+        {
+            get { return _Record; }
+            set { SetProperty(ref _Record, value); }
+        }
+
+        private bool _result;
+
+        public bool Result
+        {
+            get { return _result; }
+            set { SetProperty(ref _result, value); }
+        }
+
+        private bool _IsShow;
+
+        public bool IsShow
+        {
+            get { return _IsShow; }
+            set { SetProperty(ref _IsShow, value); }
+        }
+
+        private bool _IsSaveImage;
+        /// <summary>
+        /// 保存图像
+        /// </summary>
+        public bool IsSaveImage
+        {
+            get { return _IsSaveImage; }
+            set { SetProperty(ref _IsSaveImage, value); }
+        }
+
+        //private ProcedureSaveImageModel _SaveImageModel;
+        ///// <summary>
+        ///// 存图模式
+        ///// </summary>
+        //public ProcedureSaveImageModel SaveImageModel
+        //{
+        //    get { return _SaveImageModel; }
+        //    set { SetProperty(ref _SaveImageModel, value); }
+        //}
+
+        //private ProcedureSaveImagePathModel _SaveImagePathModel;
+        ///// <summary>
+        ///// 存图路径模式
+        ///// </summary>
+        //public ProcedureSaveImagePathModel SaveImagePathModel
+        //{
+        //    get { return _SaveImagePathModel; }
+        //    set { SetProperty(ref _SaveImagePathModel, value); }
+        //}
+
+        private string _SavePath;
+        /// <summary>
+        /// 存图路径
+        /// </summary>
+        public string SavePath
+        {
+            get { return _SavePath; }
+            set { SetProperty(ref _SavePath, value); }
+        }
+
+        private bool _IsCompress;
+        /// <summary>
+        /// 是否压缩图片
+        /// </summary>
+        public bool IsCompress
+        {
+            get { return _IsCompress; }
+            set { SetProperty(ref _IsCompress, value); }
+        }
+    }
+}

+ 2 - 0
Properties/AssemblyInfo.cs

@@ -51,3 +51,5 @@ using System.Windows;
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("1.0.0.0")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4xml/log4net.config", ConfigFileExtension = "config", Watch = true)]
+

+ 32 - 0
ValueConverters/BoolToColorConverter.cs

@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace LampInspectionMachine.ValueConverters
+{
+    public class BoolToColorConverter : IValueConverter
+    {
+         
+
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if(value==null) return new SolidColorBrush(Colors.Red);
+            if ( ( bool ) value ) 
+            {
+
+                return new SolidColorBrush(Colors.Green);
+            }
+            return new SolidColorBrush(Colors.Red);
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 165 - 32
ViewModels/CameraViewModel.cs

@@ -21,6 +21,9 @@ using System.Threading;
 using System.Windows.Interop;
 using LampInspectionMachine.Model;
 using System.Globalization;
+using LampInspectionMachine.Log4xml;
+using System.Collections.ObjectModel;
+using SqlSugar;
 
 namespace LampInspectionMachine.ViewModels
 {
@@ -30,13 +33,23 @@ namespace LampInspectionMachine.ViewModels
         private Management management;
         private int index;
 
+        public int Index { get => index; set { index = value; CanmeraName = "相机" + (index + 1); } }
+        
+        private string _CanmeraName = "";
+        public string CanmeraName { get => _CanmeraName; set { SetProperty(ref _CanmeraName, value); } }
+
         public Management Management { get => management; set { SetProperty(ref management, value); } }
 
+
+        private ObservableCollection<string> _Logs = new ObservableCollection<string>();
+        public ObservableCollection<string> Logs { get => _Logs; set => _Logs = value; }
+
         public CameraViewModel(IContainerProvider container, IRegionManager regionManager, IEventAggregator eventAggregator)
         {
             _container = container;
             Management = _container.Resolve<Management>();
-
+            if(!LogHelper.CheckLogChangHandler(ShowLog))
+            LogHelper.logChangHandler += ShowLog;
         }
 
 
@@ -56,6 +69,26 @@ namespace LampInspectionMachine.ViewModels
             _SoftTrigger_ContinueCommand ?? ( _SoftTrigger_ContinueCommand = new DelegateCommand(OnSoftTrigger__Continue) );
 
 
+
+        private DelegateCommand _ImageTriggerCommand;
+        /// <summary>
+        /// 开始采集
+        /// </summary>
+        public DelegateCommand ImageTriggerCommand =>
+            _ImageTriggerCommand ?? ( _ImageTriggerCommand = new DelegateCommand(OnImageTrigger) );
+
+
+        private DelegateCommand _ImageTrigger_ContinueCommand;
+        /// <summary>
+        /// 开始采集
+        /// </summary>
+        public DelegateCommand ImageTrigger_ContinueCommand =>
+            _ImageTrigger_ContinueCommand ?? ( _ImageTrigger_ContinueCommand = new DelegateCommand(OnImageTrigger__Continue) );
+
+
+
+
+
         private DelegateCommand _CameraInifCommand;
         /// <summary>
         /// 相机初始化
@@ -73,23 +106,93 @@ namespace LampInspectionMachine.ViewModels
 
 
 
+        private void ShowLog(Log4xml.Log log)
+        {
+            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
+            {
+                string str = log.Msg.Trim();
+                while (true)
+                {
+                    if (str.Length > 60)
+                    {
+                        Logs.Add(str.Substring(0, 60));
+                        str = log.Time + " " + str.Substring(60);
+                    }
+                    else
+                    {
+                        Logs.Add(str);
+                        break;
+                    }
+                }
+                if (Logs.Count > 100)
+                {
+                    Logs.RemoveAt(0);
+                }
+            }));
+
+        }
+
 
         private void OnSoftTrigger()
         {
-            
-            
-            Management.SoftTrigger();
+            try
+            {
+                Management.SoftTrigger();
+            }
+            catch
+            {
+                MessageBox.Show("手动单张采集出错");
+            }
         }
         private void OnSoftTrigger__Continue()
         {
-            Management.SoftTrigger__Continue();
+            try
+            {
+                Management.SoftTrigger__Continue();
+            }
+            catch
+            {
+                MessageBox.Show("开始采集出错");
+            }
         }
 
-
+        private void OnImageTrigger()
+        {
+            try
+            {
+                Management.ImageTrigger();
+            }
+            catch
+            {
+                MessageBox.Show("单张图片出错");
+            }
+        }
+        private void OnImageTrigger__Continue()
+        {
+            try
+            {
+                Management.ImageTrigger__Continue();
+            }
+            catch
+            {
+                MessageBox.Show("图片轮询出错");
+            }
+        }
         private void OnCameraInit()
         {
-
-            Management.InitCamera();
+            try
+            {
+                if ( Management.InitCamera() )
+                {
+                    LogHelper.Info("初始化完成");
+                    Management.CamConfigs[Index] = Management.CurrCamConfig;
+                    Management.SaveCameraDevice();
+                }
+            }
+            catch 
+            {
+                MessageBox.Show("相机初始化出错");
+            }
 
         }
         /// <summary>
@@ -99,34 +202,62 @@ namespace LampInspectionMachine.ViewModels
         /// <exception cref="NotImplementedException"></exception>
         public void OnNavigatedTo(NavigationContext navigationContext)
         {
-            if ( navigationContext.Parameters.ContainsKey("Index") )
+
+            try
             {
-                 index= Convert.ToInt32(navigationContext.Parameters.GetValue<string>("Index"));
-                if ( Management.VisionProManagers!=null )
+                if ( navigationContext.Parameters.ContainsKey("Index") )
                 {
-                    if ( index < Management.VisionProManagers.Count )
+                    Index = Convert.ToInt32(navigationContext.Parameters.GetValue<string>("Index"));
+                    if ( Management.VisionProManagers != null )
                     {
-                        Management.CurrCamera = Management.VisionProManagers[ index ].Camera;
-                        Management.CurrCamConfig = Management.VisionProManagers[ index ].CameraInfo;
-                        Management.CurrCameraSn = Management.CurrCamConfig.SerialNumber;
-                        Management.Currvision=Management.VisionProManagers[ index ];
+                        if ( Index < Management.VisionProManagers.Count )
+                        {
+                            if (Management.CurrCamera!=null&&Management.CurrCamera.IsGrabbing) 
+                            {
+                                Management.CurrCamera.StopGrabbing();
+                            }
+                            Management.CurrCamera = Management.VisionProManagers[ Index ].Camera;
+                            Management.CurrCamConfig = Management.VisionProManagers[ Index ].CameraInfo.Copy();
+                            Management.CurrCameraSn = Management.CurrCamConfig.SerialNumber;
+                            Management.Currvision = Management.VisionProManagers[ Index ];
+                        }
                     }
                 }
+
+                if (!LogHelper.CheckLogChangHandler(ShowLog))
+                    LogHelper.logChangHandler += ShowLog;
+
+            }
+            catch
+            {
+                MessageBox.Show("切换视觉界面出错");
             }
+        
         }
         private void OnCameraClose()
         {
 
-
-            Management.CloseCamera();
+            try
+            {
+                Management.CloseCamera();
+            }
+            catch 
+            {
+                MessageBox.Show("相机出错");
+            }
         }
 
         public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
         {
             if ( Management.CurrCamConfig != null )
             {
-                Management.CurrCamConfig.SerialNumber = Management.CurrCameraSn;   
+                Management.VisionProManagers[Index].Camera= Management.CurrCamera;
+                Management.CurrCamConfig.SerialNumber = Management.CurrCameraSn;
+                Management.VisionProManagers[Index].CameraInfo = Management.CurrCamConfig.Copy();
+
             }
+            if (!LogHelper.CheckLogChangHandler(ShowLog))
+                LogHelper.logChangHandler -= ShowLog;
             continuationCallback(true);
         }
 
@@ -147,7 +278,7 @@ namespace LampInspectionMachine.ViewModels
         public static readonly DependencyProperty ImageSourceProperty =
         DependencyProperty.RegisterAttached(
             "ImageSource",
-            typeof(ICogImage),
+            typeof(ShowRender),
             typeof(CogDisplayBinder),
             new FrameworkPropertyMetadata(
                 null,
@@ -155,10 +286,10 @@ namespace LampInspectionMachine.ViewModels
                 OnImageSourceChanged));
 
 
-        public static ICogImage GetImageSource(WindowsFormsHost host) =>
-            ( ICogImage ) host.GetValue(ImageSourceProperty);
+        public static ShowRender GetImageSource(WindowsFormsHost host) =>
+            (ShowRender) host.GetValue(ImageSourceProperty);
 
-        public static void SetImageSource(WindowsFormsHost host, ICogImage value) =>
+        public static void SetImageSource(WindowsFormsHost host, ShowRender value) =>
             host.SetValue(ImageSourceProperty, value);
 
         public static void OnImageSourceChanged(
@@ -168,28 +299,30 @@ namespace LampInspectionMachine.ViewModels
             if ( d is WindowsFormsHost host &&
                 host.Child is CogRecordDisplay display )
             {
-                if ( e.NewValue is ICogImage newImage )
+                if ( e.NewValue is ShowRender newRender )
                 {
-
                     // 跨线程安全更新
                     host.Dispatcher.Invoke(() =>
                     {
-
                         try
                         {
-                            display.Image = newImage;
+                            display.Image = newRender.Image;
+                            display.StaticGraphics.Clear();
+                            if (newRender.Graphic != null)
+                                display.StaticGraphics.AddList(newRender.Graphic, "");
+                            if (newRender.Record != null)
+                                display.Record = newRender.Record;
+                            if (newRender.IsSaveImage)
+                            {
+                              //  SaveImage(newRender.SaveImageModel, newRender.SaveImagePathModel, render.SavePath, render.Image, (Bitmap)((Cognex.VisionPro.CogRecordDisplay)item.Value.Child).CreateContentBitmap(Cognex.VisionPro.Display.CogDisplayContentBitmapConstants.Custom), render.Result, render.IsCompress);
+                            }
                             display.Fit(true);
                         }
                         catch
                         {
 
                         }
-
-
-
                     });
-
-
                 }
                 else
                 {

+ 6 - 5
ViewModels/MainWindowViewModel.cs

@@ -15,6 +15,7 @@ using LampInspectionMachine.Model;
 using LampInspectionMachine.Core;
 using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;
 using System.Windows.Interop;
+using LampInspectionMachine.Log4xml;
 
 namespace LampInspectionMachine.ViewModels
 {
@@ -39,8 +40,6 @@ namespace LampInspectionMachine.ViewModels
             _regionManager = regionManager;
             _appData = _container.Resolve<AppData>();
             management = _container.Resolve<Management>();
-            management.LoadCameraDevice();
-
             LoadedCommand = new DelegateCommand(OnLoad);
             ClosedCommand = new DelegateCommand(OnClose);
         }
@@ -65,11 +64,11 @@ namespace LampInspectionMachine.ViewModels
 
 
 
-        private  void OnLoad()
+        private  async void OnLoad()
         {
 
-            TipService tipService = new TipService();
-            Task.Run(() => { management.InitTemplates(tipService,management); });
+          
+            _regionManager.Regions[ "RegionContent" ].RequestNavigate("WorkRunView");
         }
 
         private void OnClose()
@@ -81,6 +80,7 @@ namespace LampInspectionMachine.ViewModels
 
         void MenuViewShow()
         {
+            LogHelper.Info("切换相机调试");
             _regionManager.Regions[ "RegionContent" ].RequestNavigate("MenuView");
 
         }
@@ -93,6 +93,7 @@ namespace LampInspectionMachine.ViewModels
 
         void WorkRunViewShow()
         {
+            LogHelper.Info("切换运行界面");
             _regionManager.Regions[ "RegionContent" ].RequestNavigate("WorkRunView");
         }
 

+ 40 - 6
ViewModels/MenuViewModel.cs

@@ -9,14 +9,18 @@ using Prism.Events;
 using Prism.Ioc;
 using Prism.Regions;
 using System.Windows.Controls;
+using LampInspectionMachine.Core;
+using OpenCvSharp.Flann;
+using System.Windows.Forms;
 
 namespace LampInspectionMachine.ViewModels
 {
-    public  class MenuViewModel:BindableBase 
+    public  class MenuViewModel:BindableBase, IConfirmNavigationRequest
     {
         private IContainerProvider _container;
         private IEventAggregator _eventAggregator;
         private IRegionManager _regionManager;
+        private Management management;
 
 
         private DelegateCommand<string> _OpenCameraViewCommand;
@@ -28,25 +32,36 @@ namespace LampInspectionMachine.ViewModels
         public DelegateCommand<string> OpenVisionProViewCommand =>
             _OpenVisionProViewCommand ?? ( _OpenVisionProViewCommand = new DelegateCommand<string>(VisionProViewShow) );
 
+        public DelegateCommand LoadedCommand { get; set; }
+        public Management Management { get => management; set { SetProperty(ref management, value); } }
 
+        private bool IsLoad=false;
   
 
-
-
         public MenuViewModel(IContainerProvider container, IRegionManager regionManager, IEventAggregator eventAggregator) 
         {
             _container = container;
             _eventAggregator = eventAggregator;
             _regionManager = regionManager;
+            Management=container.Resolve<Management>(); 
+            LoadedCommand = new DelegateCommand(OnLoad);
         }
 
 
 
+        private async void OnLoad()
+        {
 
+            NavigationParameters paras = new NavigationParameters();
+            paras.Add("Index",0); //键值对
+            _regionManager.Regions[ "MenuRegionContent" ].RequestNavigate("CameraView", paras);
+            IsLoad = true;
+         
+        }
 
         void CameraViewShow(string index)
         {
-
+            
             NavigationParameters paras = new NavigationParameters();
             paras.Add("Index", Convert.ToInt32(index)); //键值对
             _regionManager.Regions[ "MenuRegionContent" ].RequestNavigate("CameraView", paras);
@@ -57,8 +72,27 @@ namespace LampInspectionMachine.ViewModels
             paras.Add("Index", Convert.ToInt32(index)); //键值对
             _regionManager.Regions[ "MenuRegionContent" ].RequestNavigate("VisionProView", paras);
         }
-       
 
-     
+        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
+        {
+            
+            continuationCallback(IsLoad);
+        }
+
+        public void OnNavigatedTo(NavigationContext navigationContext)
+        {
+           
+        }
+
+        public bool IsNavigationTarget(NavigationContext navigationContext)
+        {
+            return true;
+        }
+
+        public void OnNavigatedFrom(NavigationContext navigationContext)
+        {
+
+
+        }
     }
 }

+ 16 - 1
ViewModels/VisionProViewModel.cs

@@ -14,6 +14,7 @@ using System.Windows.Forms.Integration;
 using System.Windows;
 using Cognex.VisionPro.ToolGroup;
 using OpenCvSharp.Flann;
+using Prism.Commands;
 
 namespace LampInspectionMachine.ViewModels
 {
@@ -21,6 +22,13 @@ namespace LampInspectionMachine.ViewModels
     {
         private CogToolBlock _TcogToolBlock;
         private Management management;
+
+        private DelegateCommand _SoftTriggerCommand;
+        /// <summary>
+        /// 开始采集
+        /// </summary>
+        public DelegateCommand SoftTriggerCommand =>
+            _SoftTriggerCommand ?? ( _SoftTriggerCommand = new DelegateCommand(RunCurrVisionCogToolBlock) );
         public VisionProViewModel(IContainerProvider container, IRegionManager regionManager, IEventAggregator eventAggregato) 
         {
             management= container.Resolve<Management>();
@@ -35,12 +43,15 @@ namespace LampInspectionMachine.ViewModels
 
         public bool IsNavigationTarget(NavigationContext navigationContext)
         {
+           
             return true;
         }
 
         public void OnNavigatedFrom(NavigationContext navigationContext)
         {
            
+                management.OnSaveSwitchToolBlock(management.CurrIndex);
+            
         }
 
         public void OnNavigatedTo(NavigationContext navigationContext)
@@ -50,6 +61,10 @@ namespace LampInspectionMachine.ViewModels
                 management.OnSwitchToolBlock(Convert.ToInt32(navigationContext.Parameters.GetValue<string>("Index")));
             }
         }
-
+        public void RunCurrVisionCogToolBlock() 
+        {
+            management.SoftTrigger();
+            management.Currvision.CogToolBlock.Run();
+        }
     }
 }

+ 113 - 10
ViewModels/WorkRunViewModel.cs

@@ -19,35 +19,86 @@ using Newtonsoft.Json;
 
 using System.Collections.ObjectModel;
 using LampInspectionMachine.Views;
+using Microsoft.Xaml.Behaviors;
+using System.Collections.Specialized;
+using System.Windows.Controls;
+using LampInspectionMachine.Core;
+using Prism.Commands;
+using MvCamCtrl.NET;
 
 namespace LampInspectionMachine.ViewModels
 {
-    public class WorkRunViewModel:BindableBase, INavigationAware
+    public class WorkRunViewModel : BindableBase, INavigationAware
     {
         private AppData _appData;
         private IContainerProvider _container;
         private IEventAggregator _eventAggregator;
         private IRegionManager _regionManager;
+        private Management management;
 
         private Stopwatch[]IOChecksTime=new Stopwatch[50];
         private string CheckOrderCode=string.Empty;
+
+        private ObservableCollection<string> _Logs = new ObservableCollection<string>();
+        public ObservableCollection<string> Logs { get => _Logs; set => _Logs = value; }
+
         
+      
 
+        public DelegateCommand LoadedCommand { get; set; }
+        public Management Management { get => management; set { SetProperty(ref management, value); } }
+
+        private bool IsLoad=false;
 
-        //运行线程
-        private Thread  WorkThread;
         public WorkRunViewModel(IContainerProvider container, IRegionManager regionManager, IEventAggregator eventAggregator)
         {
             _container = container;
             _eventAggregator = eventAggregator;
             _regionManager = regionManager;
             _appData = _container.Resolve<AppData>();
-         
-
+            Management = _container.Resolve<Management>();
+            LogHelper.logChangHandler += ShowLog;
+            LoadedCommand = new DelegateCommand(OnLoad);
+        }
 
+        private async void OnLoad()
+        {
+            if ( !IsLoad )
+            {
+                LogHelper.Info("程序启动");
+                management.LoadCameraDevice();
+                management.ConnectPlc();
+                TipService tipService = new TipService();
+                await Task.Run(() => { Management.InitTemplates(tipService, Management); });
+            }
+            IsLoad = true;
+           
         }
+        private void ShowLog(Log4xml.Log log)
+        {
+            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
+            {
+                string str = log.Msg.Trim();
+                while ( true )
+                {
+                    if ( str.Length > 60 )
+                    {
+                        Logs.Add(str.Substring(0, 60));
+                        str = log.Time + " " + str.Substring(60);
+                    }
+                    else
+                    {
+                        Logs.Add(str);
+                        break;
+                    }
+                }
+                if ( Logs.Count > 100 )
+                {
+                    Logs.RemoveAt(0);
+                }
+            }));
 
-        
+        }
 
         public bool IsNavigationTarget(NavigationContext navigationContext)
         {
@@ -62,16 +113,68 @@ namespace LampInspectionMachine.ViewModels
         public void OnNavigatedTo(NavigationContext navigationContext)
         {
             //继续运行
+            for ( int i = 0; i < Management.VisionProManagers.Count; i++ )
+            {
+                if ( Management.VisionProManagers[ i ].Camera != null&& Management.VisionProManagers[ i ].Camera.IsConnected)
+                {
+                    if ( !Management.VisionProManagers[ i ].Camera.IsGrabbing )
+                    {
+                        Management.VisionProManagers[ i ].Camera.SetTriggerMode(true, 0);
+                        Management.VisionProManagers[ i ].CameraInfo.TriggerMode = true;
+                        management.VisionProManagers[ i ].Camera.StartTriggerGrabbing();
+                    }
+                    if ( Management.VisionProManagers[ i ].Camera.CheckImageCallbackEventIsHas(Management.VisionProManagers[ i ].CamCallBack) )
+                    {
+                        Management.VisionProManagers[ i ].Camera.ImageCallbackEvent -= Management.VisionProManagers[ i ].CamCallBack;
+                    }
+                }
+            }
+
         }
 
-     
 
 
-       
 
 
 
-        
-        
+
+
+
+
+    }
+
+    public class AutoScrollBehavior : Behavior<ListBox>
+    {
+        protected override void OnAttached()
+        {
+            base.OnAttached();
+            var items = AssociatedObject.Items;
+            if ( items is INotifyCollectionChanged incc )
+            {
+                incc.CollectionChanged += OnCollectionChanged;
+            }
+        }
+
+        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+        {
+            if ( e.Action == NotifyCollectionChangedAction.Add && AssociatedObject.HasItems )
+            {
+                AssociatedObject.Dispatcher.BeginInvoke(new Action(() =>
+                {
+
+                    AssociatedObject.ScrollIntoView(AssociatedObject.Items[ AssociatedObject.Items.Count - 1 ]);
+                }));
+
+            }
+        }
+
+        protected override void OnDetaching()
+        {
+            if ( AssociatedObject.Items is INotifyCollectionChanged incc )
+            {
+                incc.CollectionChanged -= OnCollectionChanged;
+            }
+            base.OnDetaching();
+        }
     }
 }

+ 120 - 66
Views/CameraView.xaml

@@ -5,6 +5,7 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:local="clr-namespace:LampInspectionMachine.Views"
              xmlns:Viewlocal="clr-namespace:LampInspectionMachine.ViewModels"
+             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
              xmlns:cognexWF1="clr-namespace:Cognex.VisionPro;assembly=Cognex.VisionPro.Controls"
              xmlns:prism="http://prismlibrary.com/"
              xmlns:valueConvert="clr-namespace:LampInspectionMachine.ValueConverters"
@@ -297,150 +298,203 @@
                 <ColumnDefinition Width="*" />
             </Grid.ColumnDefinitions>
             <Grid>
-                <Grid>
-                    <Grid.RowDefinitions>
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                        <RowDefinition Height="Auto" />
-                    </Grid.RowDefinitions>
-                    <StackPanel Grid.Row="0"
+                <StackPanel >
+                    <TextBlock Text="{Binding CanmeraName}" FontSize="20" VerticalAlignment="Center"/>
+                    <Grid>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
+                        </Grid.RowDefinitions>
+                        <StackPanel Grid.Row="0"
                                 Margin="50,15,0,0"
-                                Orientation="Horizontal"
+                                Orientation="Vertical"
                                 VerticalAlignment="Center">
-                        <GroupBox Header="相机">
-                           
-                        <ComboBox x:Name="combox"
+                            <GroupBox Header="相机">
+
+                                <ComboBox x:Name="combox"
                                   Width="190"
                                   Height="30"
                                   SelectedItem="{Binding Management.CurrCameraSn}"
                                   ItemsSource="{Binding Management.CameraList}" />
-                        </GroupBox>
-                    </StackPanel>
-
-
+                            </GroupBox>
+                        </StackPanel>
 
-                    <StackPanel Grid.Row="1"
+                        <StackPanel Grid.Row="1"
                                 Margin="50,5,0,0"
                                 Orientation="Horizontal"
                                 VerticalAlignment="Center">
-                        <GroupBox Header="采集方式">
-                            <StackPanel Orientation="Horizontal">
-                                <RadioButton  Content="软触发"
+                            <GroupBox Header="采集方式">
+                                <StackPanel Orientation="Horizontal">
+                                    <RadioButton  Content="软触发"
                                               IsChecked="{Binding Management.CurrCamConfig.TriggerMode,Converter={StaticResource EnumToBoolConverter},ConverterParameter=软触发}"
                                               GroupName="SoftTrigger"
                                               Margin="10" />
-                                <RadioButton  Content="硬触发"
+                                    <RadioButton  Content="硬触发"
                                               IsChecked="{Binding Management.CurrCamConfig.TriggerMode,Converter={StaticResource EnumToBoolConverter},ConverterParameter=硬触发}"
                                               GroupName="SoftTrigger"
                                               Margin="30,10,40,0" />
-                            </StackPanel>
-                        </GroupBox>
-                    </StackPanel>
+                                </StackPanel>
+                            </GroupBox>
+                        </StackPanel>
 
-                    <StackPanel Grid.Row="2"
+                        <StackPanel Grid.Row="2"
                                 Margin="50,5,0,0"
                                 Orientation="Horizontal"
                                 VerticalAlignment="Center">
-                        <GroupBox Header="曝光">
-                            <StackPanel Orientation="Horizontal">
-                                <TextBox Width="190"/>
-                            </StackPanel>
-                        </GroupBox>
-                    </StackPanel>
+                            <GroupBox Header="曝光">
+                                <StackPanel Orientation="Horizontal">
+                                    <TextBox Width="190"/>
+                                </StackPanel>
+                            </GroupBox>
+                        </StackPanel>
 
-                    <Border Grid.Row="3"
+                        <Border Grid.Row="3"
                             BorderThickness="1"
                             BorderBrush="#e8e8e8"
                             Margin="50,10,0,0"
                             Padding="5">
 
-                        <StackPanel  Orientation="Horizontal"
+                            <StackPanel  Orientation="Horizontal"
                                      VerticalAlignment="Center">
-                            <Border Background="#0A85D9"
+                                <Border Background="#0A85D9"
                                     BorderBrush="Black"
                                     BorderThickness="1"
                                     Margin="10,5,3,5"
                                     CornerRadius="8">
-                                <Button Content="初始化"
+                                    <Button Content="初始化"
                                         Background="Transparent"
                                         Foreground="White"
-                                        Margin="5"
+                                        Margin="2" 
                                         MinWidth="50"
                                         BorderThickness="0"
                                         Command="{Binding CameraInifCommand}" />
 
-                            </Border>
-                            <Border Background="#0A85D9"
+                                </Border>
+                                <Border Background="#0A85D9"
                                     BorderBrush="Black"
                                     BorderThickness="1"
                                     Margin="40,5,3,5"
                                     CornerRadius="8">
-                                <Button Content="关闭"
+                                    <Button Content="关闭"
                                         Background="Transparent"
                                         Foreground="White"
-                                        Margin="5"
+                                        Margin="2"
                                         MinWidth="50"
                                         BorderThickness="0"
                                         Command="{Binding CameraCloseCommand}"
                                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
 
-                            </Border>
-                        </StackPanel>
-                    </Border>
+                                </Border>
+                            </StackPanel>
+                        </Border>
 
-                    <Border Grid.Row="4"
+                        <Border Grid.Row="4"
                             BorderThickness="1"
                             BorderBrush="#e8e8e8"
                             Margin="50,10,0,0"
                             Padding="5">
 
-                        <StackPanel  Orientation="Horizontal"
+                            <StackPanel  Orientation="Horizontal"
                                      VerticalAlignment="Center">
-                            <Border Background="#0A85D9"
+                                <Border Background="#0A85D9"
                                     BorderBrush="Black"
                                     BorderThickness="1"
                                     Margin="10,5,3,5"
                                     CornerRadius="8">
-                                <Button Content="开始采集"
+                                    <Button Content="开始采集"
                                         Background="Transparent"
                                         Foreground="White"
-                                        Margin="5"
+                                        Margin="2"
                                         MinWidth="50"
                                         BorderThickness="0"
                                         Command="{Binding  SoftTrigger_ContinueCommand}"
                                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
-                            </Border>
-                            <Border Background="#0A85D9"
+                                </Border>
+                                <Border Background="#0A85D9"
                                     BorderBrush="Black"
                                     BorderThickness="1"
                                     Margin="40,5,3,5"
                                     CornerRadius="8">
-                                <Button Content="单张采集"
+                                    <Button Content="单张采集"
                                         Background="Transparent"
                                         Foreground="White"
-                                        Margin="5"
+                                        Margin="2"
                                         MinWidth="50"
                                         BorderThickness="0"
                                         Command="{Binding SoftTriggerCommand}" />
 
-                            </Border>
+                                </Border>
 
-                        </StackPanel>
-                    </Border>
+                            </StackPanel>
+                        </Border>
 
-                    
-                </Grid>
-            </Grid>
-            <DockPanel  Grid.Column="1"
-                        Margin="20,20,10,20">
-                <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.Image}">
-                    <cognexWF1:CogRecordDisplay x:Name="cogRecordDisplay" />
-                </WindowsFormsHost>
+                        <Border Grid.Row="5"
+                            BorderThickness="1"
+                            BorderBrush="#e8e8e8"
+                            Margin="50,10,0,0"
+                            Padding="5">
 
-            </DockPanel>
+                            <StackPanel  Orientation="Horizontal"
+                                     VerticalAlignment="Center">
+                                <Border Background="#0A85D9"
+                                    BorderBrush="Black"
+                                    BorderThickness="1"
+                                    Margin="10,5,3,5"
+                                    CornerRadius="8">
+                                    <Button Content="图片轮询"
+                                        Background="Transparent"
+                                        Foreground="White"
+                                        Margin="2"
+                                        MinWidth="50"
+                                        BorderThickness="0"
+                                        Command="{Binding  ImageTrigger_ContinueCommand}"
+                                        CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
+                                </Border>
+                                <Border Background="#0A85D9"
+                                    BorderBrush="Black"
+                                    BorderThickness="1"
+                                    Margin="40,5,3,5"
+                                    CornerRadius="8">
+                                    <Button Content="单张图片"
+                                        Background="Transparent"
+                                        Foreground="White"
+                                        Margin="2"
+                                        MinWidth="50"
+                                        BorderThickness="0"
+                                        Command="{Binding ImageTriggerCommand}" />
+
+                                </Border>
+
+                            </StackPanel>
+                        </Border>
+
+
+                    </Grid>
+                </StackPanel>
+            </Grid>
+            <Grid Grid.Column="1">
+                <Grid.RowDefinitions>
+                    <RowDefinition/>
+                    <RowDefinition Height="180"/>
+                </Grid.RowDefinitions>
+                <DockPanel Margin="20,20,10,20" Grid.Row="0">
+                    <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.Render}">
+                        <cognexWF1:CogRecordDisplay x:Name="cogRecordDisplay" />
+                    </WindowsFormsHost>
+                </DockPanel>
+                <DockPanel  Grid.Row="1">
+                    <ListBox ItemsSource="{Binding Logs}"
+                     BorderBrush="Transparent">
+                        <i:Interaction.Behaviors>
+                            <Viewlocal:AutoScrollBehavior />
+                        </i:Interaction.Behaviors>
+                    </ListBox>
+                </DockPanel>
+            </Grid>
         </Grid>
     </Grid>
 </UserControl>

+ 3 - 3
Views/MainWindow.xaml

@@ -86,14 +86,14 @@
                             VerticalAlignment="Top"
                             Height="65"
                             HorizontalAlignment="Right">
-                    <TextBlock Text="当前时间:"
+                    <!--<TextBlock Text="当前时间:"
                                FontSize="16"
                                Margin="5,5,5,10"
                                VerticalAlignment="Bottom" />
                     <TextBlock Text="2025-10-30"
                                FontSize="16"
                                Margin="0,0,25,10"
-                               VerticalAlignment="Bottom" />
+                               VerticalAlignment="Bottom" />-->
                     <Border Style="{StaticResource buttonborder}">
 
                         <Button Content="权限登录"
@@ -108,7 +108,7 @@
                     </Border>
                     <Border Style="{StaticResource buttonborder}">
 
-                        <Button Content="菜单界面"
+                        <Button Content="视觉界面"
                                 VerticalAlignment="Top"
                                 Padding="5"
                                 BorderBrush="Transparent"

+ 153 - 38
Views/MenuView.xaml

@@ -4,12 +4,19 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:local="clr-namespace:LampInspectionMachine.Views"
+             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
              xmlns:prism="http://prismlibrary.com/"
+             xmlns:valueConvert="clr-namespace:LampInspectionMachine.ValueConverters"
              prism:ViewModelLocator.AutoWireViewModel="True"
              mc:Ignorable="d"
              d:DesignHeight="450"
              d:DesignWidth="800"
              d:Background="White">
+    <b:Interaction.Triggers>
+        <b:EventTrigger EventName="Loaded">
+            <b:InvokeCommandAction Command="{Binding LoadedCommand}" />
+        </b:EventTrigger>
+    </b:Interaction.Triggers>
     <UserControl.Resources>
         <Style x:Key="buttonborder"
                TargetType="Border">
@@ -70,8 +77,9 @@
             <Setter Property="BorderThickness"
                     Value="0" />
         </Style>
+        <valueConvert:BoolToColorConverter x:Key="BoolToColorConverter" />
     </UserControl.Resources>
-   
+
     <Grid>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="Auto" />
@@ -83,7 +91,7 @@
                 CornerRadius="5"
                 BorderBrush="#D4D8DD"
                 BorderThickness="2">
-           <Grid Margin="5">
+            <Grid Margin="5">
                 <Grid>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="40" />
@@ -100,73 +108,180 @@
                             BorderThickness="1"
                             Grid.Row="1">
                         <StackPanel>
-                            <Button Content="相机1"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="0"/>
+                            <StackPanel Orientation="Horizontal">
+                                <Button Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="0" >
+
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机1" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[0].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[0].CameraInfo.SerialNumber}"
+                                           Margin="5"
+                                           VerticalAlignment="Center"
+                                           Background="{Binding Management.VisionProManagers[0].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
-                                    CommandParameter="0"/>
-                            <Button Content="相机2"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="1"/>
+                                    CommandParameter="0" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="1">
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机2" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[1].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[1].CameraInfo.SerialNumber}"
+                                            Margin="5"
+                                            VerticalAlignment="Center"
+                                            Background="{Binding Management.VisionProManagers[1].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
-                                    CommandParameter="1"/>
-                            <Button Content="相机3"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="2" />
+                                    CommandParameter="1" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button 
+                                        Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="2" >
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机3" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[2].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[2].CameraInfo.SerialNumber}"
+                                    Margin="5"
+                                   VerticalAlignment="Center"
+                                    Background="{Binding Management.VisionProManagers[2].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
                                     CommandParameter="2" />
-                            <Button Content="相机4"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="3" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="3">
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机4" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[3].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[3].CameraInfo.SerialNumber}"
+            Margin="5"
+            VerticalAlignment="Center"
+            Background="{Binding Management.VisionProManagers[3].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
                                     CommandParameter="3" />
-                            <Button Content="相机5"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="4" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="4" >
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机5" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[4].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[4].CameraInfo.SerialNumber}"
+            Margin="5"
+            VerticalAlignment="Center"
+            Background="{Binding Management.VisionProManagers[4].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
                                     CommandParameter="4" />
-                            <Button Content="相机6"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="5" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="5" >
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机6" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[5].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[5].CameraInfo.SerialNumber}"
+            Margin="5"
+            VerticalAlignment="Center"
+            Background="{Binding Management.VisionProManagers[5].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
                                     CommandParameter="5" />
-                            <Button Content="相机7"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="6" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button  Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="6" >
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机7" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[6].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[6].CameraInfo.SerialNumber}"
+            Margin="5"
+            VerticalAlignment="Center"
+            Background="{Binding Management.VisionProManagers[6].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
                                     Command="{Binding OpenVisionProViewCommand}"
                                     CommandParameter="6" />
-                            <Button Content="相机8"
-                                    Style="{StaticResource Menubutton}"
-                                    Command="{Binding OpenCameraViewCommand}"
-                                    CommandParameter="7" />
+                            <StackPanel Orientation="Horizontal">
+                                <Button Style="{StaticResource Menubutton}"
+                                        Command="{Binding OpenCameraViewCommand}"
+                                        CommandParameter="7" >
+                                    <StackPanel Orientation="Horizontal">
+                                        <TextBlock Text="相机8" VerticalAlignment="Center"/>
+                                        <TextBlock Text="已连接"
+                                                   Margin="5"
+                                                   VerticalAlignment="Center"
+                                                   Background="{Binding Management.VisionProManagers[7].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                                    </StackPanel>
+                                </Button>
+                                <TextBlock Text="{Binding Management.VisionProManagers[7].CameraInfo.SerialNumber}"
+                                Margin="5"
+                                VerticalAlignment="Center"
+                                Background="{Binding Management.VisionProManagers[7].IsConnected,Converter={StaticResource BoolToColorConverter}}" />
+                            </StackPanel>
                             <Button Content="视觉调试"
                                     Margin="30,0,5,5"
                                     Style="{StaticResource Menubutton}"
@@ -185,7 +300,7 @@
                 BorderThickness="2">
             <ContentControl prism:RegionManager.RegionName="MenuRegionContent" />
         </Border>
-      
+
     </Grid>
-    
+
 </UserControl>

+ 24 - 6
Views/VisionProView.xaml

@@ -9,12 +9,30 @@
              xmlns:Viewlocal="clr-namespace:LampInspectionMachine.ViewModels"
              xmlns:local="clr-namespace:LampInspectionMachine.Views"
              mc:Ignorable="d" 
-             d:DesignHeight="450" d:DesignWidth="800">
+             d:DesignHeight="500" d:DesignWidth="800">
     <Grid>
-        <DockPanel >
-            <WindowsFormsHost>
-                <cognexWF1:CogToolGroupEditV2 x:Name="cogToolBlock" />
-            </WindowsFormsHost>
-        </DockPanel>
+        <StackPanel>
+            <DockPanel>
+                <WindowsFormsHost>
+                    <cognexWF1:CogToolGroupEditV2 x:Name="cogToolBlock" />
+                </WindowsFormsHost>
+            </DockPanel>
+            <Border Background="#0A85D9"
+                    BorderBrush="Black"
+                    BorderThickness="1"
+                    Width="100"
+                    Height="40"
+                    HorizontalAlignment="Left"
+                    Margin="10,5,10,10"
+                    CornerRadius="8">
+                <Button Content="运行流程"
+                        Background="Transparent"
+                        Foreground="White"
+                        Margin="2"
+                        MinWidth="50"
+                        BorderThickness="0"
+                        Command="{Binding  SoftTriggerCommand}" />
+            </Border>
+        </StackPanel>
     </Grid>
 </UserControl>

+ 8 - 0
Views/VisionProView.xaml.cs

@@ -30,11 +30,19 @@ namespace LampInspectionMachine.Views
             InitializeComponent();
             management=container.Resolve<Management>();
             management.ToolBlockSwitched += Management_ToolBlockSwitched;
+            management.ToolBlockCatched += Management_ToolBlockCatch;
         }
 
         private void Management_ToolBlockSwitched(int obj)
         {
+            management.CurrIndex = obj;
             cogToolBlock.Subject = management.VisionProManagers[ obj ].CogToolBlock;
         }
+
+        private void Management_ToolBlockCatch(int obj)
+        {
+            
+            management.VisionProManagers[ obj ].CogToolBlock= ( CogToolBlock ) cogToolBlock.Subject;
+        }
     }
 }

+ 84 - 32
Views/WorkRunView.xaml

@@ -5,50 +5,102 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:local="clr-namespace:LampInspectionMachine.Views"
              xmlns:prism="http://prismlibrary.com/"
+             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
+             xmlns:Viewlocal="clr-namespace:LampInspectionMachine.ViewModels"
+             xmlns:cognexWF1="clr-namespace:Cognex.VisionPro;assembly=Cognex.VisionPro.Controls"
              prism:ViewModelLocator.AutoWireViewModel="True"
              mc:Ignorable="d"
              d:DesignHeight="450"
              d:DesignWidth="1200"
              d:Background="White">
+    <i:Interaction.Triggers>
+        <i:EventTrigger EventName="Loaded">
+            <i:InvokeCommandAction Command="{Binding LoadedCommand}" />
+        </i:EventTrigger>
+    </i:Interaction.Triggers>
     <Grid>
         <Grid.RowDefinitions>
-            <RowDefinition Height="Auto" />
-            <RowDefinition Height="*" />
-            <RowDefinition Height="Auto" />
+            <RowDefinition />
+            <RowDefinition />
+            <RowDefinition />
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
             <ColumnDefinition />
-            <ColumnDefinition Width="Auto" />
+            <ColumnDefinition />
+            <ColumnDefinition />
+            <ColumnDefinition />
         </Grid.ColumnDefinitions>
+        <DockPanel  Grid.Column="0"
+                    Grid.Row="0">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[0].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
+
+        </DockPanel>
+
+        <DockPanel  Grid.Column="1"
+                    Grid.Row="0">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[1].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
+
+        </DockPanel>
+
+        <DockPanel  Grid.Column="2"
+                    Grid.Row="0">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[2].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
+
+        </DockPanel>
+
+        <DockPanel  Grid.Column="0"
+                    Grid.Row="1">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[3].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
+
+        </DockPanel>
+
+        <DockPanel  Grid.Column="1"
+                    Grid.Row="1">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[4].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
+
+        </DockPanel>
+
+        <DockPanel  Grid.Column="2"
+                    Grid.Row="1">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[5].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
+
+        </DockPanel>
+        <DockPanel  Grid.Column="0"
+                    Grid.Row="2">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[6].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
 
-        <Border  Grid.Row="1"
-                 Grid.Column="0"
-                 Margin="5"
-                 BorderBrush="#7AB0F0"
-                 BorderThickness="2"
-                 CornerRadius="5"
-                 Padding="1">
-
-        </Border>
-        <Border  Grid.Row="1"
-                 Grid.Column="1"
-                 CornerRadius="5"
-                 Padding="1">
-            <Grid>
-                <Grid.RowDefinitions>
-                    <RowDefinition Height="Auto" />
-                    <RowDefinition />
-                </Grid.RowDefinitions>
-
-                <Border Grid.Row="1"
-                        Margin="30"
-                        BorderBrush="#7AB0F0"
-                        BorderThickness="2">
-
-                </Border>
-
-            </Grid>
-        </Border>
+        </DockPanel>
+        <DockPanel  Grid.Column="1"
+                    Grid.Row="2">
+            <WindowsFormsHost Viewlocal:CogDisplayBinder.ImageSource="{Binding Management.VisionProManagers[7].Render}">
+                <cognexWF1:CogRecordDisplay />
+            </WindowsFormsHost>
 
+        </DockPanel>
+        <DockPanel  Grid.Column="3"
+                    Grid.RowSpan="3"
+                    Grid.Row="0">
+            <ListBox ItemsSource="{Binding Logs}"
+                     Grid.Row="0"
+                     BorderBrush="Transparent">
+                <i:Interaction.Behaviors>
+                    <Viewlocal:AutoScrollBehavior />
+                </i:Interaction.Behaviors>
+            </ListBox>
+        </DockPanel>
     </Grid>
 </UserControl>