版博士V2.0程序
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

244 líneas
8.4 KiB

  1. using Advantech.Motion;
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. using ProductionControl.Device;
  5. using ProductionControl.Utils;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.ComponentModel;
  9. using System.Data;
  10. using System.Drawing;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using System.Windows.Forms;
  17. using System.Xml.Linq;
  18. namespace ProductionControl.UI
  19. {
  20. public partial class UIIOCardDev : UserControl
  21. {
  22. SynchronizationContext SyncContext = null;
  23. public Action<string> GetParamsEvent;
  24. //
  25. private IOCardDevProp prop = new IOCardDevProp(Config.IOCard_DeviceNum);
  26. private IOCardDev dev;
  27. public Action IOOutEvent;
  28. public UIIOCardDev()
  29. {
  30. InitializeComponent();
  31. propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;
  32. refreshUIState();
  33. //获取UI线程同步上下文
  34. SyncContext = SynchronizationContext.Current;
  35. //init();
  36. }
  37. private void refreshUIState()
  38. {
  39. foreach (ToolStripItem item in this.toolStrip1.Items)
  40. {
  41. if (item.Text == "打开设备")
  42. item.Visible = (dev == null || !dev.IsInit);
  43. else
  44. this.propertyGrid1.Enabled = item.Enabled = !(dev == null || !dev.IsInit);
  45. }
  46. }
  47. public void init()
  48. {
  49. this.tbtnSave.Visible = tssSave.Visible = (GetParamsEvent != null);
  50. this.propertyGrid1.SelectedObject = prop;
  51. dev = new IOCardDev();
  52. dev.WarningEvent = (level, info) =>
  53. {
  54. txtLog.Text = $"({level}){info}";
  55. };
  56. //IN
  57. dev.INEvent += new System.Action<int, byte>((portIndex, data) =>
  58. {
  59. if (prop.IN == null)
  60. prop.IN = dev.DIData;
  61. prop.IN[portIndex] = data;
  62. string s = Convert.ToString(data, 2).PadLeft(8, '0').Replace('0', 'L').Replace('1', 'H');
  63. prop.IN_SHOW[portIndex] = s.Substring(0, 4) + " " + s.Substring(4);
  64. this.refreshUI();
  65. if (prop.Direction == IODirectionEnum.输入输出)
  66. {
  67. bool isok = Util.compareIOInput(prop.IN_OP_SHOW, prop.IN);
  68. if (isok)
  69. {
  70. string[] OUT_OP_SHOW = Utils.Util.IODataFormatBinaryStr(prop.OUT_OP_SHOW, true);
  71. for (int i = 0; i < OUT_OP_SHOW.Length; i++)
  72. {
  73. for (int j = 0; j < OUT_OP_SHOW[i].Length; j++)
  74. {
  75. int jj = OUT_OP_SHOW[i].Length - j - 1;
  76. if (OUT_OP_SHOW[i][jj] == 'L' || OUT_OP_SHOW[i][jj] == 'H')
  77. dev.writeBitState(i, j, OUT_OP_SHOW[i][jj] == 'H');
  78. }
  79. }
  80. }
  81. }
  82. });
  83. //OUT
  84. dev.OUTEvent += new System.Action<int, byte>((portIndex, data) =>
  85. {
  86. if (prop.OUT == null)
  87. prop.OUT = dev.DOData;
  88. prop.OUT[portIndex] = data;
  89. string s = Convert.ToString(data, 2).PadLeft(8, '0').Replace('0', 'L').Replace('1', 'H');
  90. prop.OUT_SHOW[portIndex] = s.Substring(0, 4) + " " + s.Substring(4);
  91. IOOutEvent?.Invoke();
  92. this.refreshUI();
  93. });
  94. if (!dev.start(prop.DeviceNum))
  95. {
  96. this.closeDev();
  97. return;
  98. }
  99. prop.IN = new byte[dev.DIPortCount];
  100. prop.OUT = dev.DOData;
  101. this.refreshUI();
  102. refreshUIState();
  103. }
  104. public string getParamsData()
  105. {
  106. return prop.serialize();
  107. }
  108. public void setParamsData(string json)
  109. {
  110. if (json == "") return;
  111. prop.deserialize(json);
  112. this.propertyGrid1.Refresh();
  113. }
  114. private void refreshUI()
  115. {
  116. SyncContext.Post(m =>
  117. {
  118. var result = m as string;
  119. propertyGrid1.Refresh();
  120. //tbtnJogOnOff.Text = (prop.AxState == AxisState.STA_AX_EXT_JOG) ? "关闭Jog" : "开启Jog";
  121. //tbtnLeft.Enabled = tbtnRight.Enabled = (prop.AxState == AxisState.STA_AX_EXT_JOG);
  122. }, "异步操作完成结果");
  123. }
  124. private void closeDev()
  125. {
  126. try
  127. {
  128. if (dev == null)
  129. return;
  130. dev.stop();
  131. }
  132. catch (Exception ex)
  133. {
  134. refreshUIState();
  135. MessageBox.Show(ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
  136. }
  137. }
  138. protected override void OnHandleDestroyed(EventArgs e)
  139. {
  140. base.OnHandleDestroyed(e);
  141. // 在此添加需要手动释放资源的代码
  142. this.closeDev();
  143. }
  144. private void tbtnRun_Click(object sender, EventArgs e)
  145. {
  146. try
  147. {
  148. if (prop.Direction == IODirectionEnum.输出)
  149. {
  150. string[] OUT_OP_SHOW = Utils.Util.IODataFormatBinaryStr(prop.OUT_OP_SHOW,true);
  151. for (int i = 0; i < OUT_OP_SHOW.Length; i++)
  152. {
  153. for (int j = 0; j < OUT_OP_SHOW[i].Length; j++)
  154. {
  155. int jj = OUT_OP_SHOW[i].Length - j - 1;
  156. if (OUT_OP_SHOW[i][jj] == 'L' || OUT_OP_SHOW[i][jj] == 'H')
  157. dev.writeBitState(i, j, OUT_OP_SHOW[i][jj] == 'H');
  158. }
  159. }
  160. }
  161. //running...
  162. }
  163. catch(Exception ex)
  164. {
  165. MessageBox.Show(ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
  166. }
  167. }
  168. private void tbtnExport_Click(object sender, EventArgs e)
  169. {
  170. this.propertyGrid1.Refresh();
  171. string filePath = FileUtil.saveAsFile($"IOCard配置.json", "JSON|*.json");
  172. if (filePath != "")
  173. {
  174. string jsonText = prop.serialize();
  175. File.WriteAllText(filePath, jsonText);
  176. MessageBox.Show("保存成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
  177. }
  178. }
  179. private void tbtnImport_Click(object sender, EventArgs e)
  180. {
  181. string filePath = FileUtil.selectFile("JSON|*.json");
  182. if (filePath != "")
  183. {
  184. string jsonText = File.ReadAllText(filePath);
  185. prop.deserialize(jsonText);
  186. this.propertyGrid1.Refresh();
  187. //this.propertyGrid1.SelectedObject= prop;
  188. //MessageBox.Show("加载成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
  189. }
  190. }
  191. private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
  192. {
  193. //其中包含了两个重要的属性:OldValue和ChangeItem。
  194. //ChangeItem是“PropertyDescriptorGridEntry”类型。一般可以通过ChangeItem.PropertyDescriptor.ComponentType查找到属性的实际类型。
  195. //而通过ChangeItem的Label,则可以查看到当前在属性编辑输入框中显示的值。
  196. string className = e.ChangedItem.PropertyDescriptor.ComponentType.Name;
  197. string propertyName = e.ChangedItem.PropertyDescriptor.Name;
  198. var oldValue = e.OldValue;
  199. var newValue = e.ChangedItem.Value;
  200. switch (propertyName)
  201. {
  202. case "AxisIndex"://prop.propName
  203. //refreshAxisVelParam();
  204. break;
  205. }
  206. }
  207. private void tbtnSave_Click(object sender, EventArgs e)
  208. {
  209. GetParamsEvent?.Invoke(prop.serialize());
  210. }
  211. private void tsbtnOpenDev_Click(object sender, EventArgs e)
  212. {
  213. this.init();
  214. }
  215. private void toolStripButton1_Click(object sender, EventArgs e)
  216. {
  217. this.propertyGrid1.Refresh();
  218. }
  219. }
  220. }