winform 学习笔记


1、数据表格显示

2、窗体透明代码

3、用信号量实现线程的挂起和恢复

4、加载VisionPP

5、VP实现相机外部触发并注册回调

6、显示图片处理过程

7、单个窗口重复使用

8、VP保存图片

9、多线程并行处理——Task类

10、跨线程使用UI控件

11、图表显示数据

12、窗体淡入淡出显示-winform

 13、基于M库访问PLC寄存器

14、串口怎么玩

 15、获取程序当前

1-数据表格显示

DataGridView.ColumnHeadersVisible------指定是否显示列标题行。
DataGridView.RowHeadersVisible-----指定是否显示行标题列。

//增加新的数据并显示          
DataGridViewRow row = new DataGridViewRow(); row.CreateCells(dataGridShowReslut); row.Cells[0].Value = dataGridShowReslut.Rows.Count; row.Cells[1].Value = DateTime.Now.ToShortTimeString(); row.Cells[2].Value = (value).ToString("0.0000"); if (Isok) { row.Cells[3].Style.BackColor = Color.Green; row.Cells[3].Value = "PASS"; } else { row.Cells[3].Style.BackColor = Color.Red; row.Cells[3].Value = "NG"; } dataGridShowReslut.Rows.Add(row);

将显示行 聚焦行定位到最后一行,生产过程中实现表格自动滚动

                 this.dataGridShowReslut.FirstDisplayedScrollingRowIndex = this.dataGridShowReslut.Rows.Count - 1;

2-窗体透明代码

winform窗体透明代码--》

            //this.BackColor = Color.Black;
            //this.TransparencyKey = Color.Black; 窗体透明代码

3、线程挂起和恢复

            ManualResetEvent shoudong = new ManualResetEvent(true);

            shoudong.Set();

            shoudong.Reset();
            while (true)
            {
                /************************
                 * 54
                 * 4645
                 * 54
                 * 564/*/


                shoudong.WaitOne();
            }
通过信号量控制线程启动和暂停

 4-加载VPP

        public static void LoadVisionFile()
        {
            try
            {
                //System.Threading.Tasks.Task.Run(() => { mToolBlock = (CogToolBlock)CogSerializer.LoadObjectFromFile(rConfig.VisionPath+rConfig.VisionName); });
                mToolBlock = (CogToolBlock)CogSerializer.LoadObjectFromFile(rConfig.VisionPath + rConfig.VisionName);
            }
            catch (Exception)
            {
                MessageBox.Show("VPP加载错误");
            }

        }
//加载VPP

public static void SaveToolBlock()
{
CogSerializer.SaveObjectToFile(rVision.mToolBlock, rConfig.VisionPath + rConfig.VisionName);
}

//保存VPP
              CameraTool = (CogAcqFifoTool)cameraToolBlock.Tools[0];
              m_Acqfifo1 = CameraTool.Operator;
              AddHistory("Vpp Load Finished");

5- VPP 实现外部触发 捕捉拍照事件

              CameraTool = (CogAcqFifoTool)cameraToolBlock.Tools[0];
              m_Acqfifo1 = CameraTool.Operator;  //sdawdddddddddd
              AddHistory("Vpp Load Finished");
      public static void Online()
      {
          //m_Acqfifo1.OwnedTriggerParams.TriggerEnabled = false;
          //m_Acqfifo1.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.Auto;
          //m_Acqfifo1.OwnedTriggerParams.TriggerEnabled = true;
          //m_Acqfifo1.TimeoutEnabled = false;

          //m_Acqfifo1.Complete += new Cognex.VisionPro.CogCompleteEventHandler(CameraCallBackFunction);


          TaskDealImage = new Task(TaskDealImageFunction);
          IsTaskAgain = true;
          TaskDealImage.Start();


      }
      public static void OffLine()
      {
          //m_Acqfifo1.OwnedTriggerParams.TriggerEnabled = false;
          //m_Acqfifo1.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.Manual;
          //m_Acqfifo1.OwnedTriggerParams.TriggerEnabled = true;
          //m_Acqfifo1.TimeoutEnabled = false;

          //m_Acqfifo1.Complete -= new Cognex.VisionPro.CogCompleteEventHandler(CameraCallBackFunction);

          IsTaskAgain = false;
          resetEvent.WaitOne();
          MessageBox.Show("线程停止完成");

      }
      public static void CameraCallBackFunction(object sender, CogCompleteEventArgs e)
      {
          try
          {
              int numPendingVal = 0;
              int numReadyVal = 0;
              bool busyVal;
              m_Acqfifo1.GetFifoState(out numPendingVal, out numReadyVal, out busyVal);
              CogAcqInfo info = new CogAcqInfo();
               if (numReadyVal > 0)
               {
                   DealImage = (CogImage8Grey)m_Acqfifo1.CompleteAcquireEx(info);
               }
               IsRecImage = true;
               AddHistory("IsRecImage = true;");
               melsec_net.Write("D1110", 3);
          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.Message);
          }
      }

