找回密码
 立即注册
首页 业界区 业界 Winform高级技巧-界面和代码分离的实践案例 ...

Winform高级技巧-界面和代码分离的实践案例

岭猿 2025-6-2 11:30:59
办法总比困难多(不会或不想用WPF MVVM模式也可以搞工控自动化和上位机编程)...
1.gif

 
正文  

活到老就该学到老。但是难道我们不可以偷懒么,老技术指哪打哪,游刃有余,如果已经炉火纯青,那么解决问题又快又好它不香吗。本文拒绝讨论技术谁优秀谁该被鄙视。上图的流程是花2天时间搞好的,我不是得瑟有什么不得了的地方。我见很多人都在探讨MVVM,数据驱动业务多么的了不起,其实老技术Winform一样的能办到不信你问问DeepSeek让它给你一个示例代码。比如这样子的,点这里下载。如果只是这么简单的话,就没有写本文的必要了。
2.jpeg

我们看看上图的场景,因为现场的实际方案没有最终确定,所以开发人员写了5个版本的代码来验证5种流程,但界面就1个,因为业务的数据是一样的。像这种情况我们这种解决方式是极好的。写代码的同事只需要初级程序员就可以担任。帮忙验证和测试是由高级程序员来担任。我贴一些源码来辅助说明一下是怎么实现的。
1.界面的基类:  
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Windows.Forms;
  5. using MES.Core;
  6. using EES.Common;
  7. using EES.Controls.Win;
  8. using EES.Common.Data;
  9. using System.ComponentModel;
  10. using System.Runtime.InteropServices;
  11. using System.Text;
  12. using System.Linq;
  13. using WinControls;
  14. using DataCool_MES.framework;
  15. using DataCool_MES.config;
  16. using DataCool_MES.utils;
  17. using System.Drawing;
  18. namespace DataCool_MES
  19. {
  20.     public delegate void FeedInfoHandler(object sender, Exception ex, string message, MessageTipsLevel level);
  21.     /// <summary>
  22.     /// 业务窗体基类
  23.     /// </summary>
  24.     public partial class BaseModuleForm : DockBaseWorkForm
  25.     {
  26.         #region DllImport
  27.         [DllImport("kernel32")]
  28.         public static extern long WritePrivateProfileString(string section, string key, string val, string filepath);
  29.         [DllImport("kernel32")]
  30.         public static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retval, int size, string filePath);
  31.         [DllImport("imm32.dll")]
  32.         public static extern IntPtr ImmGetContext(IntPtr hwnd);
  33.         [DllImport("imm32.dll")]
  34.         public static extern bool ImmGetOpenStatus(IntPtr himc);
  35.         [DllImport("imm32.dll")]
  36.         public static extern bool ImmSetOpenStatus(IntPtr himc, bool b);
  37.         [DllImport("imm32.dll")]
  38.         public static extern bool ImmGetConversionStatus(IntPtr himc, ref int lpdw, ref int lpdw2);
  39.         [DllImport("imm32.dll")]
  40.         #endregion
  41.         public static extern int ImmSimulateHotKey(IntPtr hwnd, int lngHotkey);
  42.         private const int IME_CMODE_FULLSHAPE = 0x8;
  43.         private const int IME_CHOTKEY_SHAPE_TOGGLE = 0x11;
  44.         private SynchronizationContext sc;
  45.         protected string onceScanData = string.Empty;
  46.         private BarCodeHooK hook;
  47.         IModuleFlow coreFlowObj;
  48.         // 获取屏幕分辨率
  49.         private Rectangle primaryScreen;
  50.         private float scaleX;  // 基准分辨率宽度
  51.         private float scaleY;
  52.         [Browsable(false)]
  53.         public IModuleFlow CoreFlowObj
  54.         {
  55.             get { return coreFlowObj; }
  56.         }
  57.         [Browsable(false)]
  58.         /// <summary>
  59.         /// 日志记录处理异常信息显示处理对象
  60.         /// 此处用于各种日志和状态信息的记录,并进行对应的信息的显示
  61.         /// </summary>
  62.         internal virtual AlertLog Log
  63.         {
  64.             get
  65.             {
  66.                 return null;
  67.             }
  68.         }        
  69.         protected event Action CursorBegin;
  70.         protected event Action CursorEnd;      
  71.         
  72.         /// <summary>
  73.         /// 实例化脚本对象
  74.         /// </summary>
  75.         /// <returns></returns>
  76.         protected virtual IModuleFlow CreateModuleFlow()
  77.         {
  78.             return null;
  79.         }
  80.         public BaseModuleForm()
  81.         {
  82.             DoubleBuffered = true;
  83.             ImeMode = ImeMode.Off;
  84.             AutoScaleMode = AutoScaleMode.None;
  85.             InitializeComponent();
  86.             #region Cursor
  87.             CursorBegin = () =>
  88.             {
  89.                 Clear();
  90.                 Cursor = Cursors.WaitCursor;
  91.             };
  92.             CursorEnd = () =>
  93.             {
  94.                 Cursor = Cursors.Default;
  95.             };
  96.             #endregion
  97.             Load += BaseModuleForm_Load;
  98.             hook = new BarCodeHooK();
  99.             hook.BarCodeEvent += Hook_BarCodeEvent;
  100.             hook.Start();
  101.             FormClosed += BaseModuleForm_FormClosed;
  102.         }
  103.         private void BaseModuleForm_FormClosed(object sender, FormClosedEventArgs e)
  104.         {
  105.             try
  106.             {
  107.                 hook.Stop();
  108.                 hook.BarCodeEvent -= Hook_BarCodeEvent;
  109.                 hook = null;
  110.             }
  111.             catch (Exception ex)
  112.             {
  113.                 FrameAppContext.GetInstance().AppLogger.Error(ex);
  114.             }
  115.         }
  116.         private void Hook_BarCodeEvent(BarCodeHooK.BarCodes barCode)
  117.         {
  118.             if (CoreFlowObj != null && FlowContext.Instance.WorkStatus == WorkStatus.Running && !string.IsNullOrEmpty(barCode.BarCode))
  119.             {
  120.                 onceScanData = TrimSpecialChar(barCode.BarCode);
  121.                 CoreFlowObj.OnExecScanReceiving(onceScanData);
  122.             }
  123.         }
  124.         private void BaseModuleForm_Load(object sender, EventArgs e)
  125.         {
  126.             sc = SynchronizationContext.Current;
  127.             if (!DesignMode)
  128.             {
  129.                 Input = FlowContext.Instance;
  130.                 FlowContext.Instance.FlowCustomEvent += OnRaiseFlowCustomEvent;
  131.             }
  132.         }
  133.         private void OnRaiseFlowCustomEvent(object sender, TEventArgs<EventClass> e)
  134.         {
  135.             sc.Post(new SendOrPostCallback(delegate (object obj)
  136.             {
  137.                 OnFlowCustomEvent((EventClass)obj);
  138.             }), e.Data);
  139.         }
  140.         protected virtual void OnFlowCustomEvent(EventClass ec)
  141.         {
  142.             if (ec.EventType == FlowViewCommand.ClearCurText)
  143.             {
  144.                 Clear();
  145.             }
  146.         }
  147.         /// <summary>
  148.         /// 获取当前窗体绑定的上下文对象
  149.         /// </summary>
  150.         /// <returns></returns>
  151.         public virtual BindingType GetBindingType()
  152.         {
  153.             Type type;
  154.             if (bindingSource.DataSource is Type)
  155.             {
  156.                 type = (Type)bindingSource.DataSource;
  157.             }
  158.             else
  159.             {
  160.                 if (bindingSource.DataSource != null)
  161.                 {
  162.                     type = bindingSource.DataSource.GetType();
  163.                 }
  164.                 else
  165.                 {
  166.                     type = null;
  167.                 }
  168.             }
  169.             if (type == null)
  170.             {
  171.                 throw new Exception("界面输入的数据源为空");
  172.             }
  173.             BindingType bindingType = new BindingType();
  174.             Type type2;
  175.             if (type.GUID == typeof(DataCollection<>).GUID)
  176.             {
  177.                 type2 = type.GetGenericArguments()[0];
  178.                 bindingType.IsArray = true;
  179.             }
  180.             else
  181.             {
  182.                 if (type.GUID == typeof(List<>).GUID)
  183.                 {
  184.                     type2 = type.GetGenericArguments()[0];
  185.                     bindingType.IsArray = true;
  186.                 }
  187.                 else
  188.                 {
  189.                     type2 = type;
  190.                     bindingType.IsArray = false;
  191.                 }
  192.             }
  193.             bindingType.Type = Factory.getRawType(type2);
  194.             return bindingType;
  195.         }
  196.         public virtual void Start()
  197.         {
  198.             if (coreFlowObj != null && FlowContext.Instance.WorkStatus == WorkStatus.Running)
  199.                 return;
  200.             IModuleFlow core = null;
  201.             try
  202.             {
  203.                 CursorBegin.Invoke();
  204.                 if (CoreFlowObj != null)
  205.                     throw new Exception("正在作业,不能启动!");
  206.                 core = CreateModuleFlow();
  207.                 if (core != null)
  208.                 {
  209.                     core.FeedInfo += OnFeedInfo;
  210.                     core.ExecBeginWork();
  211.                     coreFlowObj = core;
  212.                     FlowContext.Instance.WorkStatus = WorkStatus.Running;
  213.                 }
  214.                 ImeMode = ImeMode.NoControl;
  215.                 Log.SetLogFocus();
  216.             }
  217.             catch (Exception ex)
  218.             {
  219.                 FlowContext.Instance.WorkStatus = WorkStatus.NoAction;
  220.                 if (coreFlowObj != null)
  221.                 {
  222.                     coreFlowObj.FeedInfo -= OnFeedInfo;
  223.                     coreFlowObj = null;
  224.                 }
  225.                 throw ex;
  226.             }
  227.             finally
  228.             {
  229.                 if (FlowContext.Instance.WorkStatus == WorkStatus.Running)
  230.                 {
  231.                     onceScanData = string.Empty;
  232.                 }
  233.                 CursorEnd.Invoke();
  234.             }
  235.         }
  236.         public virtual void Stop()
  237.         {
  238.             if (CoreFlowObj != null)
  239.             {
  240.                 try
  241.                 {
  242.                     var configObj = SerializerHelper.LoadFromXML(FrameAppContext.GetInstance().RunTimeConfigPath + "\\AppContentConfig.Config");
  243.                     if (configObj != null && !string.IsNullOrEmpty(configObj.EntryModuleName) && configObj.EntryModuleName.Equals("成品装箱作业"))
  244.                     {
  245.                         using (var dlgFrm = new FlowStopCheckForm())
  246.                         {
  247.                             var dlg = dlgFrm.ShowDialog();
  248.                             if (dlg == DialogResult.OK && !FlowContext.Instance.IsEndPacking)
  249.                             {
  250.                                 CoreFlowObj.ExecEndWork();
  251.                                 coreFlowObj = null;
  252.                                 FlowContext.Instance.WorkStatus = WorkStatus.Stopped;
  253.                             }
  254.                             if (dlg == DialogResult.OK && FlowContext.Instance.IsEndPacking)
  255.                             {
  256.                                 CoreFlowObj.StopWorkCheck();
  257.                             }
  258.                         }
  259.                     }
  260.                     else
  261.                     {
  262.                         CoreFlowObj.ExecEndWork();
  263.                         coreFlowObj = null;
  264.                         FlowContext.Instance.WorkStatus = WorkStatus.Stopped;
  265.                     }
  266.                 }
  267.                 catch (Exception ex)
  268.                 {
  269.                     Exception error = new Exception("流程执行异常停止," + ex.InnerException == null ? ex.Message : ex.InnerException.Message);
  270.                     FrameAppContext.GetInstance().AppLogger.Error(error);
  271.                 }
  272.                 finally
  273.                 {
  274.                     Clear();
  275.                     if (FlowContext.Instance.WorkStatus != WorkStatus.Running)
  276.                     {
  277.                         Log.Write("作业已经停止!", "", MessageTipsLevel.Warning);
  278.                         FrameAppContext.GetInstance().AppLogger.Info("作业已经停止!");
  279.                         FlowContext.Instance.ResetContext();
  280.                     }
  281.                     Utility.GCFullCollect();
  282.                 }
  283.             }
  284.         }
  285.         public virtual void Pause()
  286.         {
  287.             coreFlowObj.ExecPauseWork();
  288.             coreFlowObj = null;
  289.             FlowContext.Instance.WorkStatus = WorkStatus.Pauseing;
  290.             Clear();
  291.             Log.Write("作业已经暂停!", "", MessageTipsLevel.Warning);
  292.         }
  293.         /// <summary>
  294.         /// 界面UI控件的绑定数据清理
  295.         /// 此处为虚函数,用于UI派生界面的具体绑定调用处理
  296.         /// </summary>
  297.         protected virtual void Clear()
  298.         {
  299.         }
  300.         /// <summary>
  301.         /// 异常信息消息处理队列的回调函数
  302.         /// 主要用于各种消息或异常信息的分类处理
  303.         /// </summary>
  304.         /// <param name="sender"></param>
  305.         /// <param name="ex">异常消息结构体</param>
  306.         /// <param name="message">异常消息</param>
  307.         /// <param name="level">异常消息级别</param>
  308.         protected void OnFeedInfo(object sender, Exception ex, string message, MessageTipsLevel level)
  309.         {
  310.             if (Log == null)
  311.             {
  312.                 throw new Exception("AlertLog对象没有绑定或实例化!");
  313.             }
  314.             if (ex != null)
  315.             {
  316.                 Log.Write(string.Format("{0}:->", DateTime.Now.ToString("MM/dd HH:mm:ss")), ex.Message, MessageTipsLevel.Error, true);
  317.             }
  318.             else
  319.             {
  320.                 Log.Write(string.Format("{0}:->", DateTime.Now.ToString("MM/dd HH:mm:ss")), message, level, true);
  321.             }
  322.         }
  323.         /// <summary>
  324.         /// 响应扫描枪输入
  325.         /// </summary>
  326.         /// <param name="msg"></param>
  327.         /// <param name="keyData"></param>
  328.         /// <returns></returns>
  329.         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
  330.         {
  331.             #region 快捷键
  332.             if (msg.Msg == 0x0100 && ContextMenuStrip != null)
  333.             {
  334.                 foreach (ToolStripMenuItem item in ContextMenuStrip.Items)
  335.                 {
  336.                     if (keyData == item.ShortcutKeys)
  337.                     {
  338.                         item.PerformClick();
  339.                     }
  340.                 }
  341.             }
  342.             #endregion
  343.             if (FlowContext.Instance.WorkStatus != WorkStatus.Running)
  344.                 return base.ProcessCmdKey(ref msg, keyData);
  345.             else
  346.                 return true;
  347.         }
  348.         /// <summary>
  349.         /// 截取特殊字符
  350.         /// </summary>
  351.         /// <param name="inputString"></param>
  352.         /// <returns></returns>
  353.         protected virtual string TrimSpecialChar(string inputString)
  354.         {
  355.             return inputString.Replace("\u0010", "");
  356.         }
  357.         /// <summary>
  358.         /// 动态绑定DataGridView的列
  359.         /// </summary>
  360.         /// <param name="t"></param>
  361.         /// <param name="dgv"></param>
  362.         protected virtual void BingGridColumn(Type t, DataGridView dgv)
  363.         {
  364.             dgv.Columns.Clear();
  365.             var props = t.GetProperties().Where(prop => prop.GetCustomAttributes(typeof(DisplayNameAttribute), false).Any());
  366.             int col_width = dgv.Width / props.Count() - 8;
  367.             foreach (var prop in props)
  368.             {
  369.                 DisplayNameAttribute attrib = (DisplayNameAttribute)prop.GetCustomAttributes(typeof(DisplayNameAttribute), false).FirstOrDefault();
  370.                 if (prop.GetCustomAttributes(typeof(ProgressBarCellAttribute), false).Any())
  371.                 {
  372.                     DataGridViewProgressBarColumn dc = new DataGridViewProgressBarColumn();
  373.                     dc.Name = "col" + prop.Name;
  374.                     dc.HeaderText = attrib.DisplayName;
  375.                     dc.DataPropertyName = prop.Name;
  376.                     dc.Width = col_width;
  377.                     dgv.Columns.Add(dc);
  378.                 }
  379.                 else
  380.                 {
  381.                     DataGridViewTextBoxColumn dc = new DataGridViewTextBoxColumn();
  382.                     dc.Name = "col" + prop.Name;
  383.                     dc.HeaderText = attrib.DisplayName;
  384.                     dc.DataPropertyName = prop.Name;
  385.                     dc.Width = col_width;
  386.                     dgv.Columns.Add(dc);
  387.                 }
  388.             }
  389.         }
  390.         /// <summary>
  391.         /// 窗体激活时设置输入法是半角
  392.         /// </summary>
  393.         /// <param name="e"></param>
  394.         protected override void OnActivated(EventArgs e)
  395.         {
  396.             base.OnActivated(e);
  397.             IntPtr HIme = ImmGetContext(this.Handle);
  398.             if (ImmGetOpenStatus(HIme)) //如果输入法处于打开状态
  399.             {
  400.                 int iMode = 0;
  401.                 int iSentence = 0;
  402.                 bool bSuccess = ImmGetConversionStatus(HIme, ref iMode, ref iSentence); //检索输入法资讯
  403.                 if (bSuccess)
  404.                 {
  405.                     if ((iMode & IME_CMODE_FULLSHAPE) > 0) //如果是全形
  406.                         ImmSimulateHotKey(this.Handle, IME_CHOTKEY_SHAPE_TOGGLE); //转换成半形
  407.                 }
  408.             }
  409.         }
  410.         /// <summary>
  411.         /// 缩放控件
  412.         /// </summary>
  413.         /// <param name="control"></param>
  414.         protected void ScaleControl(Control control)
  415.         {
  416.             control.Left = (int)(control.Left * scaleX);
  417.             control.Top = (int)(control.Top * scaleY);
  418.             control.Width = (int)(control.Width * scaleX);
  419.             control.Height = (int)(control.Height * scaleY);
  420.             foreach (Control child in control.Controls)
  421.             {
  422.                 ScaleControl(child);
  423.             }
  424.         }
  425.     }
  426. }
