using Advantech.Motion; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using AssistClient.Device; using AssistClient.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml.Linq; namespace AssistClient.UI { public partial class UIIOCardDev : UserControl { SynchronizationContext SyncContext = null; public Action GetParamsEvent; // private IOCardDevProp prop = new IOCardDevProp(Config.IOCard_DeviceNum); private IOCardDev dev; public Action IOOutEvent; public UIIOCardDev() { InitializeComponent(); propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged; refreshUIState(); //获取UI线程同步上下文 SyncContext = SynchronizationContext.Current; //init(); } private void refreshUIState() { foreach (ToolStripItem item in this.toolStrip1.Items) { if (item.Text == "打开设备") item.Visible = (dev == null || !dev.IsInit); else this.propertyGrid1.Enabled = item.Enabled = !(dev == null || !dev.IsInit); } } public void init() { this.tbtnSave.Visible = tssSave.Visible = (GetParamsEvent != null); this.propertyGrid1.SelectedObject = prop; dev = new IOCardDev(); dev.WarningEvent = (level, info) => { txtLog.Text = $"({level}){info}"; }; //IN dev.INEvent += new System.Action((portIndex, data) => { if (prop.IN == null) prop.IN = dev.DIData; prop.IN[portIndex] = data; string s = Convert.ToString(data, 2).PadLeft(8, '0').Replace('0', 'L').Replace('1', 'H'); prop.IN_SHOW[portIndex] = s.Substring(0, 4) + " " + s.Substring(4); this.refreshUI(); if (prop.Direction == IODirectionEnum.输入输出) { bool isok = Util.compareIOInput(prop.IN_OP_SHOW, prop.IN); if (isok) { string[] OUT_OP_SHOW = Utils.Util.IODataFormatBinaryStr(prop.OUT_OP_SHOW, true); for (int i = 0; i < OUT_OP_SHOW.Length; i++) { for (int j = 0; j < OUT_OP_SHOW[i].Length; j++) { int jj = OUT_OP_SHOW[i].Length - j - 1; if (OUT_OP_SHOW[i][jj] == 'L' || OUT_OP_SHOW[i][jj] == 'H') dev.writeBitState(i, j, OUT_OP_SHOW[i][jj] == 'H'); } } } } }); //OUT dev.OUTEvent += new System.Action((portIndex, data) => { if (prop.OUT == null) prop.OUT = dev.DOData; prop.OUT[portIndex] = data; string s = Convert.ToString(data, 2).PadLeft(8, '0').Replace('0', 'L').Replace('1', 'H'); prop.OUT_SHOW[portIndex] = s.Substring(0, 4) + " " + s.Substring(4); IOOutEvent?.Invoke(); this.refreshUI(); }); if (!dev.start(prop.DeviceNum)) { this.closeDev(); return; } prop.IN = new byte[dev.DIPortCount]; prop.OUT = dev.DOData; this.refreshUI(); refreshUIState(); } public string getParamsData() { return prop.serialize(); } public void setParamsData(string json) { if (json == "") return; prop.deserialize(json); this.propertyGrid1.Refresh(); } private void refreshUI() { SyncContext.Post(m => { var result = m as string; propertyGrid1.Refresh(); //tbtnJogOnOff.Text = (prop.AxState == AxisState.STA_AX_EXT_JOG) ? "关闭Jog" : "开启Jog"; //tbtnLeft.Enabled = tbtnRight.Enabled = (prop.AxState == AxisState.STA_AX_EXT_JOG); }, "异步操作完成结果"); } private void closeDev() { try { if (dev == null) return; dev.stop(); } catch (Exception ex) { refreshUIState(); MessageBox.Show(ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Error); } } protected override void OnHandleDestroyed(EventArgs e) { base.OnHandleDestroyed(e); // 在此添加需要手动释放资源的代码 this.closeDev(); } private void tbtnRun_Click(object sender, EventArgs e) { try { if (prop.Direction == IODirectionEnum.输出) { string[] OUT_OP_SHOW = Utils.Util.IODataFormatBinaryStr(prop.OUT_OP_SHOW,true); for (int i = 0; i < OUT_OP_SHOW.Length; i++) { for (int j = 0; j < OUT_OP_SHOW[i].Length; j++) { int jj = OUT_OP_SHOW[i].Length - j - 1; if (OUT_OP_SHOW[i][jj] == 'L' || OUT_OP_SHOW[i][jj] == 'H') dev.writeBitState(i, j, OUT_OP_SHOW[i][jj] == 'H'); } } } //running... } catch(Exception ex) { MessageBox.Show(ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void tbtnExport_Click(object sender, EventArgs e) { this.propertyGrid1.Refresh(); string filePath = FileUtil.saveAsFile($"IOCard配置.json", "JSON|*.json"); if (filePath != "") { string jsonText = prop.serialize(); File.WriteAllText(filePath, jsonText); MessageBox.Show("保存成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void tbtnImport_Click(object sender, EventArgs e) { string filePath = FileUtil.openFile("JSON|*.json"); if (filePath != "") { string jsonText = File.ReadAllText(filePath); prop.deserialize(jsonText); this.propertyGrid1.Refresh(); //this.propertyGrid1.SelectedObject= prop; //MessageBox.Show("加载成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { //其中包含了两个重要的属性:OldValue和ChangeItem。 //ChangeItem是“PropertyDescriptorGridEntry”类型。一般可以通过ChangeItem.PropertyDescriptor.ComponentType查找到属性的实际类型。 //而通过ChangeItem的Label,则可以查看到当前在属性编辑输入框中显示的值。 string className = e.ChangedItem.PropertyDescriptor.ComponentType.Name; string propertyName = e.ChangedItem.PropertyDescriptor.Name; var oldValue = e.OldValue; var newValue = e.ChangedItem.Value; switch (propertyName) { case "AxisIndex"://prop.propName //refreshAxisVelParam(); break; } } private void tbtnSave_Click(object sender, EventArgs e) { GetParamsEvent?.Invoke(prop.serialize()); } private void tsbtnOpenDev_Click(object sender, EventArgs e) { this.init(); } private void toolStripButton1_Click(object sender, EventArgs e) { this.propertyGrid1.Refresh(); } } }