6-显示处理图片过程

      public static void DisplayDealImage(CogRecordDisplay recordDisplay)
      {
          recordDisplay.Record = measureToolBlock.CreateLastRunRecord().SubRecords[1];
          recordDisplay.Fit();
      }

7- 单个窗口重复使用

      public static void DebugCameraVpp()
      {
          try
          {
              using (FrmInspection1 fi = new FrmInspection1(MeasureVision.cameraToolBlock))
              {
                  fi.ShowDialog();
              }
          }
          catch (Exception)
          {
              MessageBox.Show("取像窗体打开失败!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Warning);
              return;
          }
      }

8- 保存图片

          if (IsSaveImage)
          {
              /*************************保存全图-耗时1.7s************************************/
              MeasureVision.ApperenceImage.ToBitmap().Save(@"D:\SaveImage\SaveImage" + SaveImageCount.ToString().PadLeft(5, '0') + ".png", System.Drawing.Imaging.ImageFormat.Png);
              SaveImageCount++;
          }

9- 多线程并行处理

      /*************************弹片高度检测************************************/
      static Action task1 = new Action(() => {

          Run();
          if (measureToolBlock.RunStatus.Result == CogToolResultConstants.Accept)
          {
              IsHeightOK = (bool)measureToolBlock.Outputs["isok"].Value;
              //get rectangle height   to Test
              recHeight1 = (double)measureToolBlock.Outputs["MeasureValue"].Value;
              recHeight2 = (double)measureToolBlock.Outputs["DistanceMaxHeight"].Value;
              //StreamWriter fwReal = new StreamWriter(System.Environment.CurrentDirectory + "/MeasureData/" + DateTime.Now.ToString("D") + "_RecHeightRealdata.csv", true);
              //fwReal.WriteLine(recHeight2.ToString());
              //fwReal.Close();

          }
          else
          {
              IsHeightOK = false;
              recHeight1 = -1;
              recHeight2 = -1;
              melsec_net.Write("D300", (short)5);
          }
      });
      /*************************弹片卡扣外观检测************************************/
      static int SaveImageCount = 0;
        static int SaveCropImageCount = 0;
      public static bool IsSaveImage = false;
      public static bool IsIgnoreAppearence = true;
      static Action task2 = new Action(() =>
      { 
        /************卡扣外观检测****************/
          IsApperenceOK = true;
          Stopwatch s = new Stopwatch();
          s.Start();
          MeasureVision.GrabApperenceImage();
          if (!IsIgnoreAppearence)
          {
              IsApperenceOK = AppearenceInspection.RunApperenceDetecVpp();
          }

          s.Stop();
          System.Console.WriteLine(s.ElapsedMilliseconds.ToString());
          s.Reset();
          s.Start();
          if (IsSaveImage)
          {
              /*************************保存全图-耗时1.7s************************************/
              MeasureVision.ApperenceImage.ToBitmap().Save(@"D:\SaveImage\SaveImage" + SaveImageCount.ToString().PadLeft(5, '0') + ".png", System.Drawing.Imaging.ImageFormat.Png);
              SaveImageCount++;
          }
          s.Stop();
          System.Console.WriteLine(s.ElapsedMilliseconds.ToString());
          //VisionPro 算法检测出外观NG 则保存裁剪好的图片
          if (!IsApperenceOK)
          {
              AppearenceInspection.CropImage = (CogImage24PlanarColor)AppearenceInspection.ApperenceDetecVpp.Outputs["OutputCropImage"].Value;
              AppearenceInspection.CropImage.ToBitmap().Save(@"D:\SaveImage\SaveCropNGImage" + SaveCropImageCount.ToString().PadLeft(5, '0') + ".png", System.Drawing.Imaging.ImageFormat.Png);
              SaveCropImageCount++;
          }

      });
                  Task task11 = new Task(task1);
                  Task task22 = new Task(task2);
                  task11.Start();
                  task22.Start();

                  Task.WaitAll(task11, task22);

 10- 跨线程使用UI控件:

            if (LBlogbox.InvokeRequired)
            {
                this.Invoke(new Action<string>(LogListBox), str);
            }
            else
            {
                DateTime now = DateTime.Now;
                string fstr = string.Format("{0:T}", now) + "-" + str;
                LBlogbox.Items.Add(fstr);
                LBlogbox.SelectedIndex = LBlogbox.Items.Count - 1;
                if (LBlogbox.Items.Count > 300)
                {
                    LBlogbox.Items.RemoveAt(0);
                }
            }

 11- 图表显示:

            try
            {
                List<int> chartTimeAxis = new List<int>();
                List<double> chartMeasureHeightvalue = new List<double>();
                for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
                {
                    chartTimeAxis.Add(Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value));
                    chartMeasureHeightvalue.Add(Convert.ToDouble(dataGridView1.Rows[i].Cells[2].Value));
                }
                chartMeasureHeight.Series["弹片高度"].Points.DataBindXY(chartTimeAxis, chartMeasureHeightvalue);
            }
            catch (Exception ex)
            {
                InfoWindow.ShowMessage(ex.Message);
            }

 12-窗体淡入淡出显示

       #region 窗体效果
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
        /*  
         * 函数功能:该函数能在显示与隐藏窗口时能产生特殊的效果。有两种类型的动画效果:滚动动画和滑动动画。  
         * 函数原型:BOOL AnimateWindow(HWND hWnd,DWORD dwTime,DWORD dwFlags);  
         * hWnd:指定产生动画的窗口的句柄。  
         * dwTime:指明动画持续的时间(以微秒计),完成一个动画的标准时间为200微秒。  
         * dwFags:指定动画类型。这个参数可以是一个或多个下列标志的组合。  
         * 返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。  
         * 在下列情况下函数将失败:窗口使用了窗口边界;窗口已经可见仍要显示窗口;窗口已经隐藏仍要隐藏窗口。若想获得更多错误信息,请调用GetLastError函数。  
         * 备注:可以将AW_HOR_POSITIVE或AW_HOR_NEGTVE与AW_VER_POSITVE或AW_VER_NEGATIVE组合来激活一个窗口。  
         * 可能需要在该窗口的窗口过程和它的子窗口的窗口过程中处理WM_PRINT或WM_PRINTCLIENT消息。对话框,控制,及共用控制已处理WM_PRINTCLIENT消息,缺省窗口过程也已处理WM_PRINT消息。  
         * 速查:WIDdOWS NT:5.0以上版本:Windows:98以上版本;Windows CE:不支持;头文件:Winuser.h;库文件:user32.lib。  
         */
        //标志描述:    
        const int AW_SLIDE = 0x40000;//使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时,这个标志就被忽略。    
        const int AW_ACTIVATE = 0x20000;//激活窗口。在使用了AW_HIDE标志后不要使用这个标志。    
        const int AW_BLEND = 0x80000;//使用淡出效果。只有当hWnd为顶层窗口的时候才可以使用此标志。    
        const int AW_HIDE = 0x10000;//隐藏窗口,缺省则显示窗口。(关闭窗口用)    
        const int AW_CENTER = 0x0010;//若使用了AW_HIDE标志,则使窗口向内重叠;若未使用AW_HIDE标志,则使窗口向外扩展。    
        const int AW_HOR_POSITIVE = 0x0001;//自左向右显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。    
        const int AW_VER_POSITIVE = 0x0004;//自顶向下显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。    
        const int AW_HOR_NEGATIVE = 0x0002;//自右向左显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。    
        const int AW_VER_NEGATIVE = 0x0008;//自下向上显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。    

        #endregion

        bool ISGradient_;

        /// 
        /// 窗体是否透明,窗体是否淡入淡出
        /// 
        /// 
        /// 
        public FormWelcome(bool IStransparent, bool ISGradient)
        {
            InitializeComponent();
            if (IStransparent)
            {
                this.BackColor = Color.Black;
                this.TransparencyKey = Color.Black;
            }
            ISGradient_ = ISGradient;
            if (ISGradient_)
            {
                AnimateWindow(this.Handle, 500, AW_BLEND); 
            }
        }

        public void ChangeLabelState(string str)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string>(ChangeLabelState), str);
            }
            else 
            {
                labelState.Text = "正在加载:  "+str;
            }
        }

        private void FormWelcome_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (ISGradient_)
            {
                AnimateWindow(this.Handle, 500, AW_HIDE | AW_BLEND); 
            }
        }

 13-基于M库访问PLC寄存器

        /// 
        /// PLC开放的端口号
        /// 
        public static int PlcPort = 888;
        /// 
        /// PLC IP地址
        /// 
        public static string PlcIP = "192.168.0.100";
        /// 
        /// 与PLC 寄存器 通讯库
        /// 
        public static MelsecMcNet melsec_net;

                    melsec_net = new MelsecMcNet(PlcIP, PlcPort);

            //Connect Plc
            melsec_net.ConnectTimeOut = 2000;
            if (melsec_net.ConnectServer().IsSuccess)
            {
                CPlog("连接PLc成功" + "192.168.0.100, 2001");
            }
            else
            {
                MessageBox.Show("Connect Failed   192.168.0.100, 2001");
                CPlog("连接PLc失败" + "192.168.0.100, 2001");
            }
public static Int16 ReadInt16(string addr) { if (melsec_net != null) { return melsec_net.ReadInt16(addr).Content; } else { return 0; } } public static void WriteInt16(string addr,Int16 value) { if (melsec_net != null) { if (!melsec_net.Write(addr, value).IsSuccess) { InfoWindow.ShowMessage("Plc写入寄存器失败"); CPlog("Plc通讯模块为null"); } } else { InfoWindow.ShowMessage("Plc通讯模块为null"); CPlog("Plc通讯模块为null"); } } melsec_net.ConnectClose(); melsec_net = null;

14-串口怎么玩

        SerialPort sp = new SerialPort();

            sp.PortName = "COM6";
            sp.BaudRate = 19200;
            sp.DataBits = 8;
            sp.StopBits = StopBits.One;
            sp.Parity = Parity.None;

            sp.Open();

            byte[] bytesSend = Encoding.ASCII.GetBytes(sendstr);
            sp.Write(bytesSend, 0, bytesSend.Length);