using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Drawing;
|
using System.Data;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
using Bro.Common.Interface;
|
|
namespace Bro.Common.Base.UI
|
{
|
public partial class CtrlPLCRunBase : UserControl, IRunCtrl
|
{
|
public CtrlPLCRunBase()
|
{
|
InitializeComponent();
|
}
|
|
public IDevice Device { get; set; }
|
protected PLCBase PLC
|
{
|
get => Device as PLCBase;
|
}
|
|
System.Threading.Timer _monitorLineChangedTimer = null;
|
System.Threading.Timer _refreshFrequenceChangedTimer = null;
|
System.Threading.Timer _refreshMonitorTimer = null;
|
public CtrlPLCRunBase(IDevice device)
|
{
|
InitializeComponent();
|
|
Device = device;
|
|
dgvMonitor.AutoGenerateColumns = false;
|
dgvMonitor.ReadOnly = true;
|
dgvMonitor.AllowUserToAddRows = false;
|
dgvMonitor.AllowUserToDeleteRows = false;
|
SetMonitorGrid();
|
|
_monitorLineChangedTimer = new System.Threading.Timer(OnMonitorLineChanged, null, -1, -1);
|
_refreshFrequenceChangedTimer = new System.Threading.Timer(OnRefreshFrequenceChanged, null, -1, -1);
|
_refreshMonitorTimer = new System.Threading.Timer(OnRefreshMonitorValues, null, 0, 1000);
|
|
cboFormat.SelectedIndex = 0;
|
cboFormat.SelectedIndexChanged += CboFormat_SelectedIndexChanged;
|
}
|
|
string _displayFormat = "G";
|
private void CboFormat_SelectedIndexChanged(object sender, EventArgs e)
|
{
|
switch (cboFormat.SelectedIndex)
|
{
|
case 0:
|
_displayFormat = "G";
|
break;
|
case 1:
|
_displayFormat = "X2";
|
break;
|
case 2:
|
_displayFormat = "";
|
break;
|
default:
|
break;
|
}
|
|
oldValues = null;
|
}
|
|
private void OnMonitorLineChanged(object state)
|
{
|
txtMonitorLines.Invoke(new Action(() =>
|
{
|
string temp = txtMonitorLines.Text.Trim();
|
|
if (!int.TryParse(temp, out int lines))
|
{
|
txtMonitorLines.Text = "10";
|
lines = 10;
|
}
|
|
MonitorLines = lines;
|
}));
|
}
|
|
int MonitorLines
|
{
|
get
|
{
|
string temp = txtMonitorLines.Text.Trim();
|
|
if (!int.TryParse(temp, out int lines))
|
{
|
txtMonitorLines.Text = "10";
|
lines = 10;
|
}
|
|
return lines;
|
}
|
set
|
{
|
SetMonitorGrid();
|
}
|
}
|
|
private void txtMonitorLines_TextChanged(object sender, EventArgs e)
|
{
|
_monitorLineChangedTimer.Change(1000, -1);
|
}
|
|
private void SetMonitorGrid()
|
{
|
int rowLines = MonitorLines;
|
|
dgvMonitor.Rows.Clear();
|
dgvMonitor.Columns.Clear();
|
|
for (int i = 0; i < PLC.PLCIConfig.EventLength; i++)
|
{
|
int rowNum = i % rowLines;
|
int colNum = i / rowLines;
|
|
if (dgvMonitor.Columns.Count <= colNum * 2)
|
{
|
var colAddr = new DataGridViewColumn(new DataGridViewTextBoxCell());
|
colAddr.HeaderText = "监听地址";
|
dgvMonitor.Columns.Add(colAddr);
|
|
var colValue = new DataGridViewColumn(new DataGridViewTextBoxCell());
|
colValue.HeaderText = "监听数值";
|
dgvMonitor.Columns.Add(colValue);
|
}
|
|
if (dgvMonitor.Rows.Count <= rowNum)
|
{
|
dgvMonitor.Rows.Add(new DataGridViewRow());
|
}
|
|
dgvMonitor.Rows[rowNum].Cells[colNum * 2].Value = (PLC.PLCIConfig.EventStartAddress + i).ToString();
|
dgvMonitor.Rows[rowNum].Cells[colNum * 2 + 1].Value = "";
|
}
|
}
|
|
int RefreshFrequence
|
{
|
get
|
{
|
string temp = txtRefreshFrequence.Text.Trim();
|
|
if (!int.TryParse(temp, out int freq))
|
{
|
txtRefreshFrequence.Text = "1000";
|
freq = 1000;
|
}
|
|
return freq;
|
}
|
set
|
{
|
SetRefreshFrequence();
|
}
|
}
|
|
private void SetRefreshFrequence()
|
{
|
_refreshMonitorTimer.Change(RefreshFrequence, RefreshFrequence);
|
}
|
|
private void txtRefreshFrequence_TextChanged(object sender, EventArgs e)
|
{
|
_refreshFrequenceChangedTimer.Change(1000, -1);
|
}
|
|
private void OnRefreshFrequenceChanged(object state)
|
{
|
txtRefreshFrequence.Invoke(new Action(() =>
|
{
|
string temp = txtRefreshFrequence.Text.Trim();
|
|
if (!int.TryParse(temp, out int freq))
|
{
|
txtRefreshFrequence.Text = "1000";
|
freq = 1000;
|
}
|
|
RefreshFrequence = freq;
|
}));
|
}
|
|
List<int> oldValues = null;
|
Dictionary<int, System.Threading.Timer> _cellChangedTimerDict = new Dictionary<int, System.Threading.Timer>();
|
private void OnRefreshMonitorValues(object state)
|
{
|
if (PLC.CurrentState != Helper.EnumHelper.DeviceState.DSOpen)
|
return;
|
|
List<int> newValues = new List<int>(PLC.MonitorValues);
|
|
if (oldValues == null || oldValues.Count != newValues.Count)
|
{
|
for (int i = 0; i < newValues.Count; i++)
|
{
|
int rowNum = i % MonitorLines;
|
int colNum = i / MonitorLines;
|
|
//string displayStr = "";
|
//if (_displayFormat != "")
|
//{
|
// displayStr = newValues[i].ToString(_displayFormat);
|
//}
|
//else
|
//{
|
// displayStr = ConvertToBinaryString(newValues[i]);
|
//}
|
dgvMonitor.Rows[rowNum].Cells[colNum * 2 + 1].Value = GetSignedShortValue(newValues[i]);
|
}
|
}
|
else
|
{
|
for (int i = 0; i < oldValues.Count; i++)
|
{
|
if (oldValues[i] != newValues[i])
|
{
|
int rowNum = i % MonitorLines;
|
int colNum = i / MonitorLines;
|
|
var cell = dgvMonitor.Rows[rowNum].Cells[colNum * 2 + 1];
|
|
//string displayStr = "";
|
//if (_displayFormat != "")
|
//{
|
// displayStr = newValues[i].ToString(_displayFormat);
|
//}
|
//else
|
//{
|
// displayStr = ConvertToBinaryString(newValues[i]);
|
//}
|
|
//cell.Value = displayStr;
|
cell.Value = GetSignedShortValue(newValues[i]);
|
cell.Style.BackColor = Color.PaleGreen;
|
cell.Style.ForeColor = Color.Red;
|
|
if (!_cellChangedTimerDict.ContainsKey(i))
|
{
|
_cellChangedTimerDict[i] = new System.Threading.Timer(OnChangedDisplayTimeout, new object[] { cell, i }, 1000, -1);
|
}
|
else
|
{
|
_cellChangedTimerDict[i].Change(1000, -1);
|
}
|
}
|
}
|
}
|
|
oldValues = new List<int>(newValues);
|
}
|
|
private string GetSignedShortValue(int v)
|
{
|
string displayStr = "";
|
switch (_displayFormat)
|
{
|
case "G":
|
displayStr = ((short)v).ToString(_displayFormat);
|
break;
|
case "X2":
|
displayStr = "0x" + ((short)v).ToString(_displayFormat);
|
break;
|
case "":
|
displayStr = ConvertToBinaryString((short)v);
|
break;
|
default:
|
break;
|
}
|
|
return displayStr;
|
}
|
private string ConvertToBinaryString(short origin)
|
{
|
string binStr = "";
|
|
//int length = v / 2;
|
//if (v % 2 > 0)
|
//{
|
// length++;
|
//}
|
|
//if (length == 0)
|
// length++;
|
|
//for (int i = 0; i < length; i++)
|
//{
|
// binStr += (v >> i & 1).ToString();
|
//}
|
|
//int origin = v;
|
if (origin == 0)
|
return "00000000";
|
|
bool isNegative = false;
|
if (origin < 0)
|
{
|
origin = (short)(0 - origin);
|
isNegative = true;
|
}
|
|
do
|
{
|
int addtional = origin % 2;
|
binStr = (addtional.ToString() + binStr);
|
|
origin = (short)(origin / (short)2);
|
} while (origin != 1);
|
|
binStr = ("1" + binStr).PadLeft(8, '0');
|
|
if (isNegative)
|
{
|
var list = binStr.ToList().ConvertAll(s => s == '1' ? "0" : "1");
|
|
int last0Index = list.LastIndexOf("0");
|
|
for (int i = last0Index; i < list.Count; i++)
|
{
|
list[i] = list[i] == "0" ? "1" : "0";
|
}
|
|
binStr = string.Join("", list);
|
}
|
|
return binStr;
|
}
|
|
private void OnChangedDisplayTimeout(object state)
|
{
|
DataGridViewCell cell = (DataGridViewCell)((state as object[])[0]);
|
int index = (int)((state as object[])[1]);
|
|
cell.Style.BackColor = SystemColors.Control;
|
cell.Style.ForeColor = SystemColors.ControlText;
|
|
_cellChangedTimerDict.Remove(index);
|
}
|
}
|
|
|
}
|