复制代码
  2、代码的基类
  1. using EES.Common;
  2. using System;
  3. using MES.Core;
  4. namespace DataCool_MES
  5. {
  6.     /// <summary>
  7.     /// 脚本的基类
  8.     /// </summary>
  9.     public abstract class ModuleBaseFlow : IModuleFlow
  10.     {
  11.         /// <summary>
  12.         /// 传递消息的事件
  13.         /// </summary>
  14.         public event FeedInfoHandler FeedInfo;
  15.         protected FlowContext flowContext = FlowContext.Instance;
  16.         //是否是调试模式
  17.         protected bool debugMode = false;
  18.         //是否显示过程明细信息
  19.         protected bool showDetail = false;
  20.         /// <summary>
  21.         /// 采集到数据后发生
  22.         /// </summary>
  23.         /// <param name="data"></param>
  24.         public virtual void OnExecScanReceiving(string data)
  25.         {
  26.             FrameAppContext.GetInstance().AppLogger.Info(data);
  27.         }
  28.         /// <summary>
  29.         /// 触发消息传递
  30.         /// </summary>
  31.         /// <param name="sender"></param>
  32.         /// <param name="ex"></param>
  33.         /// <param name="message"></param>
  34.         /// <param name="level"></param>
  35.         protected virtual void OnFeedInfo(object sender, Exception ex, string message, MessageTipsLevel level)
  36.         {
  37.             FeedInfo?.Invoke(sender, ex, message, level);
  38.             if (ex != null)
  39.                 OnException(ex);
  40.         }
  41.         /// <summary>
  42.         /// 手动处理脚本触发的异常
  43.         /// </summary>
  44.         /// <param name="ex"></param>
  45.         protected virtual void OnException(Exception ex)
  46.         {
  47.         }
  48.         /// <summary>
  49.         /// 触发抛出异常
  50.         /// </summary>
  51.         /// <param name="sender"></param>
  52.         /// <param name="message"></param>
  53.         /// <param name="args"></param>
  54.         protected virtual void RaiseException(object sender, string message, params object[] args)
  55.         {
  56.             OnFeedInfo(sender, new Exception(string.Format(message, args)), message, MessageTipsLevel.Error);
  57.             if (!message.Contains("由于目标计算机积极拒绝"))
  58.                 throw new Exception(message);
  59.         }
  60.         /// <summary>
  61.         /// 触发消息提示
  62.         /// </summary>
  63.         /// <param name="sender"></param>
  64.         /// <param name="message"></param>
  65.         protected void RaiseInfo(object sender, string message)
  66.         {
  67.             OnFeedInfo(sender, null, message, MessageTipsLevel.Information);
  68.         }
  69.         /// <summary>
  70.         /// 触发警告信息
  71.         /// </summary>
  72.         /// <param name="sender"></param>
  73.         /// <param name="message"></param>
  74.         protected void RaiseWarning(object sender, string message)
  75.         {
  76.             OnFeedInfo(sender, null, message, MessageTipsLevel.Warning);
  77.         }
  78.         /// <summary>
  79.         /// 脚本触发界面自定义事件响应
  80.         /// </summary>
  81.         /// <param name="eventType"></param>
  82.         /// <param name="portKey"></param>
  83.         /// <param name="portName"></param>
  84.         /// <param name="data"></param>
  85.         public virtual void RaiseCustomEvent(string eventType, string portKey, string portName, object data)
  86.         {
  87.             try
  88.             {
  89.                 FlowContext.Instance.RaiseCustomEvent(this, eventType, portKey, portName, data);
  90.             }
  91.             catch (Exception ex)
  92.             {
  93.                 RaiseException(this, ex.Message);
  94.             }
  95.         }
  96.         /// <summary>
  97.         /// 执行开始作业
  98.         /// </summary>
  99.         public virtual void ExecBeginWork()
  100.         {
  101.             try
  102.             {
  103.                 BeforeWorkInit();
  104.             }
  105.             catch (Exception ex)
  106.             {
  107.                 throw ex;
  108.             }
  109.         }
  110.         /// <summary>
  111.         /// 执行结束作业
  112.         /// </summary>
  113.         public virtual void ExecEndWork()
  114.         {
  115.         }
  116.         /// <summary>
  117.         /// 执行暂停作业
  118.         /// </summary>
  119.         public virtual void ExecPauseWork()
  120.         {
  121.             try
  122.             {
  123.                 PauseWorkCache();
  124.             }
  125.             catch (Exception ex)
  126.             {
  127.                 throw ex;
  128.             }
  129.             finally
  130.             {
  131.                 FlowContext.Instance.ResetContext();
  132.             }
  133.         }
  134.         /// <summary>
  135.         /// 开始作业前初始化
  136.         /// </summary>
  137.         protected virtual void BeforeWorkInit()
  138.         {
  139.             RaiseInfo(this,"作业条件检查中...");
  140.         }
  141.         /// <summary>
  142.         /// 结束作业时执行检查
  143.         /// </summary>
  144.         public virtual void StopWorkCheck()
  145.         {
  146.         }
  147.         /// <summary>
  148.         /// 暂停作业时缓存业务临时数据
  149.         /// </summary>
  150.         protected virtual void PauseWorkCache()
  151.         {
  152.         }
  153.     }
  154. }
