private void BarEditItem8_OnEditValueChanged(object sender, RoutedEventArgs e) { //显示 string value = (sender as BarEditItem).EditValue.ToString(); if (cvMain != null) { cvMain.ShowGrid = SafeConverter.SafeToBool(value); } }
private void BarEditItem7_OnEditValueChanged(object sender, RoutedEventArgs e) { string value = SafeConverter.SafeToStr((sender as BarEditItem).EditValue); if (string.IsNullOrEmpty(value)) { return; } foreach (DragThumb thumb in cvMain.SelectDragThumbs) { thumb.MonitorItem = SafeConverter.SafeToBool(value); } }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) { return(Visibility.Collapsed); } string checkValue = SafeConverter.SafeToStr(parameter); if (string.IsNullOrEmpty(checkValue)) //没有参数 { return(SafeConverter.SafeToBool(value) ? Visibility.Visible : Visibility.Collapsed); } else { string sValue = SafeConverter.SafeToStr(value); List <string> checks = checkValue.Split(';').ToList(); return((checks.Contains(sValue)) ? Visibility.Visible : Visibility.Collapsed); } }
/// <summary> /// 自动计算标签值 /// 采用动态代码执行方式,编译一次,采用参数传入的方式执行 /// </summary> private void ThreadAutoCalculation() { Type dynamicCode = null; //获取编译后代码,调用该类用 List <FmsTagCalculation> TagCalculations = null; //计算规则 Dictionary <string, Dictionary <string, string> > FuncAndParamTagPKNO = new Dictionary <string, Dictionary <string, string> >(); //函数和对应参数的Tag的PKNO while (!CBaseData.AppClosing) { #region 暂停 if (bPause) { System.Threading.Thread.Sleep(200); continue; } #endregion try { int index; if (bRefreshAutoCal) //刷新计算规则 { WcfClient <IFMSService> wsThis = new WcfClient <IFMSService>(); TagCalculations = wsThis.UseService(s => s.GetFmsTagCalculations("USE_FLAG = 1")); bRefreshAutoCal = false; if ((TagCalculations == null) || (!TagCalculations.Any())) { Thread.Sleep(500); continue; } string className = "C" + Guid.NewGuid().ToString("N"); #region 形成执行的代码 string execCode = "using System; \r\n" + "using System.Text; \r\n" + "using System.Collections.Generic; \r\n" + "using BFM.Common.Base; \r\n\r\n"; execCode += "public class " + className + "\r\n" + "{ \r\n"; string basicFuc = "AutoCalculation"; index = 1; FuncAndParamTagPKNO.Clear(); foreach (FmsTagCalculation calculation in TagCalculations) { FmsAssetTagSetting tagResult = GetTagSettingById(calculation.RESULT_TAG_PKNO); //结果 string exp = calculation.CALCULATION_EXPRESSION; //表达式 string funcname = basicFuc + index.ToString(); //函数名称 Dictionary <string, string> paramTas = new Dictionary <string, string>(); //参数对应的标签的PKNO, param List <string> funcParam = new List <string>(); //带类型的参数 string code = ""; string resultType = "string"; //将标签替换成参数名 foreach (var line in exp.Split(new string[] { "\r\n" }, StringSplitOptions.None)) { string ret = line; #region 替换标签值,将标签替换成参数名 string[] expTags = line.Split('{'); for (int i = 0; i < expTags.Length; i++) { string str = expTags[i]; int length = str.IndexOf('}'); if (length < 0) //没有找到 } { continue; } string tagPKNO = str.Substring(0, length); //{ } 内为PKNO string param = "{" + tagPKNO + "}"; if (paramTas.ContainsKey(tagPKNO)) //已经添加了该参数 { param = paramTas[tagPKNO]; } else { FmsAssetTagSetting tag = GetTagSettingById(tagPKNO); if (tag == null) { continue; } param = "param" + paramTas.Count; paramTas.Add(tagPKNO, param); string paramType = "string"; //所有参数传入都是string型 //string paramType = // ((calculation.CALCULATION_TYPE == 2) || // (tag.VALUE_TYPE > 0 && tag.VALUE_TYPE < 20)) // ? "double" // : "string"; funcParam.Add(paramType + " " + param); } ret = ret.Replace("{" + tagPKNO + "}", param); } #endregion if (string.IsNullOrEmpty(code)) { code = " " + ret; } else { code += Environment.NewLine + " " + ret; } } //确定返回结果类型,将code语句转换成C#的语句 if (calculation.CALCULATION_TYPE == 1) //逻辑运算 { //(结果为1,0):({标签1}==1)&&({标签2}==1)&&({标签3}==0||{标签4}==0)&&({标签5}==1) code = code.Replace("AND", "&&").Replace("and", "&&").Replace("OR", "||").Replace("or", "||"); resultType = "bool"; } else if (calculation.CALCULATION_TYPE == 2) //数值运算 { //{标签1}+3+{标签2}+4 resultType = "double"; } else if (calculation.CALCULATION_TYPE == 3) //字符运算 { //{标签1}+"123" } else if (calculation.CALCULATION_TYPE == 12) //条件数值运算 { //{标签1}==3:{标签2}+1;{标签1}==4:{标签2}+2;{标签1}==5:{标签2}+3 resultType = "double"; List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + "); } \r\n"; } temp += " return 0; \r\n"; code = temp; } else if (calculation.CALCULATION_TYPE == 13) //条件字符运算 { //{标签1}==3:{标签1}+"123";{标签1}==4:{标签1}+"123" List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + ").ToString(); } \r\n"; } temp += " return \"\"; \r\n"; code = temp; } else if (calculation.CALCULATION_TYPE == 100) //C#脚本 { //支持C#语法,最后返回值(Double/String) resultType = "string"; } else //不支持的类型 { code = $" return \"计算类型[{calculation.CALCULATION_TYPE}],不支持的类型。\"; \r\n"; } execCode += DynamicCode.BuildExecFunc(funcname, resultType, code, funcParam); //增加一个函数 index++; FuncAndParamTagPKNO.Add(funcname, paramTas); //添加 } execCode += "}\r\n"; #endregion #region 编译代码 CodeDomProvider compiler = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true, }; cp.ReferencedAssemblies.Add("BFM.Common.Base.dll"); CompilerResults cr = compiler.CompileAssemblyFromSource(cp, execCode); if (cr.Errors.HasErrors) { NetLog.Error("DeviceMonitor.ThreadAutoCalculation Invaild Code: :" + execCode); } dynamicCode = cr.CompiledAssembly.GetType(className); //获取 #endregion } if ((TagCalculations == null) || (!TagCalculations.Any()) || (dynamicCode == null) || (FuncAndParamTagPKNO.Count <= 0)) { Thread.Sleep(500); continue; } #region 获取值 index = 0; foreach (FmsTagCalculation calculation in TagCalculations) { FmsAssetTagSetting tagResult = GetTagSettingById(calculation.RESULT_TAG_PKNO); //结果 if (tagResult == null) { continue; } if (FuncAndParamTagPKNO.Count < index) { break; } string funcName = FuncAndParamTagPKNO.Keys.ToList()[index]; var tagParms = FuncAndParamTagPKNO.Values.ToList()[index]; List <object> paramValues = new List <object>(); //参数值 foreach (var tagpkno in tagParms) //参数 { object value = null; FmsAssetTagSetting tagParam = GetTagSettingById(tagpkno.Key); if (tagParam != null) { value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //if ((calculation.CALCULATION_TYPE == 2) || (tagParam.VALUE_TYPE > 0 && tagParam.VALUE_TYPE < 20)) //{ // value = SafeConverter.SafeToDouble(tagParam.CUR_VALUE); //} //else //{ // value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //} } else { value = ""; } paramValues.Add(value); } object obj = dynamicCode.InvokeMember(funcName, BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, System.Type.DefaultBinder, null, paramValues.ToArray()); string newValue = ""; //新的计算结果 #region 更新结果 if (calculation.CALCULATION_TYPE == 1) //逻辑运算 { newValue = SafeConverter.SafeToBool(obj) ? "1" : "0"; } else { newValue = SafeConverter.SafeToStr(obj); } SaveData(tagResult.PKNO, newValue); //保存更新值 #endregion index++; } #endregion } catch (Exception e) { NetLog.Error("DeviceMonitor.ThreadAutoCalculation error:", e); } Thread.Sleep(100); } }
public bool LoadFile(string filePath) { if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) { return(false); } XDocument xmlDoc = new XDocument(); xmlDoc = XDocument.Load(filePath); XElement root = xmlDoc.Elements("root").FirstOrDefault(); if (root == null) { return(false); } XElement drags = root.Elements("FlowDesigns").FirstOrDefault(); if (drags == null) { return(false); } RemoveAllDragThumb(); //清除所有 IEnumerable <XElement> nodes = drags.Elements(); foreach (XElement item in nodes) { string name = item.Attribute("Name")?.Value ?? ""; string position = item.Attribute("Position")?.Value ?? "0,0"; string size = item.Attribute("Size")?.Value ?? "10,10"; string source = item.Attribute("Source")?.Value ?? ""; //图片路径 string sBackground = item.Attribute("Background")?.Value ?? "#FF00ACFF"; //背景色 Brush background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(sBackground)); string sBorderBrush = item.Attribute("BorderBrush")?.Value ?? "White"; //边框 Brush borderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(sBorderBrush)); EmFlowCtrlType ctrlType = (EmFlowCtrlType) System.Enum.Parse(typeof(EmFlowCtrlType), item.Attribute("ItemType")?.Value ?? "None"); //控件类型 EmBasicShape shapeType = (EmBasicShape)System.Enum.Parse(typeof(EmBasicShape), item.Attribute("Shape")?.Value ?? "None"); DragThumb newThumb = new DragThumb(); if (ctrlType == EmFlowCtrlType.Image) { if (!source.Contains(":")) { source = System.Environment.CurrentDirectory + (source[0] == '/' ? "" : "/") + source; } if (File.Exists(source)) { newThumb = AddDragImage(name, SafeConverter.SafeToSize(size), SafeConverter.SafeToPoint(position), new BitmapImage(new Uri(source)), background, borderBrush); } } else if (ctrlType == EmFlowCtrlType.PolygonSharp) { newThumb = AddDragShape(name, shapeType, SafeConverter.SafeToSize(size), SafeConverter.SafeToPoint(position), background, borderBrush); } else if (ctrlType == EmFlowCtrlType.CircleSharp) { newThumb = AddDragCircle(name, SafeConverter.SafeToSize(size), SafeConverter.SafeToPoint(position), background, borderBrush); } else if (ctrlType == EmFlowCtrlType.Video) { newThumb = AddDragVideo(name, SafeConverter.SafeToSize(size), SafeConverter.SafeToPoint(position), source); } string sForeground = item.Attribute("Foreground")?.Value ?? "#FF000000"; //字体颜色 Brush foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(sForeground)); newThumb.Foreground = foreground; string sFontWeight = item.Attribute("FontWeight")?.Value ?? "Normal"; //文本粗体 FontWeightConverter convert = new FontWeightConverter(); newThumb.FontWeight = (FontWeight)convert.ConvertFromString(sFontWeight); string sFontSize = item.Attribute("FontSize")?.Value ?? "12"; //文字大小 newThumb.FontSize = Double.Parse(sFontSize); newThumb.MonitorItem = SafeConverter.SafeToBool(item.Attribute("Monitor")); //是否监控 newThumb.ReadOnlyCanClick = SafeConverter.SafeToBool(item.Attribute("ReadOnlyCanClick")); //是否可以单击 string text = item.Attribute("Text")?.Value ?? ""; newThumb.Text = text; } return(true); }
//测试 private void BtnTest_Click(object sender, RoutedEventArgs e) { TbTestResult.Text = ""; RefreshCalculationText(); Type dynamicCode = null; //获取编译后代码,调用该类用 Dictionary <string, Dictionary <string, string> > FuncAndParamTagPKNO = new Dictionary <string, Dictionary <string, string> >(); //函数和对应参数的Tag的PKNO string className = "C" + Guid.NewGuid().ToString("N"); try { Cursor = Cursors.Wait; #region 形成执行的代码 string execCode = "using System; \r\n" + "using System.Text; \r\n" + "using System.Collections.Generic; \r\n" + "using BFM.Common.Base; \r\n\r\n"; execCode += "public class " + className + "\r\n" + "{ \r\n"; string basicFuc = "AutoCalculation"; int index = 1; FuncAndParamTagPKNO.Clear(); string exp = CalculationText; //表达式 string funcname = basicFuc + index.ToString(); //函数名称 Dictionary <string, string> paramTas = new Dictionary <string, string>(); //参数对应的标签的PKNO, param名称 List <string> funcParam = new List <string>(); //带类型的参数 string code = ""; foreach (var line in exp.Split(new string[] { "\r\n" }, StringSplitOptions.None)) { string ret = line; #region 替换标签值,将标签替换成参数名 string[] expTags = line.Split('{'); for (int i = 0; i < expTags.Length; i++) { string str = expTags[i]; int length = str.IndexOf('}'); if (length < 0) //没有找到 } { continue; } string tagPKNO = str.Substring(0, length); //{ } 内为PKNO string param = "{" + tagPKNO + "}"; if (paramTas.ContainsKey(tagPKNO)) //已经添加了该参数 { param = paramTas[tagPKNO]; } else { FmsAssetTagSetting tag = DeviceTags.FirstOrDefault(s => s.PKNO == tagPKNO); if (tag == null) { continue; } param = "param" + paramTas.Count; paramTas.Add(tagPKNO, param); string paramType = "string"; //string paramType = ((CalculationType == 2) || (tag.VALUE_TYPE > 0 && tag.VALUE_TYPE < 20)) // ? "double" // : "string"; funcParam.Add(paramType + " " + param); } ret = ret.Replace("{" + tagPKNO + "}", param); } #endregion if (string.IsNullOrEmpty(code)) { code = " " + ret; } else { code += Environment.NewLine + " " + ret; } } //C#脚本 //支持C#语法,最后返回值(Double/String) string resultType = "string"; //确定返回结果类型,将code语句转换成C#的语句 if (CalculationType == 1) //逻辑运算 { //(结果为1,0):({标签1}==1)&&({标签2}==1)&&({标签3}==0||{标签4}==0)&&({标签5}==1) code = code.Replace("AND", "&&").Replace("and", "&&").Replace("OR", "||").Replace("or", "||"); resultType = "bool"; } else if (CalculationType == 2) //数值运算 { //{标签1}+3+{标签2}+4 resultType = "double"; } else if (CalculationType == 3) //字符运算 { //{标签1}+"123" } else if (CalculationType == 12) //条件数值运算 { //{标签1}==3:{标签2}+1;{标签1}==4:{标签2}+2;{标签1}==5:{标签2}+3 resultType = "double"; List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + "); } \r\n"; } temp += " return 0; \r\n"; code = temp; } else if (CalculationType == 13) //条件字符运算 { //{标签1}==3:{标签1}+"123";{标签1}==4:{标签1}+"123" List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + ").ToString(); } \r\n"; } temp += " return \"\"; \r\n"; code = temp; } else if (CalculationType == 21) { resultType = "string";//{标签1};3 List <string> exps = code.Split(';').ToList(); string temp = ""; if (exps.Count >= 2) { int arrayIndex = SafeConverter.SafeToInt(exps[1].Trim(), 0); temp += " if ( " + exps[0].Trim() + ".Split('|').Length > " + arrayIndex + ") { return " + exps[0].Trim() + ".Split('|')[" + arrayIndex + "]; } \r\n"; } temp += " return \"\"; \r\n"; code = temp; } else if (CalculationType == 100) //C#脚本 { //支持C#语法,最后返回值(Double/String) resultType = "string"; } else //不支持的类型 { code = $" return \"计算类型[{CalculationType}],不支持的类型。\"; \r\n"; } execCode += DynamicCode.BuildExecFunc(funcname, resultType, code, funcParam); FuncAndParamTagPKNO.Add(funcname, paramTas); //添加 execCode += "}\r\n"; #endregion #region 编译代码 CodeDomProvider compiler = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true, }; cp.ReferencedAssemblies.Add("BFM.Common.Base.dll"); CompilerResults cr = compiler.CompileAssemblyFromSource(cp, execCode); if (cr.Errors.HasErrors) { WPFMessageBox.ShowError("测试失败,语法错误.\r\n" + execCode, "测试"); return; } dynamicCode = cr.CompiledAssembly.GetType(className); //获取 #endregion #region 获取值 index = 0; string funcName = FuncAndParamTagPKNO.Keys.ToList()[index]; var tagParms = FuncAndParamTagPKNO.Values.ToList()[index]; List <object> paramValues = new List <object>(); //参数值 foreach (var tagpkno in tagParms) //参数 { object value; FmsAssetTagSetting tagParam = DeviceTags.FirstOrDefault(s => s.PKNO == tagpkno.Key); if (tagParam != null) { value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //if ((CalculationType == 2) || (tagParam.VALUE_TYPE > 0 && tagParam.VALUE_TYPE < 20)) //{ // value = SafeConverter.SafeToDouble(tagParam.CUR_VALUE); //} //else //{ // value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //} } else { value = ""; } paramValues.Add(value); } object obj = dynamicCode.InvokeMember(funcName, BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, System.Type.DefaultBinder, null, paramValues.ToArray()); string newValue = ""; //新的计算结果 if (CalculationType == 1) //逻辑运算 { newValue = SafeConverter.SafeToBool(obj) ? "1" : "0"; } else { newValue = SafeConverter.SafeToStr(obj); } Console.WriteLine("测试结果:" + newValue); TbTestResult.Text = newValue; #endregion WPFMessageBox.ShowInfo("测试成功. \r\n测试结果为:" + newValue, "测试"); } catch (Exception ex) { Console.WriteLine(ex); WPFMessageBox.ShowError("测试失败,错误为:" + ex.Message, "测试"); } finally { Cursor = Cursors.Arrow; } }
/// <summary> /// 解析地址 /// </summary> /// <param name="address">s=Station;f=读取功能;d=地址;l=长度</param> /// <param name="value">写入值</param> /// <param name="defFuncton">默认的功能</param> /// <param name="spkno">地址的PKNO,默认不需要获取反馈信息</param> private byte[] AnalysisWriteAddress(string address, string value, byte defFuncton, string spkno = "") { byte[] data = null; #region 解析Modbus地址 try { int station = 1; //Station byte function = defFuncton; // int modAddress = 0; //地址 int length = 1; GetModbusInfo(address, ref station, ref function, ref modAddress, ref length); if (length == 1) { value = value.Split('|')[0]; } if (function == WriteOneCoil) //写单个线圈 { data = new byte[6]; data[0] = (byte)station; data[1] = function; data[2] = BitConverter.GetBytes(modAddress)[1]; data[3] = BitConverter.GetBytes(modAddress)[0]; data[4] = (byte)(SafeConverter.SafeToBool(SafeConverter.SafeToInt(value.Split('|')[0])) ? 0xFF : 0x00); data[5] = 0x00; } else if (function == WriteOneRegister) //写单个寄存器 { data = new byte[6]; data[0] = (byte)station; data[1] = function; data[2] = BitConverter.GetBytes(modAddress)[1]; data[3] = BitConverter.GetBytes(modAddress)[0]; data[4] = BitConverter.GetBytes(SafeConverter.SafeToInt(value.Split('|')[0]))[1]; data[5] = BitConverter.GetBytes(SafeConverter.SafeToInt(value.Split('|')[0]))[0]; } else if (function == WriteCoil) //写多个线圈,目前只最多支持16位,注意需要设备支持 ++++++++++++++++需要测试++++++++++++++ { string[] values = value.Split('|'); string result = ""; for (int i = 0; i < length; i++) { if (i < values.Length) { result += SafeConverter.SafeToBool(values[i]) ? "1" : "0"; } else { result += "0"; } } byte innerlength = (byte)(Math.Ceiling(length * 1.0 / 8)); data = new byte[7 + innerlength]; int buf = Convert.ToInt16(result, 2); data[0] = (byte)station; data[1] = function; data[2] = BitConverter.GetBytes(modAddress)[1]; data[3] = BitConverter.GetBytes(modAddress)[0]; data[4] = BitConverter.GetBytes(length)[1]; data[5] = BitConverter.GetBytes(length)[0]; data[6] = innerlength; if (innerlength == 1) { data[7] = BitConverter.GetBytes(buf)[0]; } else if (innerlength == 2) { data[7] = BitConverter.GetBytes(buf)[1]; data[8] = BitConverter.GetBytes(buf)[0]; } } else if (function == WriteRegister) //写多个寄存器 { string[] values = value.Split('|'); byte[] buf = new byte[length * 2]; int index = 0; for (int i = 0; i < length; i++) //按照写入值得长度来确定 { string s = (values.Length > i) ? values[i] : "0"; buf[index++] = BitConverter.GetBytes(SafeConverter.SafeToInt(s))[1]; buf[index++] = BitConverter.GetBytes(SafeConverter.SafeToInt(s))[0]; } data = new byte[7 + buf.Length]; data[0] = (byte)station; data[1] = function; data[2] = BitConverter.GetBytes(modAddress)[1]; data[3] = BitConverter.GetBytes(modAddress)[0]; data[4] = BitConverter.GetBytes(buf.Length / 2)[1]; data[5] = BitConverter.GetBytes(buf.Length / 2)[0]; data[6] = (byte)(buf.Length); buf.CopyTo(data, 7); } } catch { data = null; } #endregion return(PackCommandToTcp(spkno, data)); }