From b571068f64825c2895d301f3421f8c4073349557 Mon Sep 17 00:00:00 2001 From: fyf Date: Thu, 22 Sep 2022 18:11:20 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BPASmartClient.Compiler.csproj | 32 - BPASmartClient.Compiler/CSharpConfig.cs | 181 ---- BPASmartClient.Compiler/Config.cs | 94 -- BPASmartClient.Compiler/FJson.cs | 68 -- BPASmartClient.Compiler/FRedisClient.cs | 178 ---- BPASmartClient.Compiler/HttpRequestHelper.cs | 328 ------ BPASmartClient.Compiler/IExecutable.cs | 30 - BPASmartClient.Compiler/MQTT.cs | 142 --- BPASmartClient.Compiler/RedisHelper.cs | 69 -- .../BPASmartClient.MinimalistUI.csproj | 7 +- .../FControl/RunCanvas.xaml.cs | 3 +- .../BPASmartClient.SCADAControl.csproj | 4 + .../DLL/Antlr3.Runtime.dll | Bin .../DLL/BPASmartClient.Compiler.dll | Bin 0 -> 53248 bytes .../DLL/Unvell.ReoScript.dll | Bin BeDesignerSCADA/Adorners/SelectionAdorner.cs | 228 ---- .../Adorners/SelectionAlignLine.cs | 32 - BeDesignerSCADA/BeDesignerSCADA.csproj | 34 +- BeDesignerSCADA/Controls/CanvasPanel.cs | 990 ------------------ BeDesignerSCADA/Controls/MainCanvasPanel.xaml | 21 +- BeDesignerSCADA/CustomerControls/ArcGauge.cs | 198 ---- .../CustomerControls/DigitalNumber.cs | 62 -- .../CustomerControls/GraphArrow.xaml | 14 - .../CustomerControls/GraphArrow.xaml.cs | 56 - .../CustomerControls/GraphStar.xaml | 14 - .../CustomerControls/GraphStar.xaml.cs | 56 - .../CustomerControls/KnobButton.cs | 240 ----- BeDesignerSCADA/CustomerControls/NumberBox.cs | 372 ------- .../CustomerControls/StatusLight.cs | 101 -- .../CustomerControls/SwitchButton.cs | 150 --- .../CustomerControls/TheButton.xaml | 9 - .../CustomerControls/TheButton.xaml.cs | 77 -- .../CustomerControls/TheCheckBox.xaml | 9 - .../CustomerControls/TheCheckBox.xaml.cs | 92 -- .../CustomerControls/TheComboBox.xaml | 9 - .../CustomerControls/TheComboBox.xaml.cs | 75 -- .../CustomerControls/TheGroupBox.xaml | 9 - .../CustomerControls/TheGroupBox.xaml.cs | 58 - .../CustomerControls/TheImage.xaml | 9 - .../CustomerControls/TheImage.xaml.cs | 57 - .../CustomerControls/TheRadioButton.cs | 59 -- BeDesignerSCADA/CustomerControls/TheSlider.cs | 69 -- .../CustomerControls/TheTextBlock.xaml | 9 - .../CustomerControls/TheTextBlock.xaml.cs | 55 - .../CustomerControls/TheTextBox.cs | 61 -- BeDesignerSCADA/CustomerControls/TheTimer.cs | 99 -- .../CustomerControls/TheToggleButton.xaml | 9 - .../CustomerControls/TheToggleButton.xaml.cs | 96 -- .../CustomerControls/WaveProgressBar.cs | 187 ---- BeDesignerSCADA/DLL/Antlr3.Runtime.dll | Bin 102912 -> 0 bytes BeDesignerSCADA/DLL/Unvell.ReoScript.dll | Bin 271800 -> 0 bytes BeDesignerSCADA/Themes/Styles.xaml | 298 +----- SCADA.Test/SCADA.Test.csproj | 7 +- SmartClient.sln | 51 +- 54 files changed, 55 insertions(+), 5053 deletions(-) delete mode 100644 BPASmartClient.Compiler/BPASmartClient.Compiler.csproj delete mode 100644 BPASmartClient.Compiler/CSharpConfig.cs delete mode 100644 BPASmartClient.Compiler/Config.cs delete mode 100644 BPASmartClient.Compiler/FJson.cs delete mode 100644 BPASmartClient.Compiler/FRedisClient.cs delete mode 100644 BPASmartClient.Compiler/HttpRequestHelper.cs delete mode 100644 BPASmartClient.Compiler/IExecutable.cs delete mode 100644 BPASmartClient.Compiler/MQTT.cs delete mode 100644 BPASmartClient.Compiler/RedisHelper.cs rename {BPASmartClient.Compiler => BPASmartClient.SCADAControl}/DLL/Antlr3.Runtime.dll (100%) create mode 100644 BPASmartClient.SCADAControl/DLL/BPASmartClient.Compiler.dll rename {BPASmartClient.Compiler => BPASmartClient.SCADAControl}/DLL/Unvell.ReoScript.dll (100%) delete mode 100644 BeDesignerSCADA/Adorners/SelectionAdorner.cs delete mode 100644 BeDesignerSCADA/Adorners/SelectionAlignLine.cs delete mode 100644 BeDesignerSCADA/Controls/CanvasPanel.cs delete mode 100644 BeDesignerSCADA/CustomerControls/ArcGauge.cs delete mode 100644 BeDesignerSCADA/CustomerControls/DigitalNumber.cs delete mode 100644 BeDesignerSCADA/CustomerControls/GraphArrow.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/GraphArrow.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/GraphStar.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/GraphStar.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/KnobButton.cs delete mode 100644 BeDesignerSCADA/CustomerControls/NumberBox.cs delete mode 100644 BeDesignerSCADA/CustomerControls/StatusLight.cs delete mode 100644 BeDesignerSCADA/CustomerControls/SwitchButton.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheButton.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheButton.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheCheckBox.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheCheckBox.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheComboBox.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheComboBox.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheGroupBox.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheGroupBox.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheImage.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheImage.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheRadioButton.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheSlider.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheTextBlock.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheTextBlock.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheTextBox.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheTimer.cs delete mode 100644 BeDesignerSCADA/CustomerControls/TheToggleButton.xaml delete mode 100644 BeDesignerSCADA/CustomerControls/TheToggleButton.xaml.cs delete mode 100644 BeDesignerSCADA/CustomerControls/WaveProgressBar.cs delete mode 100644 BeDesignerSCADA/DLL/Antlr3.Runtime.dll delete mode 100644 BeDesignerSCADA/DLL/Unvell.ReoScript.dll diff --git a/BPASmartClient.Compiler/BPASmartClient.Compiler.csproj b/BPASmartClient.Compiler/BPASmartClient.Compiler.csproj deleted file mode 100644 index efb7ba9f..00000000 --- a/BPASmartClient.Compiler/BPASmartClient.Compiler.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - net6.0-windows - enable - enable - - - - - - - - - - - - - - - - - - - DLL\Antlr3.Runtime.dll - - - DLL\Unvell.ReoScript.dll - - - - diff --git a/BPASmartClient.Compiler/CSharpConfig.cs b/BPASmartClient.Compiler/CSharpConfig.cs deleted file mode 100644 index faab7eee..00000000 --- a/BPASmartClient.Compiler/CSharpConfig.cs +++ /dev/null @@ -1,181 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Emit; -using Microsoft.CSharp; -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Runtime; -using System.Runtime.CompilerServices; - -namespace BPASmartClient.Compiler -{ - /// - /// C#编译器 - /// - public class CSharpConfig - { - #region 单例模式 - public static CSharpConfig Instance = null; - - public static CSharpConfig GetInstance() - { - if (Instance == null) - { - Instance = new CSharpConfig(); - } - return Instance; - } - #endregion - - public CSharpConfig() - { - - - } - - - - public object RunCSharp(string code,object[] objValue,string error = "") - { - object strretu = string.Empty; - try - { - string funName = "main"; - StringBuilder builder = new StringBuilder(); - //builder.Append("using System;\n"); - //builder.Append("using System.Linq;\n"); - builder.Append("using Newtonsoft.Json;\n"); - builder.Append("using Newtonsoft.Json.Linq;\n"); - //builder.Append("using System.IO;\n"); - //builder.Append("using System.Runtime;\n"); - //builder.Append("using System.Text;\n"); - builder.Append("using System.Collections.Generic;\n"); - builder.Append("namespace YF \n{\n class CSharpConfigRun\n"); - builder.Append(" {\n"); - builder.Append(code); - builder.Append(" }\n}\n"); - //1.添加要引用的程序集 - string output = Path.GetTempFileName(); - string assemblyName = Path.GetFileName(output); - var refPaths = new[] { - Assembly.GetExecutingAssembly().Location, - typeof(object).GetTypeInfo().Assembly.Location, - Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.dll"), - Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Collections.dll"), - Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Threading.dll"), - Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll"), - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Newtonsoft.Json.dll"), - typeof(DynamicAttribute).GetTypeInfo().Assembly.Location, - }; - MetadataReference[] references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray(); - - List refs = new List() { - MetadataReference.CreateFromFile (typeof (object).Assembly.Location), - MetadataReference.CreateFromFile (typeof (List).Assembly.Location), - MetadataReference.CreateFromFile (typeof (ASCIIEncoding).Assembly.Location), - MetadataReference.CreateFromFile (typeof (JsonConvert).Assembly.Location), - MetadataReference.CreateFromFile (typeof (JObject).Assembly.Location), - MetadataReference.CreateFromFile (typeof (Object).Assembly.Location), - MetadataReference.CreateFromFile (typeof (JContainer).Assembly.Location), - MetadataReference.CreateFromFile (typeof (JToken).Assembly.Location), - MetadataReference.CreateFromFile (typeof (Enumerable).Assembly.Location), - }; - //2.需要编辑的C#代码 - SyntaxTree tree = CSharpSyntaxTree.ParseText(builder.ToString()); - //3.生成C#编译 - var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll") - .WithOptions(new CSharpCompilationOptions( - Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary - , - usings: null, - optimizationLevel: OptimizationLevel.Debug, // TODO - checkOverflow: false, // TODO - allowUnsafe: true, // TODO - platform: Platform.AnyCpu, - warningLevel: 4, - xmlReferenceResolver: null - )) - .AddReferences(references) - .AddSyntaxTrees(tree); - - //var emitResult = compilation.Emit(output); - EmitResult emitResult; - byte[] dllBytes; - using (var stream = new MemoryStream()) - { - emitResult = compilation.Emit(stream); - dllBytes = stream.ToArray(); - } - - if (emitResult.Success) - { - Assembly assembly = Assembly.Load(dllBytes); - var obj = assembly.CreateInstance("YF.CSharpConfigRun"); - var method = obj.GetType().GetMethod("main",new Type[] { typeof(string) }); - strretu = method.Invoke(obj,objValue); - } - - - //var providerOptions = new Dictionary(); - //providerOptions.Add("CompilerVersion","v4.0"); - //CSharpCodeProvider compiler = new CSharpCodeProvider(providerOptions); - //string output = Path.GetTempFileName(); - //var cp = new CompilerParameters() { GenerateInMemory = true,OutputAssembly = output }; - //cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); - //cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); - //cp.ReferencedAssemblies.Add("System.Core.dll"); - //cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll"); //添加引用 - //cp.ReferencedAssemblies.Add("System.dll"); - //cp.GenerateExecutable = false; - //cp.EmbeddedResources.Clear(); - //cp.LinkedResources.Clear(); - //cp.Win32Resource = null; - //cp.TreatWarningsAsErrors = false; - //cp.WarningLevel = 4; - //cp.TempFiles.KeepFiles = false; - //CompilerResults cr = compiler.CompileAssemblyFromSource(cp,builder.ToString()); - - - - - // 1.ICodeComplier - // CSharpCodeProvider complier = new CSharpCodeProvider(); - // // 2.CompilerParameters - // CompilerParameters cp = new CompilerParameters(); - // cp.ReferencedAssemblies.Add("System.dll"); //添加引用 - //// cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll"); //添加引用 - // cp.GenerateExecutable = false; - // cp.GenerateInMemory = true; - // // 3.CompilerResults - // CompilerResults cr = complier.CompileAssemblyFromSource(cp,builder.ToString()); - //if (cr.Errors.HasErrors) - //{ - // foreach (CompilerError err in cr.Errors) - // { - // error += err.ErrorText + "\r\n"; - // } - //} - //else - //{ - // // 通过反射,调用HelloWorld的实例 - // Assembly objAssembly = cr.CompiledAssembly; - // object objClass = objAssembly.CreateInstance("CSharpConfigRun"); - // MethodInfo objFun = objClass.GetType().GetMethod(funName); - // strretu = objFun.Invoke(objClass,objValue); - //} - } - catch (Exception ex) - { - error += ex.Message; - } - return strretu; - } - } -} diff --git a/BPASmartClient.Compiler/Config.cs b/BPASmartClient.Compiler/Config.cs deleted file mode 100644 index 1b6cbea0..00000000 --- a/BPASmartClient.Compiler/Config.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using Unvell.ReoScript; - -namespace BPASmartClient.Compiler -{ - /// - /// 编译器 - /// 创建人:奉友福 - /// 创建时间:20220824 - /// - public class Config - { - #region 单例模式 - public static Config Instance = null; - - public static Config GetInstance() - { - if (Instance == null) - { - Instance = new Config(); - } - return Instance; - } - #endregion - - public static ScriptRunningMachine srm { get; } = new ScriptRunningMachine(); - - public Config() - { - srm.WorkMode |= - // Enable DirectAccess - MachineWorkMode.AllowDirectAccess - // Ignore exceptions in CLR calling (by default) - | MachineWorkMode.IgnoreCLRExceptions - // Enable CLR Event Binding - | MachineWorkMode.AllowCLREventBind; - - RegisterFunction(); - } - - /// - /// 运行脚本 - /// - /// - public void RunJsScipt(string script) - { - try - { - srm.Run(script); - } - catch (Exception e) - { - //MessageBox.Show(e.Message, "脚本错误"); - } - } - - /// - /// 注册对象到js - /// - public void SetVariable(string name, object obj) - { - srm.SetGlobalVariable(name, obj); - } - - /// - /// 注册方法到Js - /// - private static void RegisterFunction() - { - srm["ShowMessage"] = new NativeFunctionObject("ShowMessage", (ctx, owner, args) => - { - StringBuilder sb = new StringBuilder(); - foreach (var item in args) - { - sb.Append(item.ToString()); - } - - //MessageBox.Show($"{sb}", "提示"); - return null; - }); - - srm["SetICDValue"] = new NativeFunctionObject("SetICDValue", (ctx, owner, args) => - { - //MessageBox.Show($"发送ICD数据", "提示"); - return null; - }); - } - } -} \ No newline at end of file diff --git a/BPASmartClient.Compiler/FJson.cs b/BPASmartClient.Compiler/FJson.cs deleted file mode 100644 index a5dc848f..00000000 --- a/BPASmartClient.Compiler/FJson.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BPASmartClient.Compiler -{ - public class FJson where T : class, new() - { - private static string path - { - get - { - Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"AccessFile\\JSON")); - return AppDomain.CurrentDomain.BaseDirectory + "AccessFile\\JSON\\" + typeof(T).Name + ".json"; - } - } - - public static T Data - { - get; - set; - } = new T(); - - - public static void Save() - { - string contents = JsonConvert.SerializeObject(Data); - File.WriteAllText(path,contents); - } - - public static void Read() - { - if (File.Exists(path)) - { - T val = JsonConvert.DeserializeObject(File.ReadAllText(path)); - if (val != null) - { - Data = val; - } - } - } - - public static void SaveInterface() - { - JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings(); - jsonSerializerSettings.TypeNameHandling = TypeNameHandling.Objects; - string contents = JsonConvert.SerializeObject(Data,Formatting.Indented,jsonSerializerSettings); - File.WriteAllText(path,contents); - } - - public static void ReadInterface() - { - if (File.Exists(path)) - { - JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings(); - jsonSerializerSettings.TypeNameHandling = TypeNameHandling.Objects; - T val = JsonConvert.DeserializeObject(File.ReadAllText(path),jsonSerializerSettings); - if (val != null) - { - Data = val; - } - } - } - } -} diff --git a/BPASmartClient.Compiler/FRedisClient.cs b/BPASmartClient.Compiler/FRedisClient.cs deleted file mode 100644 index 63d28bb4..00000000 --- a/BPASmartClient.Compiler/FRedisClient.cs +++ /dev/null @@ -1,178 +0,0 @@ -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - - -namespace BPASmartClient.Compiler -{ - public class FRedisClient - { - #region 单例模式 - //private static FRedisClient instance = null; - //public static FRedisClient Instance() - //{ - // if (instance == null) instance = new FRedisClient(); - // return instance; - //} - #endregion - - #region 变量 - /// - /// IP地址 - /// - public string redisconnection = "124.222.238.75:16000,password=123456"; - /// - /// redis 连接状态 - /// - public ConnectionMultiplexer _connection = null; - /// - /// 数据存储位置 - /// - public IDatabase _database = null; - /// - /// 通道建立连接 - /// - public ISubscriber subscibe = null; - #endregion - - #region 外部访问 - /// - /// 委托出去 - /// - public Action LogMeaage = null; - #endregion - - public void Connect() - { - _connection = ConnectionMultiplexer.Connect(ConfigurationOptions.Parse(redisconnection)); - _database = _connection.GetDatabase(0);//默认使用db0 - subscibe = _connection.GetSubscriber(); - } - int dbi = 0; - public void Connect(string connection) - { - _connection = ConnectionMultiplexer.Connect(ConfigurationOptions.Parse(connection)); - if (connection.Contains("defaultDatabase=")) - { - string[] str=connection.Split(','); - string stro = str.ToList().Find(s => s.Contains("defaultDatabase=")); - - try - { - dbi=int.Parse(stro.Replace("defaultDatabase=","")); - } - catch (Exception ex) - { - - throw; - } - _database = _connection.GetDatabase(dbi);//默认使用db0 - } - else - { - _database = _connection.GetDatabase(dbi);//默认使用db0 - } - subscibe = _connection.GetSubscriber(); - } - - /// - /// 获取设备列表 - /// - /// - public Dictionary GetKeys() - { - Dictionary keys = new Dictionary(); - foreach (var endPoint in _connection.GetEndPoints()) - { - //获取指定服务器 - var server = _connection.GetServer(endPoint); - //在指定服务器上使用 keys 或者 scan 命令来遍历key - //foreach (var key in server.Keys(0,"设备列表:*")) - //{ - // //获取key对于的值 - // var val = _database.StringGet(key); - // Console.WriteLine($"key: {key}, value: {val}"); - // keys[key] = val; - //} - foreach (var key in server.Keys(dbi,"*")) - { - //获取key对于的值 - var val = _database.StringGet(key); - Console.WriteLine($"key: {key}, value: {val}"); - keys[key] = val; - } - } - return keys; - } - - /// - /// 订阅通道消息 - /// - public void SubscribeChanne(string channelname) - { - if (subscibe == null) return; - subscibe.Subscribe(channelname,(channel,message) => - { - MessageLog(channel,message); - }); - } - - /// - /// 发布通道消息 - /// - public void PublishChanne(string channelname,string value) - { - if (subscibe == null) return; - subscibe.Publish(channelname,value); - } - - /// - /// 获取 key 值 - /// - public RedisValue RedisGet(string key,string hashField = "") - { - if (_database == null) return new RedisValue(); - RedisValue result; - if (string.IsNullOrEmpty(hashField)) - { - result = _database.StringGet(key); - } - else - { - result = _database.HashGet(key,hashField); - } - return result; - //MessageLog(key,result); - } - /// - /// 设置 redis 的值 - /// - public bool RedisSet(string key,string hashField,string value) - { - bool result; - if (string.IsNullOrEmpty(hashField)) - { - result = _database.StringSet(key,value); - } - else - { - result = _database.HashSet(key,hashField,value); - } - return result; - } - - /// - /// 消息打印 - /// - private void MessageLog(string key,string msg) - { - if (LogMeaage != null) - { - LogMeaage.Invoke(key,msg); - } - } - } -} diff --git a/BPASmartClient.Compiler/HttpRequestHelper.cs b/BPASmartClient.Compiler/HttpRequestHelper.cs deleted file mode 100644 index a969c9e5..00000000 --- a/BPASmartClient.Compiler/HttpRequestHelper.cs +++ /dev/null @@ -1,328 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace BPASmartClient.Compiler -{ - /// - /// 该类实现客户端http 同步请求 - /// 支持环境 -.net4.0/-.net4.5 - /// 创建人:奉友福 - /// - public class HttpRequestHelper - { - #region 私有变量 - #endregion - - #region 公用函数 - /// - /// GET 同步请求 - /// 创建人:奉友福 - /// 创建时间:2020-11-19 - /// - /// 请求地址 - /// 超时时间设置,默认5秒 - public static string HttpGetRequest(string url,int _timeout = 2000) - { - string resultData = string.Empty; - - try - { - WebClient wc = new WebClient(); - byte[] bytes = wc.DownloadData(url); - string s = Encoding.UTF8.GetString(bytes); - return s; - } - catch (Exception e) - { - throw e; - } - return ""; - - try - { - var getrequest = HttpRequest.GetInstance().CreateHttpRequest(url,"GET",_timeout); - var getreponse = getrequest.GetResponse() as HttpWebResponse; - resultData = HttpRequest.GetInstance().GetHttpResponse(getreponse,"GET"); - } - catch (Exception) - { - throw; - } - return resultData; - } - /// - /// POST 同步请求 - /// 创建人:奉友福 - /// 创建时间:2020-11-19 - /// - /// 请求地址 - /// 请求数据 - /// - public static string HttpPostRequest(string url,string PostJsonData,int _timeout = 2000) - { - string resultData = string.Empty; - try - { - var postrequest = HttpRequest.GetInstance().CreateHttpRequest(url,"POST",_timeout,PostJsonData); - var postreponse = postrequest.GetResponse() as HttpWebResponse; - resultData = HttpRequest.GetInstance().GetHttpResponse(postreponse,"POST"); - } - catch (Exception ex) - { - return ex.Message; - } - return resultData; - } - - public static string HttpDeleteRequest(string url,string PostJsonData,int _timeout = 10000) - { - string resultData = string.Empty; - try - { - var deleteRequest = HttpRequest.CreateDeleteHttpRequest(url,PostJsonData,_timeout); - var deleteReponse = deleteRequest.GetResponse() as HttpWebResponse; - using (StreamReader reader = new StreamReader(deleteReponse.GetResponseStream(),Encoding.GetEncoding("UTF-8"))) - { - resultData = reader.ReadToEnd(); - } - } - catch (Exception ex) - { - } - return resultData; - } - - /// - /// GET 同步请求 - /// - /// 地址 - /// 头 - /// 内容 - /// - public static string GetHttpGetResponseWithHead(string url,HttpRequestHeader head,string headInfo) - { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - request.Method = "GET"; - request.ContentType = "application/json;charset=UTF-8"; - request.Timeout = 6000; - request.Headers.Set(head,headInfo); - StreamReader sr = null; - HttpWebResponse response = null; - Stream stream = null; - try - { - response = (HttpWebResponse)request.GetResponse(); - stream = response.GetResponseStream(); - sr = new StreamReader(stream,Encoding.GetEncoding("utf-8")); - var resultData = sr.ReadToEnd(); - return resultData; - } - catch (Exception ex) - { - Console.WriteLine(url + " 访问失败:" + ex.Message); - //return ex.Message; - } - finally - { - if (response != null) - { - response.Dispose(); - } - if (stream != null) - { - stream.Dispose(); - } - if (sr != null) - { - sr.Dispose(); - } - } - return null; - } - - - - /// - /// Post请求带Token - /// 2021-2-2 by dulf - /// - /// - /// - /// - /// - /// - public static string HttpPostResponseWithHead(string url,HttpRequestHeader head,string headInfo,string postParam,int Timeout = 6000) - { - string resultData = string.Empty; - try - { - var postrequest = WebRequest.Create(url) as HttpWebRequest; - postrequest.Timeout = Timeout; - postrequest.Method = "POST"; - postrequest.ContentType = "application/json;charset=UTF-8"; - postrequest.Headers.Set(head,headInfo); - byte[] data = Encoding.UTF8.GetBytes(postParam); - using (Stream reqStream = postrequest.GetRequestStream()) - { - reqStream.Write(data,0,data.Length); - var postreponse = postrequest.GetResponse() as HttpWebResponse; - resultData = HttpRequest.GetInstance().GetHttpResponse(postreponse,"POST"); - reqStream.Close(); - } - return resultData; - } - catch (Exception ex) - { - Console.Write("请求异常:" + ex.Message); - } - return ""; - } - #endregion - - } - /// - /// HTTP请求类 - /// - public class HttpRequest - { - #region 私有变量 - /// - /// http请求超时时间设置 - /// 默认值:5秒 - /// - private static int Timeout = 5000; - #endregion - - #region 单例模式 - private static HttpRequest _HttpRequest = null; - public static HttpRequest GetInstance() - { - if (_HttpRequest == null) - { - _HttpRequest = new HttpRequest(); - } - return _HttpRequest; - } - private HttpRequest() - { - - } - #endregion - - #region 公用函数 - /// - /// 函数名称:创建http请求 - /// 创建人:奉友福 - /// 创建时间:2020-11-19 - /// 例如GET 请求: 地址 + "GET" - /// 例如POST请求: 地址 + "POST" + JSON - /// - /// http请求地址 - /// http请求方式:GET/POST - /// http请求附带数据 - /// - public HttpWebRequest CreateHttpRequest(string url,string requestType,int _timeout = 5000,params object[] strjson) - { - HttpWebRequest request = null; - const string get = "GET"; - const string post = "POST"; - Timeout = _timeout; - if (string.Equals(requestType,get,StringComparison.OrdinalIgnoreCase)) - { - request = CreateGetHttpRequest(url); - } - if (string.Equals(requestType,post,StringComparison.OrdinalIgnoreCase)) - { - request = CreatePostHttpRequest(url,strjson[0].ToString()); - } - return request; - } - /// - /// http获取数据 - /// - /// - /// - /// - public string GetHttpResponse(HttpWebResponse response,string requestType) - { - var resultData = string.Empty; - const string post = "POST"; - string encoding = "UTF-8"; - if (string.Equals(requestType,post,StringComparison.OrdinalIgnoreCase)) - { - encoding = response.ContentEncoding; - if (encoding == null || encoding.Length < 1) - encoding = "UTF-8"; - } - using (StreamReader reader = new StreamReader(response.GetResponseStream(),Encoding.GetEncoding(encoding))) - { - resultData = reader.ReadToEnd(); - } - return resultData; - } - #endregion - - #region 私有函数 - /// - /// http+GET请求 - /// - /// 请求地址 - /// 请求结果 - private static HttpWebRequest CreateGetHttpRequest(string url) - { - var getrequest = WebRequest.Create(url) as HttpWebRequest; - getrequest.Method = "GET"; - getrequest.Timeout = Timeout; - getrequest.ContentType = "application/json;charset=UTF-8"; - getrequest.Proxy = null; - getrequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; - return getrequest; - } - /// - /// http+POST请求 - /// - /// 请求地址 - /// - /// 请求结果 - private static HttpWebRequest CreatePostHttpRequest(string url,string postData) - { - var postrequest = WebRequest.Create(url) as HttpWebRequest; - //postrequest.KeepAlive = false; - postrequest.Timeout = Timeout; - postrequest.Method = "POST"; - postrequest.ContentType = "application/json;charset=UTF-8"; - //postrequest.ContentLength = postData.Length; - //postrequest.AllowWriteStreamBuffering = false; - //StreamWriter writer = new StreamWriter(postrequest.GetRequestStream(), Encoding.UTF8); - //writer.Write(postData); - //writer.Flush(); - byte[] data = Encoding.UTF8.GetBytes(postData); - using (Stream reqStream = postrequest.GetRequestStream()) - { - reqStream.Write(data,0,data.Length); - reqStream.Close(); - } - return postrequest; - } - - public static HttpWebRequest CreateDeleteHttpRequest(string url,string postJson,int _timeout = 5000) - { - var deleteRequest = WebRequest.Create(url) as HttpWebRequest; - deleteRequest.Timeout = _timeout; - deleteRequest.Method = "DELETE"; - deleteRequest.ContentType = "application/json;charset=UTF-8"; - byte[] data = Encoding.UTF8.GetBytes(postJson); - using (Stream reqStream = deleteRequest.GetRequestStream()) - { - reqStream.Write(data,0,data.Length); - reqStream.Close(); - } - return deleteRequest; - } - #endregion - } -} diff --git a/BPASmartClient.Compiler/IExecutable.cs b/BPASmartClient.Compiler/IExecutable.cs deleted file mode 100644 index bc656d23..00000000 --- a/BPASmartClient.Compiler/IExecutable.cs +++ /dev/null @@ -1,30 +0,0 @@ -using BPASmartClient.MessageName.接收消息Model; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BPASmartClient.Compiler -{ - public interface IExecutable - { - /// - /// 是否执行 - /// - bool IsExecuteState { get; set; } - /// - /// 运行程序 注册事件 - /// - void Register(); - /// - /// 控件类型 - /// - string ControlType { get; } - /// - /// 属性改变 - /// - event EventHandler PropertyChange; //声明一个事件 - } -} diff --git a/BPASmartClient.Compiler/MQTT.cs b/BPASmartClient.Compiler/MQTT.cs deleted file mode 100644 index c532ddd4..00000000 --- a/BPASmartClient.Compiler/MQTT.cs +++ /dev/null @@ -1,142 +0,0 @@ -using MQTTnet; -using MQTTnet.Client; -using MQTTnet.Client.Options; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BPASmartClient.Compiler -{ - public class MQTT - { - - //private volatile static MQTT _Instance; - //public static MQTT GetInstance => _Instance ?? (_Instance = new MQTT()); - //private MQTT() { } - - - public IMqttClient client; - IMqttClientOptions options; - - /// - /// MQTT 接收消息 - /// - public Action MqttReceive { get; set; } - - /// - /// MQTT 连接成功 - /// - public Action ConnectOk { get; set; } - - /// - /// 重连成功 - /// - public Action Reconnection { get; set; } - - - public async void MqttInitAsync(string UserName,string pass,string IP,int port,string clientID) - { - p1: - options = new MqttClientOptionsBuilder().WithTcpServer(IP,port).WithClientId(clientID).WithCredentials(UserName,pass).Build(); - client = new MqttFactory().CreateMqttClient(); - client.UseDisconnectedHandler(async c => - { - Thread.Sleep(2000); - //while (!Device.DataBus.内存数据缓存.DataBus.GetInstance().NetworkConnectState) - //{ - // Thread.Sleep(2000); - //} - //Device.DataBus.内存数据缓存.DataBus.GetInstance().MQTTConnectState = false; - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO,$"断开连接"); - - try - { - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO,$"重连中"); - await client.ConnectAsync(options); - } - catch (Exception ex) - { - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.ERROR,ex.Message); - } - if (client.IsConnected) - { - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO,$"MQTT重连成功"); - if (Reconnection != null) Reconnection(); - } - - }).UseApplicationMessageReceivedHandler(c => - { - MqttReceive(c); - }).UseConnectedHandler((e) => - { - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO,$"连接成功"); - }); - - - try - { - await client.ConnectAsync(options); - } - catch (Exception ex) - { - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.ERROR,ex.Message); - } - if (!client.IsConnected) - { - Thread.Sleep(2000); - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO,$"mqtt连接失败!重连执行中"); - goto p1; - } - Thread.Sleep(2000); - //logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO,$"MQTT连接成功!"); - if (ConnectOk != null) ConnectOk(); - } - - /// - /// Mqtt 订阅 - /// - /// 需要订阅的主题 - public async void MqttSubscriptionAsync(string topic) - { - if (client != null) - { - if (client.IsConnected) - { - try - { - var result = await client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).WithExactlyOnceQoS().Build()); - } - catch { } - } - } - } - - /// - /// Mqtt 发布 - /// - /// 需要发布的主题 - /// 需要发布的内容 - public async void MqttPublishAsync(string topic,string content) - { - if (client != null) - { - if (client.IsConnected) - { - - var msg = new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(content).WithExactlyOnceQoS().Build(); - try - { - var result = await client.PublishAsync(msg); - } - catch { } - } - } - } - - private static readonly object sendMessageLock = new object(); - - - } -} diff --git a/BPASmartClient.Compiler/RedisHelper.cs b/BPASmartClient.Compiler/RedisHelper.cs deleted file mode 100644 index b3f8e21b..00000000 --- a/BPASmartClient.Compiler/RedisHelper.cs +++ /dev/null @@ -1,69 +0,0 @@ -using ServiceStack.Redis; -using System.Diagnostics; - -namespace BPASmartClient.Compiler -{ - public class RedisHelper - { - - private volatile static RedisHelper _Instance; - public static RedisHelper GetInstance => _Instance ?? (_Instance = new RedisHelper()); - private RedisHelper() { } - RedisClient client; - - public async Task ConnectAsync(string redisconnection) - { - return await Task.Factory.StartNew(new Func(() => - { - if (client == null) - { - //"124.222.238.75:16000,password=123456"; - client = new RedisClient("124.222.238.75",16000,"123456",1); - client.ConnectTimeout = 5000; - Stopwatch sw = new Stopwatch(); - sw.Start(); - while (!client.IsSocketConnected()) - { - if (sw.ElapsedMilliseconds >= client.ConnectTimeout) break; - Thread.Sleep(1000); - } - string status = client.IsSocketConnected() ? "成功" : "失败"; - } - return client.IsSocketConnected(); - })); - - } - - /// - /// 清除所有redis 数据 - /// - public void FlushDb() - { - client?.FlushDb(); - } - - /// - /// 设置值 - /// - /// - /// - /// - public void SetValue(string key,TValue value) - { - var res = client?.Set(key,value); - } - - /// - /// 获取值 - /// - /// - /// - /// - public TResult GetValue(string key) - { - if (client == null) return default(TResult); - return client.Get(key); - } - - } -} diff --git a/BPASmartClient.MinimalistUI/BPASmartClient.MinimalistUI.csproj b/BPASmartClient.MinimalistUI/BPASmartClient.MinimalistUI.csproj index 0cd74038..449b3683 100644 --- a/BPASmartClient.MinimalistUI/BPASmartClient.MinimalistUI.csproj +++ b/BPASmartClient.MinimalistUI/BPASmartClient.MinimalistUI.csproj @@ -27,12 +27,17 @@ - + + + ..\BPASmartClient.SCADAControl\DLL\BPASmartClient.Compiler.dll + + + diff --git a/BPASmartClient.MinimalistUI/FControl/RunCanvas.xaml.cs b/BPASmartClient.MinimalistUI/FControl/RunCanvas.xaml.cs index 7b7c212e..6049c3ab 100644 --- a/BPASmartClient.MinimalistUI/FControl/RunCanvas.xaml.cs +++ b/BPASmartClient.MinimalistUI/FControl/RunCanvas.xaml.cs @@ -1,4 +1,5 @@ -using BPASmartClient.Compiler; + +using BPASmartClient.Compiler; using BPASmartClient.MessageName.接收消息Model; using System; using System.Collections.Generic; diff --git a/BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj b/BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj index 552fa8f3..3854ac4a 100644 --- a/BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj +++ b/BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj @@ -56,6 +56,10 @@ ..\BPASmartClient.Compiler\DLL\Antlr3.Runtime.dll + + DLL\BPASmartClient.Compiler.dll + True + ..\BPASmartClient.Compiler\DLL\Unvell.ReoScript.dll diff --git a/BPASmartClient.Compiler/DLL/Antlr3.Runtime.dll b/BPASmartClient.SCADAControl/DLL/Antlr3.Runtime.dll similarity index 100% rename from BPASmartClient.Compiler/DLL/Antlr3.Runtime.dll rename to BPASmartClient.SCADAControl/DLL/Antlr3.Runtime.dll diff --git a/BPASmartClient.SCADAControl/DLL/BPASmartClient.Compiler.dll b/BPASmartClient.SCADAControl/DLL/BPASmartClient.Compiler.dll new file mode 100644 index 0000000000000000000000000000000000000000..bf41ab07b7cb68b6e104c278e3053df963406f30 GIT binary patch literal 53248 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 { 6, 4 }, 4); - - //1.绘制边框 - drawingContext.DrawRectangle(renderBrush, renderPen1, new Rect(adornerRect.TopLeft.X, adornerRect.TopLeft.Y, adornerRect.Width, adornerRect.Height)); - //2.绘制拖动正方形 - // Draw a circle at each corner. - drawingContext.DrawRectangle(renderBrush, renderPen, new Rect(adornerRect.TopLeft.X - 2.5, adornerRect.TopLeft.Y - 2.5, 5, 5)); - drawingContext.DrawRectangle(renderBrush, renderPen, new Rect(adornerRect.TopRight.X - 2.5, adornerRect.TopRight.Y - 2.5, 5, 5)); - drawingContext.DrawRectangle(renderBrush, renderPen, new Rect(adornerRect.BottomLeft.X - 2.5, adornerRect.BottomLeft.Y - 2.5, 5, 5)); - drawingContext.DrawRectangle(renderBrush, renderPen, new Rect(adornerRect.BottomRight.X - 2.5, adornerRect.BottomRight.Y - 2.5, 5, 5)); - //3.绘制4个中心正方形 - drawingContext.DrawRectangle(renderBrush, renderPen, - new Rect(adornerRect.TopLeft.X + adornerRect.Width / (double)2 - 2.5, adornerRect.TopLeft.Y - 2.5, 5, 5)); - drawingContext.DrawRectangle(renderBrush, renderPen, - new Rect(adornerRect.TopRight.X - 2.5, adornerRect.TopRight.Y + adornerRect.Height / (double)2 - 2.5, 5, 5)); - drawingContext.DrawRectangle(renderBrush, renderPen, - new Rect(adornerRect.BottomLeft.X - 2.5, adornerRect.BottomLeft.Y - adornerRect.Height / (double)2 - 2.5, 5, 5)); - drawingContext.DrawRectangle(renderBrush, renderPen, - new Rect(adornerRect.BottomRight.X - adornerRect.Width / (double)2 - 2.5, adornerRect.BottomRight.Y - 2.5, 5, 5)); - - MouseDown += SelectionAdorner_MouseDown; - MouseMove += SelectionAdorner_MouseMove; - MouseUp += SelectionAdorner_MouseUp; - ResourceDictionary languageResDic = new ResourceDictionary(); - languageResDic.Source = new Uri(@"/BeDesignerSCADA;component/Themes/Styles.xaml", UriKind.RelativeOrAbsolute); - this.Resources.MergedDictionaries.Add(languageResDic); - ContextMenu = FindResource("AdornerRightMenu") as ContextMenu; - Tag = CanvasPanel.GetParentObject(AdornedElement); - - this.Focus(); - this.SelectionAdorner_MouseDown(this, null); - this.SelectionAdorner_MouseMove(this, null); - } - - private void SelectionAdorner_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) - { - ReleaseMouseCapture(); - CanvasPanel.GetParentObject(AdornedElement).ClearAlignLine(); - } - - /// - /// 鼠标最后一次按下位置 - /// - Point lastPoint = new Point(); - /// - /// 鼠标在控件中的位置 - /// - public MousePos mousePos; - double tempX = 0d; - double tempY = 0d; - double movePx = 0d; - /// - /// 改变鼠标状态,鼠标在控件上,下,左,右,左上,右上,左下,右下,向上不同的光标 - /// - private void SetCursor() - { - Rect adornerRect = new Rect(AdornedElement.DesiredSize); - double _left = CanvasPanel.GetLeft(AdornedElement); - double _top = CanvasPanel.GetTop(AdornedElement); - var DQPoint = Mouse.GetPosition(CanvasPanel.GetParentObject(AdornedElement)); - if (DQPoint.X >= (adornerRect.TopLeft.X - 2.5 + _left) && DQPoint.X <= (adornerRect.TopLeft.X + 2.5 + _left) && DQPoint.Y >= (adornerRect.TopLeft.Y - 2.5 + _top) && DQPoint.Y <= (adornerRect.TopLeft.Y + 2.5 + _top)) - { - //左上 - this.Cursor = Cursors.SizeNWSE; mousePos = MousePos.LeftTop; - } - else if (DQPoint.X >= (adornerRect.TopRight.X - 2.5 + _left) && DQPoint.X <= (adornerRect.TopRight.X + 2.5 + _left) && DQPoint.Y >= (adornerRect.TopRight.Y - 2.5 + _top) && DQPoint.Y <= (adornerRect.TopRight.Y + 2.5 + _top)) - { - //右上 - this.Cursor = Cursors.SizeNESW; mousePos = MousePos.RightTop; - } - else if (DQPoint.X >= (adornerRect.BottomLeft.X - 2.5 + _left) && DQPoint.X <= (adornerRect.BottomLeft.X + 2.5 + _left) && DQPoint.Y >= (adornerRect.BottomLeft.Y - 2.5 + _top) && DQPoint.Y <= (adornerRect.BottomLeft.Y + 2.5 + _top)) - { - //左下 - this.Cursor = Cursors.SizeNESW; mousePos = MousePos.LeftBottom ; - } - else if (DQPoint.X >= (adornerRect.BottomRight.X - 2.5 + _left) && DQPoint.X <= (adornerRect.BottomRight.X + 2.5 + _left) && DQPoint.Y >= (adornerRect.BottomRight.Y - 2.5 + _top) && DQPoint.Y <= (adornerRect.BottomRight.Y + 2.5 + _top)) - { - //右下 - this.Cursor = Cursors.SizeNWSE; mousePos = MousePos.RightBottom; - } - else if (DQPoint.X >= (adornerRect.TopLeft.X + adornerRect.Width / (double)2 - 2.5 + _left) && DQPoint.X <= (adornerRect.TopLeft.X + adornerRect.Width / (double)2 + 2.5 + _left) && DQPoint.Y >= (adornerRect.TopLeft.Y - 2.5 + _top) && DQPoint.Y <= (adornerRect.TopLeft.Y + 2.5 + _top)) - { - //上中 - this.Cursor = Cursors.SizeNS; mousePos = MousePos.Top; - } - else if (DQPoint.X >= (adornerRect.BottomRight.X - adornerRect.Width / (double)2 - 2.5 + _left) && DQPoint.X <= (adornerRect.BottomRight.X - adornerRect.Width / (double)2 + 2.5 + _left) && DQPoint.Y >= (adornerRect.BottomRight.Y - 2.5 + _top) && DQPoint.Y <= (adornerRect.BottomRight.Y + 2.5 + _top)) - { - //下中 - this.Cursor = Cursors.SizeNS; mousePos = MousePos.Bottom; - } - else if (DQPoint.X >= (adornerRect.TopRight.X - 2.5 + _left) && DQPoint.X <= (adornerRect.TopRight.X + 2.5 + _left) && DQPoint.Y >= (adornerRect.TopRight.Y + adornerRect.Height / (double)2 - 2.5 + _top) && DQPoint.Y <= (adornerRect.TopRight.Y + adornerRect.Height / (double)2 + 2.5 + _top)) - { - //右中 - this.Cursor = Cursors.SizeWE; mousePos = MousePos.Right; - } - else if (DQPoint.X >= (adornerRect.BottomLeft.X - 2.5 + _left) && DQPoint.X <= (adornerRect.BottomLeft.X + 2.5 + _left) && DQPoint.Y >= (adornerRect.BottomLeft.Y - adornerRect.Height / (double)2 - 2.5 + _top) && DQPoint.Y <= (adornerRect.BottomLeft.Y - adornerRect.Height / (double)2 + 2.5 + _top)) - { - //左中 - this.Cursor = Cursors.SizeWE; mousePos = MousePos.Left; - } - else - { - this.Cursor = Cursors.Arrow; mousePos = MousePos.None; - } - } - - - private void SelectionAdorner_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) - { - if (Mouse.LeftButton != MouseButtonState.Pressed - && Mouse.MiddleButton != MouseButtonState.Pressed - && Mouse.RightButton != MouseButtonState.Pressed)//鼠标没有按下,改变鼠标状态 - { - SetCursor(); - } - - if (this.Cursor == Cursors.Arrow && Mouse.LeftButton == MouseButtonState.Pressed)//移动控件 - { - if (lastPoint.X == 0 && lastPoint.Y == 0) - { - return; - } - - CaptureMouse(); - var nowPoint = Mouse.GetPosition(CanvasPanel.GetParentObject(AdornedElement)); - double offsetX = nowPoint.X - lastPoint.X; - double offsetY = nowPoint.Y - lastPoint.Y; - lastPoint = nowPoint; - - tempX += offsetX; - tempY += offsetY; - - var canvas = CanvasPanel.GetParentObject(AdornedElement); - movePx = canvas.GridPxiel; - - if (Math.Abs(tempX) >= movePx) - { - offsetX = Math.Round(tempX / movePx) * movePx; - tempX -= offsetX; - canvas.MoveControls(offsetX, 0); - } - - if (Math.Abs(tempY) >= movePx) - { - offsetY = Math.Round(tempY / movePx) * movePx; - tempY -= offsetY; - canvas.MoveControls(0, offsetY); - } - } - else if (this.Cursor != Cursors.Arrow && Mouse.LeftButton == MouseButtonState.Pressed) - { - CaptureMouse(); - //lastPoint 最后一次鼠标按下位置 nowPonit 鼠标当前位置 mousePos 鼠标在控件中的位置 - var nowPoint = Mouse.GetPosition(CanvasPanel.GetParentObject(AdornedElement)); - CanvasPanel.GetParentObject(AdornedElement).ReCtrlSize(lastPoint, nowPoint, mousePos); - lastPoint = nowPoint; - } - else if (Mouse.MiddleButton == MouseButtonState.Pressed)//中间同步拖拽控件大小 - { - CaptureMouse(); - var nowPoint = Mouse.GetPosition(CanvasPanel.GetParentObject(AdornedElement)); - int offsetX = (int)(nowPoint.X - lastPoint.X); - int offsetY = (int)(nowPoint.Y - lastPoint.Y); - CanvasPanel.GetParentObject(AdornedElement).ZoomControls(offsetX, offsetY); - lastPoint = nowPoint; - } - } - - private void SelectionAdorner_MouseDown(object sender, MouseButtonEventArgs e) - { - var canv = CanvasPanel.GetParentObject(AdornedElement); - lastPoint = Mouse.GetPosition(canv); - Keyboard.Focus(canv); - - if (Keyboard.Modifiers == ModifierKeys.Control && e != null) - { - var layer = AdornerLayer.GetAdornerLayer(AdornedElement); - var arr = layer.GetAdorners(AdornedElement); - if (canv.SelectedItems.Contains(AdornedElement)) - { - canv.SelectedItems.Remove(AdornedElement as FrameworkElement); - canv.RefreshSelection(); - } - } - } - } - - /// - /// 鼠标在控件中的位置 - /// - public enum MousePos - { - None, - Top, - Right, - Bottom, - Left, - LeftTop, - LeftBottom, - RightTop, - RightBottom - } -} diff --git a/BeDesignerSCADA/Adorners/SelectionAlignLine.cs b/BeDesignerSCADA/Adorners/SelectionAlignLine.cs deleted file mode 100644 index 38be84d8..00000000 --- a/BeDesignerSCADA/Adorners/SelectionAlignLine.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Media; - -namespace BeDesignerSCADA.Adorners -{ - public class SelectionAlignLine : Adorner - { - public SelectionAlignLine(UIElement adornedElement, Point start, Point end) : base(adornedElement) - { - startPoint = start; - endPoint = end; - } - - Point startPoint = default(Point); - Point endPoint = default(Point); - protected override void OnRender(DrawingContext drawingContext) - { - base.OnRender(drawingContext); - Rect adornerRect = new Rect(AdornedElement.DesiredSize); - Pen render = new Pen(new SolidColorBrush(Colors.RoyalBlue), 1); - render.DashCap = PenLineCap.Round; - render.DashStyle = new DashStyle(new List() { 4, 2 }, 2); - drawingContext.DrawLine(render, startPoint, endPoint); - } - } -} diff --git a/BeDesignerSCADA/BeDesignerSCADA.csproj b/BeDesignerSCADA/BeDesignerSCADA.csproj index 5bf728ff..fbf1f44f 100644 --- a/BeDesignerSCADA/BeDesignerSCADA.csproj +++ b/BeDesignerSCADA/BeDesignerSCADA.csproj @@ -8,9 +8,21 @@ Images\fyf.ico + + + + + + + + + + + + @@ -68,15 +80,6 @@ - - - DLL\Antlr3.Runtime.dll - - - DLL\Unvell.ReoScript.dll - - - @@ -102,11 +105,22 @@ - + + + ..\BPASmartClient.SCADAControl\DLL\Antlr3.Runtime.dll + + + ..\BPASmartClient.SCADAControl\DLL\BPASmartClient.Compiler.dll + + + ..\BPASmartClient.SCADAControl\DLL\Unvell.ReoScript.dll + + + diff --git a/BeDesignerSCADA/Controls/CanvasPanel.cs b/BeDesignerSCADA/Controls/CanvasPanel.cs deleted file mode 100644 index 40f37ead..00000000 --- a/BeDesignerSCADA/Controls/CanvasPanel.cs +++ /dev/null @@ -1,990 +0,0 @@ -using BeDesignerSCADA.Adorners; -using BeDesignerSCADA.Speical; -using BPASmartClient.Compiler; -using BPASmartClient.SCADAControl; -using Microsoft.Toolkit.Mvvm.Input; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Markup; -using System.Windows.Media; -using System.Windows.Shapes; -using System.Xml; - -namespace BeDesignerSCADA.Controls -{ - public class CanvasPanel : Canvas - { - public CanvasPanel() - { - UseLayoutRounding = true; - Drop += CanvasPanel_Drop; - CopySelectItemsCommand = new RelayCommand(CopySelectItems); - PasteSelectItemsCommand = new RelayCommand(PasteSelectItems); - DeleteSelectItemsCommand = new RelayCommand(DeleteSelectItems); - SetTopLayerCommand = new RelayCommand(SetTopLayer); - SetBottomLayerCommand = new RelayCommand(SetBottomLayer); - SelectedItems = new ObservableCollection(); - ContextMenu=Application.Current.Resources["CanvasRightMenu"] as ContextMenu; - KeyDown += CanvasPanel_KeyDown; - } - - #region 添加控件 - private void CanvasPanel_Drop(object sender, DragEventArgs e) - { - Type type = e.Data.GetData("System.RuntimeType") as Type; - var t = type.GetCustomAttributes(typeof(ControlTypeAttribute), false); - if (t.Length > 0) - { - Console.WriteLine((t as ControlTypeAttribute[])[0].Group); - } - - try - { - var control = Activator.CreateInstance(type) as FrameworkElement; - control.Name = GetControlName(type); - Children.Add(control); - - var xPos = e.GetPosition(this).X; - var yPos = e.GetPosition(this).Y; - if (xPos % GridPxiel != 0) - xPos = (GridPxiel - xPos % GridPxiel) + xPos; - if (yPos % GridPxiel != 0) - yPos = (GridPxiel - yPos % GridPxiel) + yPos; - - SetLeft(control, xPos); - SetTop(control, yPos); - - SelectedItems = new ObservableCollection() { control }; - SelectedItem = control; - } - catch (Exception) - { - } - - } - - string GetControlName(Type ctrlType) - { - var children = Children.GetEnumerator(); - children.Reset(); - List names = new List(); - while (children.MoveNext()) - { - if (children.Current.GetType().Name == ctrlType.Name) - { - names.Add((children.Current as FrameworkElement).Name); - } - } - - var nameIndex = names.Count; - while (names.Contains($"{ctrlType.Name.ToLower().Replace("the", string.Empty)}{nameIndex}")) - { - nameIndex++; - } - - return $"{ctrlType.Name.ToLower().Replace("the", string.Empty)}{nameIndex}"; - } - #endregion - - #region 初始化 - protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) - { - if (visualAdded is Border || visualRemoved is Border) - { - return; - } - - if (visualAdded is FrameworkElement ctrl) - { - ctrl.PreviewMouseLeftButtonDown += Ctrl_MouseLeftButtonDown; - } - if (visualRemoved is FrameworkElement ctr) - { - ctr.PreviewMouseLeftButtonDown -= Ctrl_MouseLeftButtonDown; - } - - base.OnVisualChildrenChanged(visualAdded, visualRemoved); - } - #endregion - - #region 单击选中项处理 - /// - /// 单击了控件时:不调用框选的刷新方式 - /// - bool isClickedControl = false; - /// - /// 左键按下 - /// - /// - /// - private void Ctrl_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) - { - if (sender is FrameworkElement ctl) - { - var cp = GetParentObject(ctl); - if (Keyboard.Modifiers == ModifierKeys.Control) - { - cp.SelectedItems.Add(ctl); - } - else - { - cp.SelectedItems = new ObservableCollection() { ctl }; - } - isClickedControl = true; - RefreshSelection(); - } - } - /// - /// 获取属性 - /// - /// - /// - /// - public static T GetParentObject(DependencyObject obj) where T : FrameworkElement - { - DependencyObject parent = VisualTreeHelper.GetParent(obj); - while (parent != null) - { - if (parent is T) - { - return (T)parent; - } - parent = VisualTreeHelper.GetParent(parent); - } - return null; - } - #endregion - - #region 右键菜单 - #endregion - - #region 绘制选择框 - Border selectionBorder = new Border() - { - Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#557F7F7F")), - BorderThickness = new Thickness(1), - BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF303030")), - }; - - protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) - { - base.OnMouseLeftButtonDown(e); - selectionStart = e.GetPosition(this); - if (!this.Children.Contains(selectionBorder)) - { - this.Children.Add(selectionBorder); - this.CaptureMouse(); - } - - } - - Point selectionStart = default; - protected override void OnMouseMove(MouseEventArgs e) - { - if (isClickedControl) - { - return; - } - base.OnMouseMove(e); - if (e.LeftButton == MouseButtonState.Pressed) - { - var nowPoint = e.GetPosition(this); - - var offsetX = nowPoint.X - selectionStart.X; - var offsetY = nowPoint.Y - selectionStart.Y; - Clear(); - - selectionBorder.Width = Math.Abs(offsetX); - selectionBorder.Height = Math.Abs(offsetY); - // 分四种情况绘制 - if (offsetX >= 0 && offsetY >= 0)// 右下 - { - SetLeft(selectionBorder, selectionStart.X); - SetTop(selectionBorder, selectionStart.Y); - } - else if (offsetX > 0 && offsetY < 0)// 右上 - { - SetLeft(selectionBorder, selectionStart.X); - SetBottom(selectionBorder, ActualHeight - selectionStart.Y); - - } - else if (offsetX < 0 && offsetY > 0)// 左下 - { - SetRight(selectionBorder, ActualWidth - selectionStart.X); - SetTop(selectionBorder, selectionStart.Y); - } - else if (offsetX < 0 && offsetY < 0)// 左上 - { - SetRight(selectionBorder, ActualWidth - selectionStart.X); - SetBottom(selectionBorder, ActualHeight - selectionStart.Y); - } - - - } - } - - protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) - { - base.OnMouseLeftButtonUp(e); - if (double.IsNaN(GetLeft(selectionBorder))) - { - SetLeft(selectionBorder, ActualWidth - GetRight(selectionBorder) - selectionBorder.ActualWidth); - } - if (double.IsNaN(GetTop(selectionBorder))) - { - SetTop(selectionBorder, ActualHeight - GetBottom(selectionBorder) - selectionBorder.ActualHeight); - } - - FrameSelection(GetLeft(selectionBorder), GetTop(selectionBorder), selectionBorder.Width, selectionBorder.Height); - selectionBorder.Width = 0; - selectionBorder.Height = 0; - this.Children.Remove(selectionBorder); - this.ReleaseMouseCapture(); - } - - private void Clear() - { - SetLeft(selectionBorder, double.NaN); - SetRight(selectionBorder, double.NaN); - SetTop(selectionBorder, double.NaN); - SetBottom(selectionBorder, double.NaN); - } - - #endregion - - #region 选中属性 - public FrameworkElement SelectedItem - { - get { return (FrameworkElement)GetValue(SelectedItemProperty); } - set { SetValue(SelectedItemProperty, value); } - } - public static readonly DependencyProperty SelectedItemProperty = - DependencyProperty.Register("SelectedItem", typeof(FrameworkElement), typeof(CanvasPanel), new PropertyMetadata(null, OnSelectedItemChanged)); - private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as CanvasPanel)?.RefreshSelection1(); - public void RefreshSelection1() - { - - } - #endregion - - #region 框选 - public ObservableCollection SelectedItems - { - get { return (ObservableCollection)GetValue(SelectedItemsProperty); } - set { SetValue(SelectedItemsProperty, value); } - } - public static readonly DependencyProperty SelectedItemsProperty = - DependencyProperty.Register("SelectedItems", typeof(ObservableCollection), typeof(CanvasPanel), new PropertyMetadata(null, OnSelectedItemsChanged)); - - private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as CanvasPanel)?.RefreshSelection(); - - public void RefreshSelection() - { - foreach (var item in Children) - { - if (!(item is IExecutable)) - continue; - - var ele = item as FrameworkElement; - if (ele == null) continue; - - var layer = AdornerLayer.GetAdornerLayer(ele); - var arr = layer.GetAdorners(ele);//获取该控件上所有装饰器,返回一个数组 - if (arr != null) - { - for (int i = arr.Length - 1; i >= 0; i--) - { - layer.Remove(arr[i]); - } - } - } - - if (SelectedItems != null) - { - foreach (var item in SelectedItems) - { - var layer = AdornerLayer.GetAdornerLayer(item); - layer.Add(new SelectionAdorner(item)); - SelectedItem = item; - } - } - } - - /// - /// 移除所有选择装饰器 - /// - public void ClearSelection() - { - foreach (var item in Children) - { - if (!(item is IExecutable)) - continue; - - var ele = item as FrameworkElement; - if (ele == null) continue; - - var layer = AdornerLayer.GetAdornerLayer(ele); - var arr = layer.GetAdorners(ele);//获取该控件上所有装饰器,返回一个数组 - if (arr != null) - { - for (int i = arr.Length - 1; i >= 0; i--) - { - layer.Remove(arr[i]); - } - } - } - } - - /// - /// 计算框选项 - /// - private void FrameSelection(double x, double y, double width, double height) - { - if (width > 0 || height > 0) - { - isClickedControl = false; - } - if (isClickedControl) - { - isClickedControl = false; - SelectedItems = new ObservableCollection(); - return; - } - SelectedItems = new ObservableCollection(); - foreach (var item in Children) - { - if (item is FrameworkElement ctrl && !(ctrl is Border)) - { - // 框左上角 - var left = GetLeft(ctrl); - var top = GetTop(ctrl); - if (left >= x && left <= x + width && top >= y && top <= y + height) - { - if (!SelectedItems.Contains(ctrl)) - SelectedItems.Add(ctrl); - } - - // 框右下角 - var right = left + ctrl.ActualWidth; - var bottom = top + ctrl.ActualHeight; - if (right >= x && right <= x + width && bottom >= y && bottom <= y + height) - { - if (!SelectedItems.Contains(ctrl)) - SelectedItems.Add(ctrl); - } - - // 框右上角 - if (right >= x && right <= x + width && top >= y && top <= y + height) - { - if (!SelectedItems.Contains(ctrl)) - SelectedItems.Add(ctrl); - } - - // 框左下角 - if (left >= x && left <= x + width && bottom >= y && bottom <= y + height) - { - if (!SelectedItems.Contains(ctrl)) - SelectedItems.Add(ctrl); - } - } - } - - RefreshSelection(); - } - #endregion - - #region 外部调用 - public List GetAllExecChildren() - { - List result = new List(); - foreach (var ctrl in Children) - { - if (ctrl is IExecutable exec) - { - result.Add(ctrl as FrameworkElement); - } - } - - return result; - } - - /// - /// 对齐像素单位 - /// - public int GridPxiel - { - get { return (int)GetValue(GridPxielProperty); } - set { SetValue(GridPxielProperty, value); } - } - public static readonly DependencyProperty GridPxielProperty = - DependencyProperty.Register("GridPxiel", typeof(int), typeof(CanvasPanel), new PropertyMetadata(4)); - - - public void MoveControls(double offsetX, double offsetY) - { - ClearAlignLine(); - - // 获取可对齐的点 - List points = new List(); - foreach (FrameworkElement ctrl in Children) - { - if (!SelectedItems.Contains(ctrl)) - { - // 左上的点 - Point item = new Point(GetLeft(ctrl), GetTop(ctrl)); - points.Add(item); - - // 左下的点 - Point itemlb = new Point(GetLeft(ctrl), GetTop(ctrl) + ctrl.ActualHeight); - points.Add(itemlb); - - // 右下的点 - Point itemrb = new Point(GetLeft(ctrl) + ctrl.ActualWidth, GetTop(ctrl) + ctrl.ActualHeight); - points.Add(itemrb); - - // 右上的点 - Point itemrt = new Point(GetLeft(ctrl) + ctrl.ActualWidth, GetTop(ctrl)); - points.Add(itemrt); - } - } - - // 控件移动 - foreach (var item in SelectedItems) - { - var moveX = GetLeft(item) + offsetX; - moveX = (moveX < 0) ? 0 : moveX; - - var moveY = GetTop(item) + offsetY; - moveY = moveY < 0 ? 0 : moveY; - - if (moveX % GridPxiel != 0) - moveX = (GridPxiel - moveX % GridPxiel) + moveX; - if (moveY % GridPxiel != 0) - moveY = (GridPxiel - moveY % GridPxiel) + moveY; - - SetLeft(item, moveX); - SetTop(item, moveY); - } - - // 计算是否显示对齐线 - var targetItemTop = SelectedItems?.Min(x => GetTop(x)); - var targetItem = SelectedItems.FirstOrDefault(x => GetTop(x) == targetItemTop); - var lefAlign = points.FirstOrDefault(x => Math.Abs(x.X - GetLeft(targetItem)) == 0); - if (lefAlign != default) - { - //SetLeft(targetItem, lefAlign.X); - var layer = AdornerLayer.GetAdornerLayer(this); - layer.Add(new SelectionAlignLine(this, lefAlign, new Point(GetLeft(targetItem), GetTop(targetItem)))); - } - - var topAlign = points.FirstOrDefault(x => Math.Abs(x.Y - GetTop(targetItem)) == 0); - if (topAlign != default) - { - //SetTop(targetItem, topAlign.Y); - var layer = AdornerLayer.GetAdornerLayer(this); - layer.Add(new SelectionAlignLine(this, topAlign, new Point(GetLeft(targetItem), GetTop(targetItem)))); - } - - int px = 20; - // 网格对齐 - if (UseAutoAlignment) - { - foreach (var item in SelectedItems) - { - var left = GetLeft(item); - if (left % px <= 1) - { - SetLeft(item, (int)left / px * px); - } - - var top = GetTop(item); - if (top % px <= 1) - { - SetTop(item, (int)top / px * px); - } - } - } - } - - /// - /// 清除绘制的对齐线 - /// - public void ClearAlignLine() - { - var arr = AdornerLayer.GetAdornerLayer(this).GetAdorners(this); - if (arr != null) - { - for (int i = arr.Length - 1; i >= 0; i--) - { - AdornerLayer.GetAdornerLayer(this).Remove(arr[i]); - } - } - } - - public void ZoomControls(int offsetX, int offsetY) - { - foreach (var item in SelectedItems) - { - if (item.ActualHeight + offsetY > 10) - { - item.Height += offsetY; - } - if (item.ActualWidth + offsetX > 10) - { - item.Width += offsetX; - } - } - } - - /// - /// 调整控件大小:鼠标在控件中的不同位置,调整控件大小 - /// - public void ReCtrlSize(Point lastPoint,Point currentPoint, MousePos mousePos) - { - foreach (var control in SelectedItems) - { - //计算偏移量 - double x = currentPoint.X - lastPoint.X; - double y = currentPoint.Y - lastPoint.Y; - switch (mousePos) - { - case MousePos.None: - break; - case MousePos.Top://上,调整 - if (control.Height - y > control.MinHeight) - { - SetTop(control, GetTop(control) + y); - //control.Top += y; - control.Height -= y; - } - break; - case MousePos.Right: - if (control.Width + x > control.MinWidth) - { - control.Width += x; - } - break; - case MousePos.Bottom: - if (control.Height + y > control.MinHeight) - { - control.Height += y; - } - break; - case MousePos.Left: - if (control.Width - x > control.MinWidth) - { - SetLeft(control, GetLeft(control) + x);//control.Left += x; - control.Width -= x; - } - break; - case MousePos.LeftTop://左上 - if (control.Width - x > control.MinWidth) - { - SetLeft(control, GetLeft(control) + x);//control.Left += x; - control.Width -= x; - } - if (control.Height - y > control.MinHeight) - { - SetTop(control, GetTop(control) + y);//control.Top += y; - control.Height -= y; - } - break; - case MousePos.LeftBottom: - if (control.Width - x > control.MinWidth) - { - SetLeft(control, GetLeft(control) + x);//control.Left += x; - control.Width -= x; - } - if (control.Height + y > control.MinHeight) - { - control.Height += y; - } - break; - case MousePos.RightTop: - if (control.Width + x > MinWidth) - { - control.Width += x; - } - if (control.Height - y > MinHeight) - { - SetTop(control, GetTop(control) + y);//control.Top += y; - control.Height -= y; - } - break; - case MousePos.RightBottom: - if (control.Width + x > MinWidth) - { - control.Width += x; - } - if (control.Height + y > MinHeight) - { - control.Height += y; - } - break; - default: - break; - } - } - - } - #endregion - - #region 对齐操作 - /// - /// 是否使用网格对齐 10px - /// - public bool UseAutoAlignment - { - get { return (bool)GetValue(UseAutoAlignmentProperty); } - set { SetValue(UseAutoAlignmentProperty, value); } - } - public static readonly DependencyProperty UseAutoAlignmentProperty = - DependencyProperty.Register("UseAutoAlignment", typeof(bool), typeof(CanvasPanel), new PropertyMetadata(false)); - - - public void AlignLeft() - { - if (SelectedItems == null || SelectedItems.Count == 0) - return; - - var leftMin = SelectedItems.Min(x => Canvas.GetLeft(x)); - foreach (var item in SelectedItems) - { - SetLeft(item, leftMin); - } - } - - public void AlignRight() - { - if (SelectedItems == null || SelectedItems.Count == 0) - return; - - var rightMax = SelectedItems.Max(x => GetLeft(x) + x.ActualWidth); - foreach (var item in SelectedItems) - { - var targetLeft = rightMax - item.ActualWidth; - SetLeft(item, targetLeft); - } - } - - public void AlignCenter() - { - if (SelectedItems == null || SelectedItems.Count == 0) - return; - - var leftmin = SelectedItems.Min(x => GetLeft(x)); - var rightmax = SelectedItems.Max(x => GetLeft(x) + x.ActualWidth); - var center = (rightmax - leftmin) / 2 + leftmin; - - foreach (var item in SelectedItems) - { - var target = center - (item.ActualWidth / 2); - SetLeft(item, target); - } - } - - public void AlignTop() - { - if (SelectedItems == null || SelectedItems.Count == 0) - return; - - var topMin = SelectedItems.Min(x => GetTop(x)); - foreach (var item in SelectedItems) - { - SetTop(item, topMin); - } - } - - public void AlignBottom() - { - if (SelectedItems == null || SelectedItems.Count == 0) - return; - - var botMax = SelectedItems.Max(x => GetTop(x) + x.ActualHeight); - foreach (var item in SelectedItems) - { - var targetLeft = botMax - item.ActualHeight; - SetTop(item, targetLeft); - } - } - - public void VertialLayout() - { - if (SelectedItems == null || SelectedItems.Count < 3) - return; - - var topCtl = SelectedItems.Min(x => GetTop(x) + x.ActualHeight); - var botCtrl = SelectedItems.Max(x => GetTop(x)); - var emptyHeight = botCtrl - topCtl; - - var orderCtrl = SelectedItems.OrderBy(x => GetTop(x)).ToList(); - orderCtrl.RemoveAt(0); - orderCtrl.RemoveAt(orderCtrl.Count - 1); - var useSpace = orderCtrl.Sum(x => x.ActualHeight); - - var ableSpaceAvg = (emptyHeight - useSpace) / (SelectedItems.Count - 1); - double nowPostion = topCtl; - foreach (var item in orderCtrl) - { - SetTop(item, nowPostion + ableSpaceAvg); - nowPostion += item.ActualHeight + ableSpaceAvg; - } - } - - public void HorizontalLayout() - { - if (SelectedItems == null || SelectedItems.Count < 3) - return; - - var leftCtl = SelectedItems.Min(x => GetLeft(x) + x.ActualWidth); - var rightCtrl = SelectedItems.Max(x => GetLeft(x)); - var emptyHeight = rightCtrl - leftCtl; - - var orderCtrl = SelectedItems.OrderBy(x => GetLeft(x)).ToList(); - orderCtrl.RemoveAt(0); - orderCtrl.RemoveAt(orderCtrl.Count - 1); - var useSpace = orderCtrl.Sum(x => x.ActualWidth); - - var ableSpaceAvg = (emptyHeight - useSpace) / (SelectedItems.Count - 1); - double nowPostion = leftCtl; - foreach (var item in orderCtrl) - { - SetLeft(item, nowPostion + ableSpaceAvg); - nowPostion += item.ActualWidth + ableSpaceAvg; - } - } - #endregion - - #region 按键操作 - public RelayCommand CopySelectItemsCommand { get; set; } - public RelayCommand PasteSelectItemsCommand { get; set; } - public RelayCommand DeleteSelectItemsCommand { get; set; } - public RelayCommand SetTopLayerCommand { get; set; } - public RelayCommand SetBottomLayerCommand { get; set; } - - List copyTemp = new List(); - - private void CanvasPanel_KeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control) - { - CopySelectItems(); - } - else if (e.Key == Key.V && Keyboard.Modifiers == ModifierKeys.Control) - { - PasteSelectItems(); - } - else if (e.Key == Key.Delete) - { - DeleteSelectItems(); - } - else if (e.Key == Key.Up) - { - var offset = -1; - foreach (var item in SelectedItems) - { - SetTop(item, (GetTop(item) + offset) < 0 ? 0 : GetTop(item) + offset); - } - e.Handled = true; - } - else if (e.Key == Key.Down) - { - var offset = 1; - foreach (var item in SelectedItems) - { - SetTop(item, (GetTop(item) + offset) < 0 ? 0 : GetTop(item) + offset); - } - e.Handled = true; - } - else if (e.Key == Key.Left) - { - var offset = -1; - foreach (var item in SelectedItems) - { - SetLeft(item, (GetLeft(item) + offset) < 0 ? 0 : GetLeft(item) + offset); - } - e.Handled = true; - - } - else if (e.Key == Key.Right) - { - var offset = 1; - foreach (var item in SelectedItems) - { - SetLeft(item, (GetLeft(item) + offset) < 0 ? 0 : GetLeft(item) + offset); - } - e.Handled = true; - } - } - - /// - /// 复制 - /// - public void CopySelectItems() - { - copyTemp.Clear(); - foreach (var item in SelectedItems) - { - copyTemp.Add(item); - } - } - - /// - /// 粘贴 - /// - public void PasteSelectItems() - { - SelectedItems.Clear(); - foreach (var item in copyTemp) - { - var xml = XamlWriter.Save(item); - var element = XamlReader.Parse(xml) as FrameworkElement; - element.Name += "_1"; - - SetLeft(element, GetLeft(element) + 10); - SetTop(element, GetTop(element) + 10); - - Children.Add(element); - SelectedItems.Add(element); - } - - // 将复制的内容替换 以便处理连续复制 - copyTemp.Clear(); - foreach (var item in SelectedItems) - { - copyTemp.Add(item); - } - RefreshSelection(); - } - - /// - /// 置于顶层 - /// - public void SetTopLayer() - { - if (SelectedItems.Count == 0) - return; - - foreach (var item in SelectedItems) - { - Children.Remove(item); - } - - foreach (var item in SelectedItems) - { - Children.Add(item); - } - } - - /// - /// 置于底层 - /// - public void SetBottomLayer() - { - if (SelectedItems.Count == 0) - return; - - foreach (var item in SelectedItems) - { - Children.Remove(item); - } - - foreach (var item in SelectedItems) - { - Children.Insert(0, item); - } - } - /// - /// 删除 - /// - public void DeleteSelectItems() - { - foreach (var item in SelectedItems) - { - Children.Remove(item); - } - - SelectedItems.Clear(); - RefreshSelection(); - } - #endregion - - #region 运行Xaml 保存 读取 - public List Generator() - { - List elements = new List(); - foreach (var item in Children) - { - // 排除非自定义的控件们 - if (!(item is IExecutable)) - continue; - if(item is IDisposable) (item as IDisposable).Dispose(); - var xml = XamlWriter.Save(item); - var ele = XamlReader.Parse(xml) as FrameworkElement; - elements.Add(ele); - } - - return elements; - } - - /// - /// 保存数据到文本 - /// - public string Save() - { - StringBuilder sb = new StringBuilder(); - - foreach (var item in Children) - { - // 排除非自定义的控件们 - if (!(item is IExecutable)) - continue; - if (item is IDisposable) (item as IDisposable).Dispose(); - var xml = XamlWriter.Save(item); - sb.Append(xml + "\r\n"); - } - - return sb.ToString(); - } - - /// - /// 读取文件 - /// - public void Load(string path) - { - Children.Clear(); - FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Unicode)) - { - while (sr.Peek() > -1) - { - string str = sr.ReadLine(); - try - { - var ele = XamlReader.Parse(str) as FrameworkElement; - Children.Add(ele); - } - catch (Exception ex) - { - - } - - } - } - - SelectedItems?.Clear(); - } - #endregion - } -} diff --git a/BeDesignerSCADA/Controls/MainCanvasPanel.xaml b/BeDesignerSCADA/Controls/MainCanvasPanel.xaml index 93c2c854..7a4290c9 100644 --- a/BeDesignerSCADA/Controls/MainCanvasPanel.xaml +++ b/BeDesignerSCADA/Controls/MainCanvasPanel.xaml @@ -1,4 +1,5 @@ - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - --> - - +