复制代码
  3.业务窗体
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using System.ComponentModel.Composition.Hosting;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Windows.Forms;
  11. using MES.Core;
  12. using MES.Services;
  13. using DataCool_MES.modules.dto;
  14. using MES.Services.ModuleFlowServices;
  15. using System.Net.Sockets;
  16. using System.IO;
  17. using WinControls;
  18. namespace DataCool_MES.modules
  19. {
  20.     [FullScreenStyle(true)]
  21.     [View("批量扫描tray盘混料检测", EntryType.入口, "一次产品检验", "包装作业")]
  22.     public partial class BatchPackForm : BaseModuleForm
  23.     {
  24.         [Import]
  25.         protected IModuleFlowFormService ModuleFlowFormService { get; set; }
  26.         //已扫记录
  27.         private List<BatchScanLogDto> LogData = new List<BatchScanLogDto>();
  28.         private BatchScanLogDto currentBarcodeData = null;
  29.         private WorkStationConfig config;
  30.         private TcpClient cameraClient;
  31.         private TcpClient transmitDeviceClient;
  32.         private byte[] buffer = new byte[2048];
  33.         public BatchPackForm()
  34.         {
  35.             DoubleBuffered = true;
  36.             CheckForIllegalCrossThreadCalls = false;
  37.             InitializeComponent();
  38.             config = SerializerHelper.LoadFromXML<WorkStationConfig>(AppDomain.CurrentDomain.BaseDirectory + "Config\" + "WorkStationConfig.xml");
  39.             if (config != null)
  40.             {
  41.                 FlowContext.Instance.TraySpecifications = config.TraySpecifications;
  42.             }
  43.             Load += BatchPackForm_Load;
  44.             FormClosed += BatchPackForm_FormClosed;
  45.         }
  46.         private void BatchPackForm_FormClosed(object sender, FormClosedEventArgs e)
  47.         {
  48.             if (transmitDeviceClient != null)
  49.             {
  50.                 try
  51.                 {
  52.                     transmitDeviceClient.Client?.Disconnect(false);
  53.                     transmitDeviceClient.Client?.Close();
  54.                     transmitDeviceClient?.Close();
  55.                     transmitDeviceClient = null;
  56.                 }
  57.                 catch
  58.                 {
  59.                 }
  60.             }
  61.             Program.Quit();
  62.         }
  63.         AlertLog log;
  64.         internal override AlertLog Log
  65.         {
  66.             get
  67.             {
  68.                 if (log == null)
  69.                 {
  70.                     Interlocked.CompareExchange(ref log, new AlertLog(richTextBox1), null);
  71.                 }
  72.                 return log;
  73.             }
  74.         }
  75.         private void BatchPackForm_Load(object sender, EventArgs e)
  76.         {
  77.             var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  78.             var container = new CompositionContainer(catalog);
  79.             container.ComposeParts(this, new FlowWorkService());
  80.             if (!System.Diagnostics.Debugger.IsAttached)
  81.             {
  82.                 btnStart.DataBindings.Add(new Binding("Enabled", FlowContext.Instance, "IsStoped", false, DataSourceUpdateMode.OnPropertyChanged));
  83.                 btnStop.DataBindings.Add(new Binding("Enabled", FlowContext.Instance, "IsRunning", false, DataSourceUpdateMode.OnPropertyChanged));
  84.             }
  85.             if (config != null && !string.IsNullOrEmpty(config.TransmissionDeviceIP))
  86.             {
  87.                 try
  88.                 {
  89.                     transmitDeviceClient = new TcpClient();
  90.                     transmitDeviceClient.BeginConnect(config.TransmissionDeviceIP, config.TransmissionDevicePort, new AsyncCallback(ConnectCallback2), transmitDeviceClient);
  91.                 }
  92.                 catch (Exception ex)
  93.                 {
  94.                     FrameAppContext.GetInstance().AppLogger.Error(ex);
  95.                 }
  96.             }
  97.         }
  98.         protected override IModuleFlow CreateModuleFlow()
  99.         {
  100.             return new BatchScanWorkFlow(ModuleFlowFormService);
  101.         }
  102.         protected override void Clear()
  103.         {
  104.             richTextBox1.Text = "";
  105.         }
  106.         private void btnStart_Click(object sender, EventArgs e)
  107.         {
  108.             try
  109.             {
  110.                 Start();
  111.                 if (FlowContext.Instance.WorkStatus == WorkStatus.Running)
  112.                 {
  113.                     cameraClient = new TcpClient();
  114.                     cameraClient.BeginConnect(config.CameraIP, config.CameraPort, new AsyncCallback(ConnectCallback), cameraClient);
  115.                 }
  116.                 if (FlowContext.Instance.WorkStatus == WorkStatus.Running)
  117.                 {
  118.                     try
  119.                     {
  120.                         if (transmitDeviceClient != null)
  121.                         {
  122.                             var sm = transmitDeviceClient.GetStream();
  123.                             SendCommandToDevice(sm, "OK");
  124.                         }
  125.                         else
  126.                         {
  127.                             Log.Write("", "没有和传动设备建立连接!!!", MessageTipsLevel.Error);
  128.                         }
  129.                     }
  130.                     catch (Exception ex)
  131.                     {
  132.                         Log.Write("", "和传动设备通信失败!!!" + Environment.NewLine + ex.Message, MessageTipsLevel.Error);
  133.                     }
  134.                 }
  135.             }
  136.             catch (Exception ex)
  137.             {
  138.                 FrameAppContext.GetInstance().AppLogger.Error($"{ex.Message}");
  139.             }
  140.         }
  141.         void ConnectCallback(IAsyncResult ar)
  142.         {
  143.             TcpClient client = (TcpClient)ar.AsyncState;
  144.             try
  145.             {
  146.                 client.EndConnect(ar);
  147.                 NetworkStream stream = client.GetStream();
  148.                 if (stream != null)
  149.                 {
  150.                     buffer = new byte[2048];
  151.                     stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), stream);
  152.                 }
  153.             }
  154.             catch (Exception ex)
  155.             {
  156.                 log.Write("", ex.Message, MessageTipsLevel.Error);
  157.             }
  158.         }
  159.         void ReadCallback(IAsyncResult ar)
  160.         {
  161.             NetworkStream stream = (NetworkStream)ar.AsyncState;
  162.             if (FlowContext.Instance.WorkStatus != WorkStatus.Running)
  163.                 return;
  164.             int bytesRead = stream.EndRead(ar);
  165.             string responseData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
  166.             log.Write("", $"Received: {Environment.NewLine}{responseData}", MessageTipsLevel.Information);
  167.             FrameAppContext.GetInstance().AppLogger.Info(Environment.NewLine + responseData);
  168.             if (!string.IsNullOrEmpty(responseData) && responseData.IndexOf("+") != -1)
  169.             {
  170.                 ScanLog(responseData);
  171.             }
  172.             buffer = new byte[2048];
  173.             stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), stream);
  174.         }
  175.         private void BtnStop_Click(object sender, EventArgs e)
  176.         {
  177.             try
  178.             {
  179.                 Stop();
  180.                 var config = SerializerHelper.LoadFromXML<WorkStationConfig>(AppDomain.CurrentDomain.BaseDirectory + "Config\" + "WorkStationConfig.xml");
  181.                 FlowContext.Instance.TraySpecifications = config.TraySpecifications;
  182.                 if (config != null && !string.IsNullOrEmpty(config.TraySpecifications) &&
  183.                     config.TraySpecifications.IndexOf(",") == -1)
  184.                 {
  185.                     string[] cellData = config.TraySpecifications.Split('*');
  186.                     if (cellData.Length > 0)
  187.                     {
  188.                         FlowContext.Instance.TrayRowCount = Convert.ToInt32(cellData[1]);
  189.                         FlowContext.Instance.TrayCellCount = Convert.ToInt32(cellData[0]);
  190.                     }
  191.                 }
  192.                 if (cameraClient != null && FlowContext.Instance.WorkStatus != WorkStatus.Running)
  193.                 {
  194.                     cameraClient.Client?.Disconnect(false);
  195.                     cameraClient.Client?.Close();
  196.                     cameraClient?.Close();
  197.                     cameraClient = null;
  198.                 }
  199.                 SendCommandToDevice(transmitDeviceClient.GetStream(), "NG");
  200.             }
  201.             catch (Exception ex)
  202.             {
  203.                 FrameAppContext.GetInstance().AppLogger.Error($"{ex.Message}");
  204.             }
  205.         }
  206.         protected override void OnFlowCustomEvent(EventClass ec)
  207.         {
  208.             if (ec.EventType.Equals("LoadData"))
  209.             {
  210.                 DataAction(LoadData);
  211.             }
  212.             if (ec.EventType.Equals("ExportResultData"))
  213.             {
  214.                 DataAction(ExportLogToExcelFile);
  215.             }
  216.         }
  217.         /// <summary>
  218.         /// 从临时xml文件读取扫描历史记录
  219.         /// </summary>
  220.         private void SaveData()
  221.         {
  222.             if (!System.IO.Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "LocalData"))
  223.             {
  224.                 System.IO.Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "LocalData");
  225.             }
  226.             if (!System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + "LocalData\" + DateTime.Now.ToString("yyyyMMdd") + ".xml"))
  227.             {
  228.                 SerializerHelper.SerializerToXML(AppDomain.CurrentDomain.BaseDirectory + "LocalData\" + DateTime.Now.ToString("yyyyMMdd") + ".xml", LogData);
  229.             }
  230.             else
  231.             {
  232.                 System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory + "LocalData\" + DateTime.Now.ToString("yyyyMMdd") + ".xml");
  233.                 SerializerHelper.SerializerToXML(AppDomain.CurrentDomain.BaseDirectory + "LocalData\" + DateTime.Now.ToString("yyyyMMdd") + ".xml", LogData);
  234.             }
  235.             FlowContext.Instance.L1Count = LogData.Count;
  236.             if (LogData.Count > 0)
  237.                 bindingSourceGrid.DataSource = LogData.OrderByDescending(t => t.ScanDatetime).ToList();
  238.         }
  239.         /// <summary>
  240.         /// 加载已有扫描记录
  241.         /// </summary>
  242.         private void LoadData()
  243.         {
  244.             if (!System.IO.Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "LocalData"))
  245.             {
  246.                 System.IO.Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "LocalData");
  247.             }
  248.             if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + "LocalData\" + DateTime.Now.ToString("yyyyMMdd") + ".xml"))
  249.             {
  250.                 LogData = SerializerHelper.LoadFromXML<List<BatchScanLogDto>>(AppDomain.CurrentDomain.BaseDirectory + "LocalData\" + DateTime.Now.ToString("yyyyMMdd") + ".xml");
  251.                 FlowContext.Instance.L1Count = LogData.Count;
  252.                 if (LogData.Count > 0)
  253.                     bindingSourceGrid.DataSource = LogData.OrderByDescending(t => t.ScanDatetime).ToList();
  254.             }
  255.         }
  256.         /// <summary>
  257.         /// 扫描到一组条码
  258.         /// </summary>
  259.         /// <param name="barcodeData"></param>
  260.         private void ScanLog(string barcodeData)
  261.         {
  262.             if (LogData.Any(t => t.BarcodeData == barcodeData))
  263.             {
  264.                 log.Write(DateTime.Now + "->:", "重复扫描!", MessageTipsLevel.Error);
  265.             }
  266.             else
  267.             {
  268.                 #region 传递收到的数据
  269.                 var entity = new BatchScanLogDto();
  270.                 entity.BarcodeData = barcodeData;
  271.                 entity.MaterialCode = FlowContext.Instance.MaterielCode;
  272.                 entity.ScanDatetime = DateTime.Now.ToString();
  273.                 entity.TraySpecifications = FlowContext.Instance.TraySpecifications;
  274.                 entity.ResourceText = barcodeData;
  275.                 currentBarcodeData = entity;
  276.                 #endregion
  277.                 //校验数据
  278.                 ThreeColorled1_Click(threeColorled1, new EventArgs());
  279.             }
  280.         }
  281.         private void ThreeColorled1_Click(object sender, EventArgs e)
  282.         {
  283.             //必须是符合业务场景的扫描数据
  284.             if (FlowContext.Instance.WorkStatus != WorkStatus.Running ||
  285.                 currentBarcodeData == null ||
  286.                 currentBarcodeData.BarcodeData.IndexOf("+") == -1)
  287.                 return;
  288.             #region 展示解析结果
  289.             BarcodeResultViewForm barcodeResultViewForm = new BarcodeResultViewForm(currentBarcodeData);
  290.             var diagResult = barcodeResultViewForm.ShowDialog();
  291.             if (diagResult == DialogResult.OK &&
  292.                 !LogData.Any(r => r.ResourceText == currentBarcodeData.ResourceText))
  293.             {
  294.                 threeColorled1.StatusCode = "1";
  295.                 log.Write("", "校验通过!", MessageTipsLevel.Information);
  296.                 LogData.Add(barcodeResultViewForm.BarcodeData);
  297.                 DataAction(SaveData);
  298.                 FlowContext.Instance.L1Count = LogData.Count;
  299.                 SendCommandToDevice(transmitDeviceClient.GetStream(), "OK");
  300.             }
  301.             else if (diagResult != DialogResult.OK &&
  302.                 !LogData.Any(r => r.ResourceText == currentBarcodeData.ResourceText))
  303.             {
  304.                 threeColorled1.StatusCode = "2";
  305.                 var sm = transmitDeviceClient.GetStream();
  306.                 SendCommandToDevice(sm, "NG");
  307.                 log.Write("", $"{Environment.NewLine}校验结果是有混料,不予通行!!!", MessageTipsLevel.Warning);
  308.             }
  309.             #endregion
  310.         }
  311.         /// <summary>
  312.         /// 和传动设备建立Socket连接回调
  313.         /// </summary>
  314.         /// <param name="ar"></param>
  315.         void ConnectCallback2(IAsyncResult ar)
  316.         {
  317.             TcpClient client = (TcpClient)ar.AsyncState;
  318.             try
  319.             {
  320.                 client.EndConnect(ar);
  321.                 Log.Write("", "传动设备已准备就绪...", MessageTipsLevel.Information);
  322.             }
  323.             catch (Exception ex)
  324.             {
  325.                 Log.Write("", "传动设备连接失败!"+ex.Message, MessageTipsLevel.Error);
  326.                 FrameAppContext.GetInstance().AppLogger.Error(ex);
  327.             }
  328.         }
  329.         /// <summary>
  330.         /// 给NetworkStream发送指令
  331.         /// </summary>
  332.         /// <param name="stream"></param>
  333.         /// <param name="cmd"></param>
  334.         private void SendCommandToDevice(NetworkStream stream, string cmd)
  335.         {
  336.             string command = cmd;
  337.             byte[] commandBuffer = ASCIIEncoding.ASCII.GetBytes(command);
  338.             stream.WriteAsync(commandBuffer, 0, commandBuffer.Length);
  339.         }
  340.         /// <summary>
  341.         /// 导出Excel文件(扫码原始记录)
  342.         /// </summary>
  343.         /// <param name="sender"></param>
  344.         /// <param name="e"></param>
  345.         private void BtnExport_Click(object sender, EventArgs e)
  346.         {
  347.             if (LogData.Count == 0)
  348.             {
  349.                 MessageTip.ShowError("还没有通过检验的记录不能导出!");
  350.             }
  351.             else
  352.             {
  353.                 ExportExcel exportExcel = new ExportExcel();
  354.                 string fileName = $"{AppDomain.CurrentDomain.BaseDirectory + "LocalData"}\\{DateTime.Now.Date:yyyyMMdd}{FlowContext.Instance.MaterielCode}.xls";
  355.                 exportExcel.GridToExcel(fileName, this.dataGridView1);
  356.                 if (File.Exists(fileName))
  357.                 {
  358.                     MessageTip.ShowOk($"Excel文件导出成功!");
  359.                 }
  360.             }
  361.         }
  362.         /// <summary>
  363.         /// 导出Excel文件(MES要求的格式)
  364.         /// </summary>
  365.         private void ExportLogToExcelFile()
  366.         {
  367.             if (LogData.Count == 0)
  368.                 return;
  369.             #region 临时表
  370.             var dt = new DataTable();
  371.             dt.Columns.Add(new DataColumn("条码", typeof(string)));
  372.             foreach (var logItem in LogData)
  373.             {
  374.                 string[] barcodeList = logItem.BarcodeData.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  375.                 foreach (var barcode in barcodeList)
  376.                 {
  377.                     DataRow dr = dt.NewRow();
  378.                     dr[0] = barcode;
  379.                     dt.Rows.Add(dr);
  380.                 }
  381.             }
  382.             #endregion
  383.             try
  384.             {
  385.                 ExportExcel exportExcel = new ExportExcel();
  386.                 string fileName = $"{AppDomain.CurrentDomain.BaseDirectory + "LocalData"}\\{DateTime.Now.Date:yyyyMMdd}{FlowContext.Instance.MaterielCode}(仅条码).xls";
  387.                 if (File.Exists(fileName))
  388.                     File.Delete(fileName);
  389.                 exportExcel.DataTableToExcel(fileName, dt);
  390.                 if (File.Exists(fileName))
  391.                 {
  392.                     MessageTip.ShowOk("生产过程的全部条码已保存!");
  393.                     string logMessage = $"本次生产共计扫描条码{dt.Rows.Count}个,通过tray盘{LogData.Count}盘.";
  394.                     log.Write("", logMessage, MessageTipsLevel.Information);
  395.                     FrameAppContext.GetInstance().AppLogger.Info(logMessage);
  396.                 }
  397.             }
  398.             catch (Exception ex)
  399.             {
  400.                 log.Write("", ex.Message, MessageTipsLevel.Error);
  401.             }
  402.             finally
  403.             {
  404.                 dt.Dispose();
  405.             }
  406.         }
  407.         private void button1_Click(object sender, EventArgs e)
  408.         {
  409.             Program.Quit();
  410.         }
  411.         private void richTextBox1_DoubleClick(object sender, EventArgs e)
  412.         {
  413.             Clear();
  414.         }
  415.     }
  416. }
复制代码
  4.流程代码
  1. using System;
  2. using System.ComponentModel.Composition;
  3. using System.IO;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using MES.Core;
  9. using MES.Services;
  10. namespace DataCool_MES.modules
  11. {
  12.     /// <summary>
  13.     /// 批量扫描作业流程
  14.     /// </summary>
  15.     public class BatchScanWorkFlow : ModuleBaseFlow
  16.     {
  17.         private TcpClient cameraClient;
  18.         protected IModuleFlowFormService ModuleFlowFormService { get; set; }
  19.         /// <summary>
  20.         /// 析构函数
  21.         /// </summary>
  22.         /// <param name="svr"></param>
  23.         public BatchScanWorkFlow(IModuleFlowFormService svr)
  24.         {
  25.             ModuleFlowFormService = svr;
  26.         }
  27.         /// <summary>
  28.         /// 和阅读器建立Socket连接回调
  29.         /// </summary>
  30.         /// <param name="ar"></param>
  31.         void ConnectCallback(IAsyncResult ar)
  32.         {
  33.             try
  34.             {
  35.                 TcpClient client = (TcpClient)ar.AsyncState;
  36.                 client?.EndConnect(ar);
  37.                 NetworkStream stream = client.GetStream();
  38.                 if (stream != null)
  39.                 {
  40.                     RaiseInfo(this, "读码器已准备就绪...");
  41.                     if (client != null)
  42.                     {
  43.                         stream.Close();
  44.                         cameraClient?.Close();
  45.                     }
  46.                 }
  47.             }
  48.             catch (Exception ex)
  49.             {
  50.                 RaiseException(this, "读码器连接失败!!!错误码:"+ex.Message);
  51.             }
  52.             
  53.         }
  54.         /// <summary>
  55.         /// 给NetworkStream发送指令
  56.         /// </summary>
  57.         /// <param name="stream"></param>
  58.         /// <param name="cmd"></param>
  59.         private void SendCommandToDevice(NetworkStream stream, string cmd)
  60.         {
  61.             string command = cmd;
  62.             byte[] commandBuffer = ASCIIEncoding.ASCII.GetBytes(command);
  63.             stream.WriteAsync(commandBuffer, 0, commandBuffer.Length);
  64.         }
  65.         /// <summary>
  66.         /// 和传动设备建立Socket连接回调
  67.         /// </summary>
  68.         /// <param name="ar"></param>
  69.         void ConnectCallback2(IAsyncResult ar)
  70.         {
  71.             try
  72.             {
  73.                 TcpClient client = (TcpClient)ar.AsyncState;
  74.                 client?.EndConnect(ar);
  75.                 NetworkStream stream = client.GetStream();
  76.                 if (stream != null)
  77.                 {
  78.                     //发消息让皮带开始转动
  79.                     SendCommandToDevice(stream, "OK");
  80.                 }
  81.             }
  82.             catch (Exception ex)
  83.             {
  84.                 RaiseException(this, "传动设备连接失败!!!错误码:" + ex.Message);
  85.             }
  86.         }
  87.         /// <summary>
  88.         /// 开始作业前准备工作
  89.         /// </summary>
  90.         protected override void BeforeWorkInit()
  91.         {
  92.             base.BeforeWorkInit();
  93.             if (string.IsNullOrEmpty(FlowContext.Instance.TraySpecifications))
  94.             {
  95.                 RaiseException($"{DateTime.Now}->:", $"必须设定容器的规格!");
  96.             }
  97.             if (string.IsNullOrEmpty(FlowContext.Instance.MaterielCodeHeader+FlowContext.Instance.MaterielCodeEnder))
  98.             {
  99.                 RaiseException($"{DateTime.Now}->:", $"必须输入本次校验的物料代码!");
  100.             }
  101.             flowContext.L1Count = 0;
  102.             RaiseCustomEvent("LoadData", "", "", "");
  103.             var config = SerializerHelper.LoadFromXML<WorkStationConfig>(AppDomain.CurrentDomain.BaseDirectory + "Config\" + "WorkStationConfig.xml");
  104.             if (config != null && !string.IsNullOrEmpty(config.CameraIP))
  105.             {
  106.                 try
  107.                 {
  108.                     cameraClient = new TcpClient();
  109.                     cameraClient.BeginConnect(config.CameraIP, config.CameraPort, new AsyncCallback(ConnectCallback), cameraClient);
  110. }
  111.                 catch (Exception ex)
  112.                 {
  113.                     RaiseException(this,"",ex.Message);
  114.                 }
  115.             }
  116.             else
  117.             {
  118.                 RaiseException($"{DateTime.Now}->:", $"必须设定阅读器的IP地址!");
  119.             }
  120.             if (config != null && !string.IsNullOrEmpty(config.TraySpecifications) && config.TraySpecifications.IndexOf(",") == -1)
  121.             {
  122.                 string[] cellData = config.TraySpecifications.Split('*');
  123.                 if (cellData.Length > 0)
  124.                 {
  125.                     flowContext.TrayRowCount = Convert.ToInt32(cellData[1]);
  126.                     flowContext.TrayCellCount = Convert.ToInt32(cellData[0]);
  127.                 }
  128.             }
  129.             FlowContext.Instance.MaterielCode= FlowContext.Instance.MaterielCodeHeader+FlowContext.Instance.MaterielCodeEnder;
  130.             RaiseInfo(this, "系统准备就绪...");
  131.         }
  132.         /// <summary>
  133.         /// 扫描到一个条码
  134.         /// </summary>
  135.         /// <param name="data"></param>
  136.         public override void OnExecScanReceiving(string data)
  137.         {
  138.             RaiseCustomEvent("ScanLog", "", "", data);
  139.         }
  140.         /// <summary>
  141.         /// 结束本次作业
  142.         /// </summary>
  143.         public override void ExecEndWork()
  144.         {
  145.             base.ExecEndWork();
  146.             //导出扫描记录
  147.             RaiseCustomEvent("ExportResultData", "", "", "");
  148.         }
  149.     }
  150. }
复制代码
  5.界面绑定代码
  1. protected override IModuleFlow CreateModuleFlow()
  2. {
  3.      return new BatchScanWorkFlow(ModuleFlowFormService);
  4. }
复制代码
  
3.png

 界面和代码中间还有个上下文对象,也就是一个单例,貌似这样子:
  1. using EES.Common;
  2. using MES.Core;
  3. using System;
  4. using System.ComponentModel;  
  5. namespace DataCool_MES
  6. {
  7.     /// <summary>
  8.     /// 工作流程上下文对象
  9.     /// </summary>
  10.     [Serializable]
  11.     public class FlowContext : SingletonProvider<FlowContext>, INotifyPropertyChanged
  12.     {
  13.         public System.Configuration.Configuration AppConfig { get; set; }
  14.         public event EventHandler<TEventArgs<EventClass>> FlowCustomEvent;
  15.         public event PropertyChangedEventHandler PropertyChanged;
  16.         private void OnPropertyChanged(string propertyName)
  17.         {
  18.             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  19.         }
  20.         private WorkStatus workStatus;
  21.         /// <summary>
  22.         /// 工作流程运行状态
  23.         /// </summary>
  24.         public WorkStatus WorkStatus
  25.         {
  26.             get { return workStatus; }
  27.             set
  28.             {
  29.                 workStatus = value;
  30.                 OnPropertyChanged("WorkStatus");
  31.                 switch (value)
  32.                 {
  33.                     case WorkStatus.Running:
  34.                         IsRunning = true;
  35.                         IsStoped = false;
  36.                         WorkStatusName = "运行中...";
  37.                         break;
  38.                     case WorkStatus.Pauseing:
  39.                         IsRunning = false;
  40.                         IsStoped = true;
  41.                         WorkStatusName = "暂停中...";
  42.                         break;
  43.                     case WorkStatus.Stopped:
  44.                         IsRunning = false;
  45.                         IsStoped = true;
  46.                         WorkStatusName = "已经停止...";
  47.                         break;
  48.                     default:
  49.                         IsRunning = false;
  50.                         IsStoped = true;
  51.                         WorkStatusName = "未启动";
  52.                         break;
  53.                 }
  54.             }
  55.         }
  56.         private string workStation;
  57.         /// <summary>
  58.         /// 工位
  59.         /// </summary>
  60.         public string WorkStation
  61.         {
  62.             get { return workStation; }
  63.             set
  64.             {
  65.                 workStation = value;
  66.                 OnPropertyChanged("WorkStation");
  67.             }
  68.         }
  69.         private string _operator;
  70.         /// <summary>
  71.         /// 工位操作员
  72.         /// </summary>
  73.         public string Operator
  74.         {
  75.             get { return _operator; }
  76.             set { _operator = value; OnPropertyChanged("Operator"); }
  77.         }
  78.         private string lineNo;
  79.         /// <summary>
  80.         /// 线号
  81.         /// </summary>
  82.         public string LineNo
  83.         {
  84.             get { return lineNo; }
  85.             set { lineNo = value; OnPropertyChanged("LineNo"); }
  86.         }
  87.         private string _L1Code;
  88.         /// <summary>
  89.         /// PCBA条码
  90.         /// </summary>
  91.         public string L1Code
  92.         {
  93.             get { return _L1Code; }
  94.             set { _L1Code = value; OnPropertyChanged("L1Code"); }
  95.         }
  96.         private string _L2Code;
  97.         /// <summary>
  98.         /// 过程条码
  99.         /// </summary>
  100.         public string L2Code
  101.         {
  102.             get { return _L2Code; }
  103.             set { _L2Code = value; OnPropertyChanged("L2Code"); }
  104.         }
  105.         private string workStatusName;
  106.         /// <summary>
  107.         /// 状态状态描述信息
  108.         /// </summary>
  109.         public string WorkStatusName
  110.         {
  111.             get { return workStatusName; }
  112.             set { workStatusName = value; OnPropertyChanged("WorkStatusName"); }
  113.         }
  114.         private int _L1Count;
  115.         /// <summary>
  116.         /// 第一道工序计数
  117.         /// </summary>
  118.         public int L1Count
  119.         {
  120.             get { return _L1Count; }
  121.             set
  122.             {
  123.                 _L1Count = value;
  124.                 OnPropertyChanged("L1Count");
  125.             }
  126.         }
  127.         private int _L1CountEx = 0;
  128.         /// <summary>
  129.         /// 制令计数,可清零
  130.         /// </summary>
  131.         public int L1CountEx
  132.         {
  133.             get { return _L1CountEx; }
  134.             set
  135.             {
  136.                 _L1CountEx = value;
  137.                 OnPropertyChanged("L1CountEx");
  138.             }
  139.         }
  140.         private int _L2Count;
  141.         /// <summary>
  142.         /// 第二道工序计数
  143.         /// </summary>
  144.         public int L2Count
  145.         {
  146.             get { return _L2Count; }
  147.             set { _L2Count = value; OnPropertyChanged("L2Count"); }
  148.         }
  149.         private string _TraySpecifications;
  150.         /// <summary>
  151.         ///Tray Specifications
  152.         /// </summary>
  153.         public string TraySpecifications
  154.         {
  155.             get { return _TraySpecifications; }
  156.             set
  157.             {
  158.                 _TraySpecifications = value;
  159.                 OnPropertyChanged("TraySpecifications");
  160.             }
  161.         }
  162.         public int TrayCellCount
  163.         {
  164.             get;set;
  165.         }
  166.         public int TrayRowCount
  167.         {
  168.             get; set;
  169.         }
  170.         private string orderNo;
  171.         /// <summary>
  172.         /// 状态状态描述信息
  173.         /// </summary>
  174.         public string OrderNo
  175.         {
  176.             get { return orderNo; }
  177.             set
  178.             {
  179.                 orderNo = value;
  180.                 OnPropertyChanged("OrderNo");
  181.             }
  182.         }
  183.         private string _MaterielCode;
  184.         /// <summary>
  185.         /// 物料编码
  186.         /// </summary>
  187.         public string MaterielCode
  188.         {
  189.             get { return _MaterielCode; }
  190.             set { _MaterielCode = value; OnPropertyChanged("MaterielCode"); }
  191.         }
  192.         private string _MaterielCodeEnder;
  193.         /// <summary>
  194.         /// 物料编码
  195.         /// </summary>
  196.         public string MaterielCodeEnder
  197.         {
  198.             get { return _MaterielCodeEnder; }
  199.             set { _MaterielCodeEnder = value; OnPropertyChanged("_MaterielCodeEnder"); }
  200.         }
  201.         private string _MaterielCodeHeader;
  202.         /// <summary>
  203.         /// 物料编码
  204.         /// </summary>
  205.         public string MaterielCodeHeader
  206.         {
  207.             get { return _MaterielCodeHeader; }
  208.             set { _MaterielCodeHeader = value; OnPropertyChanged("MaterielCodeHeader"); }
  209.         }
  210.         private int progress;
  211.         /// <summary>
  212.         /// 本次扫描完成时的进度
  213.         /// </summary>
  214.         public int Progress
  215.         {
  216.             get { return progress; }
  217.             set { progress = value; OnPropertyChanged("Progress"); }
  218.         }
  219.         private bool isStoped = true;
  220.         /// <summary>
  221.         /// WorkStatus是否已经停止
  222.         /// </summary>
  223.         public bool IsStoped
  224.         {
  225.             get { return isStoped; }
  226.             set { isStoped = value; OnPropertyChanged("IsStoped"); }
  227.         }
  228.         private bool isRunning = false;
  229.         /// <summary>
  230.         /// WorkStatus是否正在运行
  231.         /// </summary>
  232.         public bool IsRunning
  233.         {
  234.             get { return isRunning; }
  235.             set { isRunning = value; OnPropertyChanged("IsRunning"); }
  236.         }
  237.         private string _Parameter1;
  238.         /// <summary>
  239.         /// 公用参数1
  240.         /// </summary>
  241.         public string Parameter1
  242.         {
  243.             get { return _Parameter1; }
  244.             set { _Parameter1 = value; OnPropertyChanged("Parameter1"); }
  245.         }
  246.         private string _Parameter2;
  247.         /// <summary>
  248.         /// 公用参数2
  249.         /// </summary>
  250.         public string Parameter2
  251.         {
  252.             get { return _Parameter2; }
  253.             set { _Parameter2 = value; OnPropertyChanged("Parameter2"); }
  254.         }
  255.         private string _Parameter3;
  256.         /// <summary>
  257.         /// 公用参数3
  258.         /// </summary>
  259.         public string Parameter3
  260.         {
  261.             get { return _Parameter3; }
  262.             set { _Parameter3 = value; OnPropertyChanged("Parameter3"); }
  263.         }
  264.         private string _Parameter4;
  265.         /// <summary>
  266.         /// 公用参数4
  267.         /// </summary>
  268.         public string Parameter4
  269.         {
  270.             get { return _Parameter4; }
  271.             set { _Parameter4 = value; OnPropertyChanged("Parameter4"); }
  272.         }
  273.         private string _Parameter5;
  274.         /// <summary>
  275.         /// 公用参数5
  276.         /// </summary>
  277.         public string Parameter5
  278.         {
  279.             get { return _Parameter5; }
  280.             set { _Parameter5 = value; OnPropertyChanged("Parameter5"); }
  281.         }
  282.         private string _Parameter6;
  283.         /// <summary>
  284.         /// 公用参数6
  285.         /// </summary>
  286.         public string Parameter6
  287.         {
  288.             get { return _Parameter6; }
  289.             set { _Parameter6 = value; OnPropertyChanged("Parameter6"); }
  290.         }
  291.         private string _Parameter7;
  292.         /// <summary>
  293.         /// 公用参数7
  294.         /// </summary>
  295.         public string Parameter7
  296.         {
  297.             get { return _Parameter7; }
  298.             set { _Parameter7 = value; OnPropertyChanged("Parameter7"); }
  299.         }
  300.         private string _Parameter8;
  301.         /// <summary>
  302.         /// 公用参数8
  303.         /// </summary>
  304.         public string Parameter8
  305.         {
  306.             get { return _Parameter8; }
  307.             set { _Parameter8 = value; OnPropertyChanged("Parameter8"); }
  308.         }
  309.         private string _Parameter9;
  310.         /// <summary>
  311.         /// 公用参数9
  312.         /// </summary>
  313.         public string Parameter9
  314.         {
  315.             get { return _Parameter9; }
  316.             set { _Parameter9 = value; OnPropertyChanged("Parameter9"); }
  317.         }
  318.         private int packagePCS;
  319.         /// <summary>
  320.         /// 二级包装,PCS数量
  321.         /// </summary>
  322.         public int PackagePCS_Count
  323.         {
  324.             get { return packagePCS; }
  325.             set { packagePCS = value; OnPropertyChanged("PackagePCS_Count"); }
  326.         }
  327.         private bool isEndPacking=false;
  328.         /// <summary>
  329.         /// 是否是在装尾箱
  330.         /// </summary>
  331.         public bool IsEndPacking
  332.         {
  333.             get { return isEndPacking; }
  334.             set { isEndPacking= value; OnPropertyChanged("IsEndPacking"); }
  335.         }
  336.   
  337.         private int _WorkEndNumber;
  338.         public int WorkEndNumber
  339.         {
  340.             get { return _WorkEndNumber; }
  341.             set
  342.             {
  343.                 _WorkEndNumber = value;
  344.                 OnPropertyChanged("WorkEndNumber");
  345.             }
  346.         }
  347.         public void RaiseCustomEvent(object sender, string eventType, string portKey, string portName, object data)
  348.         {
  349.             RaiseCustomEvent(sender, eventType, portKey, portName, data, null);
  350.         }
  351.         public void RaiseCustomEvent(object sender, string eventType, string portKey, string portName, object data,
  352.             object extend)
  353.         {
  354.             if (FlowCustomEvent != null)
  355.             {
  356.                 EventClass ec = new EventClass(sender, eventType, portKey, portName, data, extend);
  357.                 FlowCustomEvent(this, new TEventArgs<EventClass>(ec));
  358.             }
  359.         }
  360.         /// <summary>
  361.         /// 重置上下文
  362.         /// </summary>
  363.         public void ResetContext()
  364.         {
  365.             OrderNo = string.Empty;
  366.             MaterielCode = string.Empty;
  367.             Progress = 0;
  368.             L1Code = string.Empty;
  369.             L1Count = 0;
  370.             L2Code = "";
  371.             L2Count = 0;
  372.             L1CountEx = 0;
  373.             TraySpecifications = "";
  374.             Parameter1 = "";
  375.             Parameter2 = "";
  376.             Parameter3 = "";
  377.             Parameter4 = "";
  378.             Parameter5 = "";
  379.             Parameter6 = "";
  380.             Parameter7 = "";
  381.             Parameter8 = "";
  382.             Parameter9 = "";
  383.             IsEndPacking = false;
  384.         }
  385.     }
  386. }
复制代码
  好了,我的言传就是这样。我的表达能力就只能到这样了。
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册