Browse Source

总控模块UI

Linsk 3 months ago
parent
commit
5a8d9cc9a2
30 changed files with 2173 additions and 12 deletions
  1. 1 1
      Scada/Page/PageAuthManage.Designer.cs
  2. 1 1
      Scada/Page/PageChartManage.Designer.cs
  3. 1 1
      Scada/Page/PageEquipmentMonitor1.Designer.cs
  4. 1 1
      Scada/Page/PageEquipmentMonitor2.Designer.cs
  5. 1 1
      Scada/Page/PageEquipmentMonitor3.Designer.cs
  6. 1 1
      Scada/Page/PageLogManage.Designer.cs
  7. 1 1
      Scada/Page/PageRecipeManage.Designer.cs
  8. 1 1
      Scada/Page/PageReportManage.Designer.cs
  9. 1 1
      Scada/Page/PageSystemParameterSet.Designer.cs
  10. 334 3
      Scada/Page/PageTotalEquipmentControl.Designer.cs
  11. 1 0
      Scada/Page/PageTotalEquipmentControl.cs
  12. 14 0
      Scada/UIExtension.cs
  13. 98 0
      Scada/UserControls/UserAlarmState.Designer.cs
  14. 70 0
      Scada/UserControls/UserAlarmState.cs
  15. 120 0
      Scada/UserControls/UserAlarmState.resx
  16. 66 0
      Scada/UserControls/UserCounterButton.Designer.cs
  17. 111 0
      Scada/UserControls/UserCounterButton.cs
  18. 120 0
      Scada/UserControls/UserCounterButton.resx
  19. 98 0
      Scada/UserControls/UserDeviceState.Designer.cs
  20. 70 0
      Scada/UserControls/UserDeviceState.cs
  21. 120 0
      Scada/UserControls/UserDeviceState.resx
  22. 95 0
      Scada/UserControls/UserDeviceUnitControl.Designer.cs
  23. 85 0
      Scada/UserControls/UserDeviceUnitControl.cs
  24. 120 0
      Scada/UserControls/UserDeviceUnitControl.resx
  25. 115 0
      Scada/UserControls/UserSetValue.Designer.cs
  26. 94 0
      Scada/UserControls/UserSetValue.cs
  27. 120 0
      Scada/UserControls/UserSetValue.resx
  28. 115 0
      Scada/UserControls/UserVarCurrentValue.Designer.cs
  29. 78 0
      Scada/UserControls/UserVarCurrentValue.cs
  30. 120 0
      Scada/UserControls/UserVarCurrentValue.resx

+ 1 - 1
Scada/Page/PageAuthManage.Designer.cs

@@ -33,7 +33,7 @@
             // PageAuthManage
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Name = "PageAuthManage";
             Text = "PageAuthManage";
             Load += PageAuthManage_Load;

+ 1 - 1
Scada/Page/PageChartManage.Designer.cs

@@ -33,7 +33,7 @@
             // PageChartManage
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Name = "PageChartManage";
             Text = "PageChartManage";
             Load += PageChartManage_Load;

+ 1 - 1
Scada/Page/PageEquipmentMonitor1.Designer.cs

@@ -44,7 +44,7 @@
             // PageEquipmentMonitor1
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Controls.Add(uiLabel1);
             Name = "PageEquipmentMonitor1";
             Text = "PageEquipmentMonitor";

+ 1 - 1
Scada/Page/PageEquipmentMonitor2.Designer.cs

@@ -44,7 +44,7 @@
             // PageEquipmentMonitor2
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Controls.Add(uiLabel1);
             Name = "PageEquipmentMonitor2";
             Text = "PageEquipmentMonitor2";

+ 1 - 1
Scada/Page/PageEquipmentMonitor3.Designer.cs

@@ -44,7 +44,7 @@
             // PageEquipmentMonitor3
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Controls.Add(uiLabel1);
             Name = "PageEquipmentMonitor3";
             Text = "PageEquipmentMonitor3";

+ 1 - 1
Scada/Page/PageLogManage.Designer.cs

@@ -33,7 +33,7 @@
             // PageLogManage
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Name = "PageLogManage";
             Text = "PageLogManage";
             Load += PageLogManage_Load;

+ 1 - 1
Scada/Page/PageRecipeManage.Designer.cs

@@ -33,7 +33,7 @@
             // PageRecipeManage
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Name = "PageRecipeManage";
             Text = "PageRecipeManage";
             Load += PageRecipeManage_Load;

+ 1 - 1
Scada/Page/PageReportManage.Designer.cs

@@ -33,7 +33,7 @@
             // PageReportManage
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Name = "PageReportManage";
             Text = "PageReportManage";
             Load += PageReportManage_Load;

+ 1 - 1
Scada/Page/PageSystemParameterSet.Designer.cs

@@ -33,7 +33,7 @@
             // PageSystemParameterSet
             // 
             AutoScaleMode = AutoScaleMode.None;
-            ClientSize = new Size(1067, 497);
+            ClientSize = new Size(1067, 544);
             Name = "PageSystemParameterSet";
             Text = "PageSystemParameterSet";
             Load += PageSystemParameterSet_Load;

+ 334 - 3
Scada/Page/PageTotalEquipmentControl.Designer.cs

@@ -28,18 +28,349 @@
         /// </summary>
         private void InitializeComponent()
         {
+            uiTitlePanel1 = new Sunny.UI.UITitlePanel();
+            btn_DryRun = new Sunny.UI.UISymbolButton();
+            btn_AlarmReset = new Sunny.UI.UISymbolButton();
+            btn_MachineReset = new Sunny.UI.UISymbolButton();
+            btn_Stop = new Sunny.UI.UISymbolButton();
+            btn_Start = new Sunny.UI.UISymbolButton();
+            uiTitlePanel2 = new Sunny.UI.UITitlePanel();
+            device_SSJ = new UserDeviceUnitControl();
+            device_CX = new UserDeviceUnitControl();
+            device_JX = new UserDeviceUnitControl();
+            device_GHL = new UserDeviceUnitControl();
+            device_TH = new UserDeviceUnitControl();
+            device_LQS = new UserDeviceUnitControl();
+            device_SFL = new UserDeviceUnitControl();
+            device_TZ = new UserDeviceUnitControl();
+            uiTitlePanel3 = new Sunny.UI.UITitlePanel();
+            txt_Log = new Sunny.UI.UITextBox();
+            uiTitlePanel1.SuspendLayout();
+            uiTitlePanel2.SuspendLayout();
+            uiTitlePanel3.SuspendLayout();
             SuspendLayout();
             // 
+            // uiTitlePanel1
+            // 
+            uiTitlePanel1.Controls.Add(btn_DryRun);
+            uiTitlePanel1.Controls.Add(btn_AlarmReset);
+            uiTitlePanel1.Controls.Add(btn_MachineReset);
+            uiTitlePanel1.Controls.Add(btn_Stop);
+            uiTitlePanel1.Controls.Add(btn_Start);
+            uiTitlePanel1.Dock = DockStyle.Top;
+            uiTitlePanel1.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            uiTitlePanel1.Location = new Point(0, 0);
+            uiTitlePanel1.Margin = new Padding(4, 5, 4, 5);
+            uiTitlePanel1.MinimumSize = new Size(1, 1);
+            uiTitlePanel1.Name = "uiTitlePanel1";
+            uiTitlePanel1.ShowText = false;
+            uiTitlePanel1.Size = new Size(1067, 189);
+            uiTitlePanel1.TabIndex = 0;
+            uiTitlePanel1.Text = "厂线总控制";
+            uiTitlePanel1.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // btn_DryRun
+            // 
+            btn_DryRun.Font = new Font("微软雅黑", 21.75F);
+            btn_DryRun.Location = new Point(870, 68);
+            btn_DryRun.MinimumSize = new Size(1, 1);
+            btn_DryRun.Name = "btn_DryRun";
+            btn_DryRun.Radius = 10;
+            btn_DryRun.Size = new Size(181, 84);
+            btn_DryRun.Symbol = 61452;
+            btn_DryRun.SymbolSize = 55;
+            btn_DryRun.TabIndex = 4;
+            btn_DryRun.TagString = "空运行";
+            btn_DryRun.Text = "空运行";
+            btn_DryRun.TipsFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            // 
+            // btn_AlarmReset
+            // 
+            btn_AlarmReset.Font = new Font("微软雅黑", 20F);
+            btn_AlarmReset.Location = new Point(645, 68);
+            btn_AlarmReset.MinimumSize = new Size(1, 1);
+            btn_AlarmReset.Name = "btn_AlarmReset";
+            btn_AlarmReset.Radius = 10;
+            btn_AlarmReset.Size = new Size(210, 84);
+            btn_AlarmReset.Symbol = 61473;
+            btn_AlarmReset.SymbolSize = 55;
+            btn_AlarmReset.TabIndex = 3;
+            btn_AlarmReset.TagString = "报警复位";
+            btn_AlarmReset.Text = "报警复位";
+            btn_AlarmReset.TipsFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            // 
+            // btn_MachineReset
+            // 
+            btn_MachineReset.Font = new Font("微软雅黑", 20F);
+            btn_MachineReset.Location = new Point(414, 68);
+            btn_MachineReset.MinimumSize = new Size(1, 1);
+            btn_MachineReset.Name = "btn_MachineReset";
+            btn_MachineReset.Radius = 10;
+            btn_MachineReset.Size = new Size(210, 84);
+            btn_MachineReset.Symbol = 61473;
+            btn_MachineReset.SymbolSize = 55;
+            btn_MachineReset.TabIndex = 2;
+            btn_MachineReset.TagString = "机械复位";
+            btn_MachineReset.Text = "机械复位";
+            btn_MachineReset.TipsFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            // 
+            // btn_Stop
+            // 
+            btn_Stop.Font = new Font("微软雅黑", 21.75F);
+            btn_Stop.Location = new Point(216, 68);
+            btn_Stop.MinimumSize = new Size(1, 1);
+            btn_Stop.Name = "btn_Stop";
+            btn_Stop.Radius = 10;
+            btn_Stop.Size = new Size(181, 84);
+            btn_Stop.Symbol = 62093;
+            btn_Stop.SymbolSize = 55;
+            btn_Stop.TabIndex = 1;
+            btn_Stop.TagString = "总停止";
+            btn_Stop.Text = "总停止";
+            btn_Stop.TipsFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            // 
+            // btn_Start
+            // 
+            btn_Start.Font = new Font("微软雅黑", 21.75F);
+            btn_Start.Location = new Point(23, 68);
+            btn_Start.MinimumSize = new Size(1, 1);
+            btn_Start.Name = "btn_Start";
+            btn_Start.Radius = 10;
+            btn_Start.Size = new Size(181, 84);
+            btn_Start.Symbol = 561649;
+            btn_Start.SymbolSize = 55;
+            btn_Start.TabIndex = 0;
+            btn_Start.TagString = "总启动";
+            btn_Start.Text = "总启动";
+            btn_Start.TipsFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            // 
+            // uiTitlePanel2
+            // 
+            uiTitlePanel2.Controls.Add(device_SSJ);
+            uiTitlePanel2.Controls.Add(device_CX);
+            uiTitlePanel2.Controls.Add(device_JX);
+            uiTitlePanel2.Controls.Add(device_GHL);
+            uiTitlePanel2.Controls.Add(device_TH);
+            uiTitlePanel2.Controls.Add(device_LQS);
+            uiTitlePanel2.Controls.Add(device_SFL);
+            uiTitlePanel2.Controls.Add(device_TZ);
+            uiTitlePanel2.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            uiTitlePanel2.Location = new Point(4, 199);
+            uiTitlePanel2.Margin = new Padding(4, 5, 4, 5);
+            uiTitlePanel2.MinimumSize = new Size(1, 1);
+            uiTitlePanel2.Name = "uiTitlePanel2";
+            uiTitlePanel2.ShowText = false;
+            uiTitlePanel2.Size = new Size(563, 341);
+            uiTitlePanel2.TabIndex = 1;
+            uiTitlePanel2.Text = "设备单元控制";
+            uiTitlePanel2.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_SSJ
+            // 
+            device_SSJ.BackColor = Color.Transparent;
+            device_SSJ.CloseVariableName = "输送机工位关";
+            device_SSJ.EquipmentUnitName = "输送机工位";
+            device_SSJ.FillColor = Color.Transparent;
+            device_SSJ.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_SSJ.Location = new Point(278, 273);
+            device_SSJ.MinimumSize = new Size(1, 1);
+            device_SSJ.Name = "device_SSJ";
+            device_SSJ.OpenVariableName = "输送机工位开";
+            device_SSJ.RectColor = Color.Transparent;
+            device_SSJ.Size = new Size(265, 46);
+            device_SSJ.State = false;
+            device_SSJ.TabIndex = 3;
+            device_SSJ.Text = "userDeviceUnitControl1";
+            device_SSJ.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_CX
+            // 
+            device_CX.BackColor = Color.Transparent;
+            device_CX.CloseVariableName = "粗细工位关";
+            device_CX.EquipmentUnitName = "粗细工位";
+            device_CX.FillColor = Color.Transparent;
+            device_CX.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_CX.Location = new Point(19, 126);
+            device_CX.MinimumSize = new Size(1, 1);
+            device_CX.Name = "device_CX";
+            device_CX.OpenVariableName = "粗细工位开";
+            device_CX.RectColor = Color.Transparent;
+            device_CX.Size = new Size(253, 46);
+            device_CX.State = false;
+            device_CX.TabIndex = 1;
+            device_CX.Text = "userDeviceUnitControl1";
+            device_CX.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_JX
+            // 
+            device_JX.BackColor = Color.Transparent;
+            device_JX.CloseVariableName = "精洗工位关";
+            device_JX.EquipmentUnitName = "精洗工位";
+            device_JX.FillColor = Color.Transparent;
+            device_JX.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_JX.Location = new Point(19, 273);
+            device_JX.MinimumSize = new Size(1, 1);
+            device_JX.Name = "device_JX";
+            device_JX.OpenVariableName = "精洗工位开";
+            device_JX.RectColor = Color.Transparent;
+            device_JX.Size = new Size(253, 46);
+            device_JX.State = false;
+            device_JX.TabIndex = 2;
+            device_JX.Text = "userDeviceUnitControl1";
+            device_JX.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_GHL
+            // 
+            device_GHL.BackColor = Color.Transparent;
+            device_GHL.CloseVariableName = "固化炉工位关";
+            device_GHL.EquipmentUnitName = "固化炉工位";
+            device_GHL.FillColor = Color.Transparent;
+            device_GHL.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_GHL.Location = new Point(278, 197);
+            device_GHL.MinimumSize = new Size(1, 1);
+            device_GHL.Name = "device_GHL";
+            device_GHL.OpenVariableName = "固化炉工位开";
+            device_GHL.RectColor = Color.Transparent;
+            device_GHL.Size = new Size(265, 46);
+            device_GHL.State = false;
+            device_GHL.TabIndex = 3;
+            device_GHL.Text = "userDeviceUnitControl1";
+            device_GHL.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_TH
+            // 
+            device_TH.BackColor = Color.Transparent;
+            device_TH.CloseVariableName = "陶化工位关";
+            device_TH.EquipmentUnitName = "陶化工位";
+            device_TH.FillColor = Color.Transparent;
+            device_TH.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_TH.Location = new Point(19, 197);
+            device_TH.MinimumSize = new Size(1, 1);
+            device_TH.Name = "device_TH";
+            device_TH.OpenVariableName = "陶化工位开";
+            device_TH.RectColor = Color.Transparent;
+            device_TH.Size = new Size(253, 46);
+            device_TH.State = false;
+            device_TH.TabIndex = 2;
+            device_TH.Text = "userDeviceUnitControl1";
+            device_TH.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_LQS
+            // 
+            device_LQS.BackColor = Color.Transparent;
+            device_LQS.CloseVariableName = "冷却室工位关";
+            device_LQS.EquipmentUnitName = "冷却室工位";
+            device_LQS.FillColor = Color.Transparent;
+            device_LQS.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_LQS.Location = new Point(278, 126);
+            device_LQS.MinimumSize = new Size(1, 1);
+            device_LQS.Name = "device_LQS";
+            device_LQS.OpenVariableName = "冷却室工位开";
+            device_LQS.RectColor = Color.Transparent;
+            device_LQS.Size = new Size(265, 46);
+            device_LQS.State = false;
+            device_LQS.TabIndex = 3;
+            device_LQS.Text = "userDeviceUnitControl1";
+            device_LQS.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_SFL
+            // 
+            device_SFL.BackColor = Color.Transparent;
+            device_SFL.CloseVariableName = "水分炉工位关";
+            device_SFL.EquipmentUnitName = "水分炉工位";
+            device_SFL.FillColor = Color.Transparent;
+            device_SFL.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_SFL.Location = new Point(278, 53);
+            device_SFL.MinimumSize = new Size(1, 1);
+            device_SFL.Name = "device_SFL";
+            device_SFL.OpenVariableName = "水分炉工位开";
+            device_SFL.RectColor = Color.Transparent;
+            device_SFL.Size = new Size(265, 46);
+            device_SFL.State = false;
+            device_SFL.TabIndex = 2;
+            device_SFL.Text = "userDeviceUnitControl1";
+            device_SFL.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // device_TZ
+            // 
+            device_TZ.BackColor = Color.Transparent;
+            device_TZ.CloseVariableName = "脱脂工位关";
+            device_TZ.EquipmentUnitName = "脱脂工位";
+            device_TZ.FillColor = Color.Transparent;
+            device_TZ.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            device_TZ.Location = new Point(19, 53);
+            device_TZ.MinimumSize = new Size(1, 1);
+            device_TZ.Name = "device_TZ";
+            device_TZ.OpenVariableName = "脱脂工位开";
+            device_TZ.RectColor = Color.Transparent;
+            device_TZ.Size = new Size(253, 46);
+            device_TZ.State = false;
+            device_TZ.TabIndex = 0;
+            device_TZ.Text = "userDeviceUnitControl1";
+            device_TZ.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // uiTitlePanel3
+            // 
+            uiTitlePanel3.Controls.Add(txt_Log);
+            uiTitlePanel3.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            uiTitlePanel3.Location = new Point(575, 199);
+            uiTitlePanel3.Margin = new Padding(4, 5, 4, 5);
+            uiTitlePanel3.MinimumSize = new Size(1, 1);
+            uiTitlePanel3.Name = "uiTitlePanel3";
+            uiTitlePanel3.ShowText = false;
+            uiTitlePanel3.Size = new Size(496, 341);
+            uiTitlePanel3.TabIndex = 2;
+            uiTitlePanel3.Text = "日志栏";
+            uiTitlePanel3.TextAlignment = ContentAlignment.MiddleCenter;
+            // 
+            // txt_Log
+            // 
+            txt_Log.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            txt_Log.Location = new Point(4, 40);
+            txt_Log.Margin = new Padding(4, 5, 4, 5);
+            txt_Log.MinimumSize = new Size(1, 16);
+            txt_Log.Multiline = true;
+            txt_Log.Name = "txt_Log";
+            txt_Log.Padding = new Padding(5);
+            txt_Log.ShowText = false;
+            txt_Log.Size = new Size(488, 294);
+            txt_Log.TabIndex = 0;
+            txt_Log.TextAlignment = ContentAlignment.MiddleLeft;
+            txt_Log.Watermark = "";
+            // 
             // PageTotalEquipmentControl
             // 
-            AutoScaleDimensions = new SizeF(9F, 20F);
-            AutoScaleMode = AutoScaleMode.Font;
-            ClientSize = new Size(1067, 497);
+            AutoScaleMode = AutoScaleMode.None;
+            ClientSize = new Size(1067, 544);
+            Controls.Add(uiTitlePanel3);
+            Controls.Add(uiTitlePanel2);
+            Controls.Add(uiTitlePanel1);
             Name = "PageTotalEquipmentControl";
             Text = "PageTotalEquipmentControl";
+            uiTitlePanel1.ResumeLayout(false);
+            uiTitlePanel2.ResumeLayout(false);
+            uiTitlePanel3.ResumeLayout(false);
             ResumeLayout(false);
         }
 
         #endregion
+
+        private Sunny.UI.UITitlePanel uiTitlePanel1;
+        private Sunny.UI.UISymbolButton btn_Start;
+        private Sunny.UI.UISymbolButton btn_DryRun;
+        private Sunny.UI.UISymbolButton btn_AlarmReset;
+        private Sunny.UI.UISymbolButton btn_MachineReset;
+        private Sunny.UI.UISymbolButton btn_Stop;
+        private Sunny.UI.UITitlePanel uiTitlePanel2;
+        private UserDeviceUnitControl device_TZ;
+        private UserDeviceUnitControl device_GHL;
+        private UserDeviceUnitControl device_SSJ;
+        private UserDeviceUnitControl device_JX;
+        private UserDeviceUnitControl device_TH;
+        private UserDeviceUnitControl device_LQS;
+        private UserDeviceUnitControl device_SFL;
+        private UserDeviceUnitControl device_CX;
+        private Sunny.UI.UITitlePanel uiTitlePanel3;
+        private Sunny.UI.UITextBox txt_Log;
     }
 }

+ 1 - 0
Scada/Page/PageTotalEquipmentControl.cs

@@ -17,5 +17,6 @@ namespace Scada.Page
         {
             InitializeComponent();
         }
+
     }
 }

+ 14 - 0
Scada/UIExtension.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Sunny.UI;
+
+namespace Scada
+{
+    public static class UIExtension
+    {
+        public static Action<UIStyleManager>? SetStyleManager;
+    }
+}

+ 98 - 0
Scada/UserControls/UserAlarmState.Designer.cs

@@ -0,0 +1,98 @@
+namespace Scada
+{
+    partial class UserAlarmState
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel();
+            lbl_StateName = new Sunny.UI.UILabel();
+            lbl_AlarmName = new Sunny.UI.UISymbolLabel();
+            uiTableLayoutPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // uiTableLayoutPanel1
+            // 
+            uiTableLayoutPanel1.ColumnCount = 2;
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 60F));
+            uiTableLayoutPanel1.Controls.Add(lbl_StateName, 0, 0);
+            uiTableLayoutPanel1.Controls.Add(lbl_AlarmName, 1, 0);
+            uiTableLayoutPanel1.Dock = DockStyle.Fill;
+            uiTableLayoutPanel1.Location = new Point(0, 0);
+            uiTableLayoutPanel1.Name = "uiTableLayoutPanel1";
+            uiTableLayoutPanel1.RowCount = 1;
+            uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.Size = new Size(250, 60);
+            uiTableLayoutPanel1.TabIndex = 0;
+            uiTableLayoutPanel1.TagString = null;
+            // 
+            // lbl_StateName
+            // 
+            lbl_StateName.BackColor = Color.Transparent;
+            lbl_StateName.Dock = DockStyle.Fill;
+            lbl_StateName.Font = new Font("微软雅黑", 15F);
+            lbl_StateName.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_StateName.Location = new Point(3, 0);
+            lbl_StateName.Name = "lbl_StateName";
+            lbl_StateName.Size = new Size(184, 60);
+            lbl_StateName.TabIndex = 0;
+            lbl_StateName.Text = "报警名称";
+            lbl_StateName.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // lbl_AlarmName
+            // 
+            lbl_AlarmName.Dock = DockStyle.Fill;
+            lbl_AlarmName.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            lbl_AlarmName.Location = new Point(193, 3);
+            lbl_AlarmName.MinimumSize = new Size(1, 1);
+            lbl_AlarmName.Name = "lbl_AlarmName";
+            lbl_AlarmName.Size = new Size(54, 54);
+            lbl_AlarmName.Style = Sunny.UI.UIStyle.Custom;
+            lbl_AlarmName.Symbol = 61683;
+            lbl_AlarmName.SymbolColor = Color.Red;
+            lbl_AlarmName.SymbolSize = 54;
+            lbl_AlarmName.TabIndex = 1;
+            // 
+            // UserAlarmState
+            // 
+            AutoScaleMode = AutoScaleMode.None;
+            Controls.Add(uiTableLayoutPanel1);
+            FillColor = Color.Transparent;
+            Name = "UserAlarmState";
+            RectColor = Color.Transparent;
+            Size = new Size(250, 60);
+            uiTableLayoutPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1;
+        private Sunny.UI.UILabel lbl_StateName;
+        private Sunny.UI.UISymbolLabel lbl_AlarmName;
+    }
+}

+ 70 - 0
Scada/UserControls/UserAlarmState.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Sunny.UI;
+
+namespace Scada
+{
+    public partial class UserAlarmState : UIUserControl
+    {
+        public UserAlarmState()
+        {
+            InitializeComponent();
+        }
+
+        private string deviceAlarmName = "报警名称";
+
+        [Description("设置或获取设备报警名称")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string DeviceName
+        {
+            get { return deviceAlarmName; }
+            set
+            {
+                deviceAlarmName = value;
+                this.lbl_AlarmName.Text = value;
+            }
+        }
+
+        // 设备状态属性
+        private bool state = true;
+
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("设置或获取设备报警的状态")]
+        public bool State
+        {
+            get { return state; }
+            set
+            {
+                state = value;
+                if (state)
+                {
+                    this.lbl_AlarmName.SymbolColor = Color.Red;
+                }
+                else
+                {
+                    this.lbl_AlarmName.SymbolColor = Color.LimeGreen;
+                }
+            }
+        }
+
+
+        private string variableName = "";
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("获取变量名称")]
+        public string VariableName
+        {
+            get { return variableName; }
+            set { variableName = value; }
+        }
+    }
+}

+ 120 - 0
Scada/UserControls/UserAlarmState.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 66 - 0
Scada/UserControls/UserCounterButton.Designer.cs

@@ -0,0 +1,66 @@
+namespace Scada
+{
+    partial class UserCounterButton
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            btn_Counter = new Sunny.UI.UISymbolButton();
+            SuspendLayout();
+            // 
+            // btn_Counter
+            // 
+            btn_Counter.Dock = DockStyle.Fill;
+            btn_Counter.Font = new Font("微软雅黑", 21.75F);
+            btn_Counter.Location = new Point(0, 0);
+            btn_Counter.MinimumSize = new Size(1, 1);
+            btn_Counter.Name = "btn_Counter";
+            btn_Counter.Radius = 50;
+            btn_Counter.Size = new Size(190, 90);
+            btn_Counter.Symbol = 558653;
+            btn_Counter.SymbolSize = 55;
+            btn_Counter.TabIndex = 0;
+            btn_Counter.Text = "空运行";
+            btn_Counter.TipsFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btn_Counter.Click += btn_Counter_Click;
+            // 
+            // UserCounterButton
+            // 
+            AutoScaleMode = AutoScaleMode.None;
+            BackColor = Color.Transparent;
+            Controls.Add(btn_Counter);
+            FillColor = Color.Transparent;
+            Name = "UserCounterButton";
+            RectColor = Color.Transparent;
+            Size = new Size(190, 90);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Sunny.UI.UISymbolButton btn_Counter;
+    }
+}

+ 111 - 0
Scada/UserControls/UserCounterButton.cs

@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Sunny.UI;
+
+namespace Scada
+{
+    public partial class UserCounterButton : UIUserControl
+    {
+        private UIStyle Style;
+        private Color defaultFillColor;
+        private Color defaultRectColor;
+        public UserCounterButton()
+        {
+            InitializeComponent();
+            this.Load += UserCounterButton_Load;
+        }
+
+        private void UserCounterButton_Load(object? sender, EventArgs e)
+        {
+            UIExtension.SetStyleManager = SetStyle;
+        }
+
+        private void SetStyle(UIStyleManager manager)
+        {
+            this.btn_Counter.Style = manager.Style;
+            Style = manager.Style;
+
+            defaultFillColor = this.btn_Counter.FillColor;
+            defaultRectColor = this.btn_Counter.RectColor;
+        }
+
+        private string buttonName;
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("按钮名称")]
+        public string ButtonName
+        {
+            get { return buttonName; }
+            set { this.btn_Counter.Text = value; }
+        }
+
+        private int counterButtonSymbol = 61452;
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("图标")]
+        public int CounterButtonSymbol
+        {
+            get { return counterButtonSymbol; }
+            set { this.btn_Counter.Symbol = counterButtonSymbol; }
+        }
+
+        private bool counterButtonState;
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("按钮的状态")]
+        public bool CounterButtonState
+        {
+            get { return counterButtonState; }
+            set
+            {
+                counterButtonState = value;
+
+                if (counterButtonState = value)
+                {
+                    this.btn_Counter.FillColor = this.btn_Counter.FillPressColor;
+                    this.btn_Counter.RectColor = this.btn_Counter.RectPressColor;
+                }
+                else
+                {
+                    if (this.btn_Counter.Style != Style)
+                    {
+                        this.btn_Counter.Style = Style;
+                    }
+                    else
+                    {
+                        this.btn_Counter.FillColor = defaultFillColor;
+                        this.btn_Counter.RectColor = defaultRectColor;
+                    }
+
+                }
+            }
+
+        }
+
+        private string variableName = "";
+
+      
+
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("获取变量名称")]
+        public string VariableName
+        {
+            get { return variableName; }
+            set { variableName = value; }
+        }
+
+        public event EventHandler? CounterButtonClick;
+        private void btn_Counter_Click(object sender, EventArgs e)
+        {
+            CounterButtonClick?.Invoke(this, e);
+        }
+    }
+}

+ 120 - 0
Scada/UserControls/UserCounterButton.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 98 - 0
Scada/UserControls/UserDeviceState.Designer.cs

@@ -0,0 +1,98 @@
+namespace Scada
+{
+    partial class UserDeviceState
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel();
+            lbl_StateName = new Sunny.UI.UILabel();
+            light_State = new Sunny.UI.UILight();
+            uiTableLayoutPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // uiTableLayoutPanel1
+            // 
+            uiTableLayoutPanel1.ColumnCount = 2;
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 60F));
+            uiTableLayoutPanel1.Controls.Add(lbl_StateName, 0, 0);
+            uiTableLayoutPanel1.Controls.Add(light_State, 1, 0);
+            uiTableLayoutPanel1.Dock = DockStyle.Fill;
+            uiTableLayoutPanel1.Location = new Point(0, 0);
+            uiTableLayoutPanel1.Name = "uiTableLayoutPanel1";
+            uiTableLayoutPanel1.RowCount = 1;
+            uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.Size = new Size(250, 60);
+            uiTableLayoutPanel1.TabIndex = 0;
+            uiTableLayoutPanel1.TagString = null;
+            // 
+            // lbl_StateName
+            // 
+            lbl_StateName.BackColor = Color.Transparent;
+            lbl_StateName.Dock = DockStyle.Fill;
+            lbl_StateName.Font = new Font("微软雅黑", 15F);
+            lbl_StateName.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_StateName.Location = new Point(3, 0);
+            lbl_StateName.Name = "lbl_StateName";
+            lbl_StateName.Size = new Size(184, 60);
+            lbl_StateName.TabIndex = 0;
+            lbl_StateName.Text = "状态名称";
+            lbl_StateName.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // light_State
+            // 
+            light_State.Dock = DockStyle.Fill;
+            light_State.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            light_State.Location = new Point(193, 3);
+            light_State.MinimumSize = new Size(1, 1);
+            light_State.Name = "light_State";
+            light_State.OffColor = Color.Red;
+            light_State.Radius = 54;
+            light_State.Size = new Size(54, 54);
+            light_State.TabIndex = 1;
+            light_State.Text = "uiLight1";
+            // 
+            // UserDeviceState
+            // 
+            AutoScaleMode = AutoScaleMode.None;
+            BackColor = SystemColors.Control;
+            Controls.Add(uiTableLayoutPanel1);
+            FillColor = Color.Transparent;
+            Name = "UserDeviceState";
+            RectColor = Color.Transparent;
+            Size = new Size(250, 60);
+            uiTableLayoutPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1;
+        private Sunny.UI.UILabel lbl_StateName;
+        private Sunny.UI.UILight light_State;
+    }
+}

+ 70 - 0
Scada/UserControls/UserDeviceState.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Sunny.UI;
+
+namespace Scada
+{
+    public partial class UserDeviceState : UIUserControl
+    {
+        public UserDeviceState()
+        {
+            InitializeComponent();
+        }
+
+        private string deviceRunName = "状态名称";
+
+        [Description("设置或获取设备运行状态名称")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string DeviceRunName
+        {
+            get { return deviceRunName; }
+            set
+            {
+                deviceRunName = value;
+                this.lbl_StateName.Text = value;
+            }
+        }
+
+        // 设备状态属性
+        private bool state = false;
+
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("设置或获取设备运行状态")]
+        public bool State
+        {
+            get { return state; }
+            set
+            {
+                state = value;
+                if (state)
+                {
+                    this.light_State.State = UILightState.On;
+                }
+                else
+                {
+                    this.light_State.State = UILightState.Off;
+                }
+            }
+        }
+
+
+        private string variableName = "";
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("获取变量名称")]
+        public string VariableName
+        {
+            get { return variableName; }
+            set { variableName = value; }
+        }
+    }
+}

+ 120 - 0
Scada/UserControls/UserDeviceState.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 95 - 0
Scada/UserControls/UserDeviceUnitControl.Designer.cs

@@ -0,0 +1,95 @@
+namespace Scada
+{
+    partial class UserDeviceUnitControl
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel();
+            lbl_DeviceName = new Sunny.UI.UILabel();
+            sw_Device = new Sunny.UI.UISwitch();
+            uiTableLayoutPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // uiTableLayoutPanel1
+            // 
+            uiTableLayoutPanel1.ColumnCount = 2;
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
+            uiTableLayoutPanel1.Controls.Add(lbl_DeviceName, 0, 0);
+            uiTableLayoutPanel1.Controls.Add(sw_Device, 1, 0);
+            uiTableLayoutPanel1.Dock = DockStyle.Fill;
+            uiTableLayoutPanel1.Location = new Point(0, 0);
+            uiTableLayoutPanel1.Name = "uiTableLayoutPanel1";
+            uiTableLayoutPanel1.RowCount = 1;
+            uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.Size = new Size(250, 60);
+            uiTableLayoutPanel1.TabIndex = 0;
+            uiTableLayoutPanel1.TagString = null;
+            // 
+            // lbl_DeviceName
+            // 
+            lbl_DeviceName.Dock = DockStyle.Fill;
+            lbl_DeviceName.Font = new Font("微软雅黑", 15F);
+            lbl_DeviceName.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_DeviceName.Location = new Point(3, 0);
+            lbl_DeviceName.Name = "lbl_DeviceName";
+            lbl_DeviceName.Size = new Size(124, 60);
+            lbl_DeviceName.TabIndex = 0;
+            lbl_DeviceName.Text = "工位名称";
+            lbl_DeviceName.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // sw_Device
+            // 
+            sw_Device.Dock = DockStyle.Fill;
+            sw_Device.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            sw_Device.Location = new Point(133, 3);
+            sw_Device.MinimumSize = new Size(1, 1);
+            sw_Device.Name = "sw_Device";
+            sw_Device.Size = new Size(114, 54);
+            sw_Device.TabIndex = 1;
+            sw_Device.Click += sw_Device_Click;
+            // 
+            // UserDeviceUnitControl
+            // 
+            AutoScaleMode = AutoScaleMode.None;
+            BackColor = Color.Transparent;
+            Controls.Add(uiTableLayoutPanel1);
+            FillColor = Color.Transparent;
+            Name = "UserDeviceUnitControl";
+            RectColor = Color.Transparent;
+            Size = new Size(250, 60);
+            uiTableLayoutPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1;
+        private Sunny.UI.UILabel lbl_DeviceName;
+        private Sunny.UI.UISwitch sw_Device;
+    }
+}

+ 85 - 0
Scada/UserControls/UserDeviceUnitControl.cs

@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Sunny.UI;
+
+namespace Scada
+{
+    public partial class UserDeviceUnitControl : UIUserControl
+    {
+        public UserDeviceUnitControl()
+        {
+            InitializeComponent();
+        }
+
+        private string equipmentUnitName = "设备单元";
+        [Browsable(true)]//使属性可以暴露出来,显示到窗口中
+        [Category("自定义属性")]//自定义属性
+        [Description("设备单元的名称")]
+        public string EquipmentUnitName
+        {
+            get { return equipmentUnitName; }
+            set
+            {
+                equipmentUnitName = value;
+                this.lbl_DeviceName.Text = equipmentUnitName;
+            }
+        }
+
+        private bool state;
+        [Browsable(true)]//使属性可以暴露出来,显示到窗口中
+        [Category("自定义属性")]//自定义属性
+        [Description("设备状态")]
+        public bool State
+        {
+            get
+            {
+                state = this.sw_Device.Active;
+                return state;
+            }
+            set
+            {
+                state = value;
+                this.sw_Device.Active = state;
+            }
+        }
+
+        private string openVariableName = "";
+        [Browsable(true)]//使属性可以暴露出来,显示到窗口中
+        [Category("自定义属性")]//自定义属性
+        [Description("获取变量名称")]
+        public string OpenVariableName
+        {
+            get { return openVariableName; }
+            set { openVariableName = value; }
+        }
+
+
+
+        private string closeVariableName = "";
+        [Browsable(true)]//使属性可以暴露出来,显示到窗口中
+        [Category("自定义属性")]//自定义属性
+        [Description("获取变量名称")]
+        public string CloseVariableName
+        {
+            get { return closeVariableName; }
+            set { closeVariableName = value; }
+        }
+
+        [Browsable(true)]
+        [Category("自定义事件")]
+        [Description("点击事件")]
+        public event EventHandler ClickEvent;
+        private void sw_Device_Click(object sender, EventArgs e)
+        {
+            ClickEvent?.Invoke(this, e);
+        }
+
+    }
+}

+ 120 - 0
Scada/UserControls/UserDeviceUnitControl.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 115 - 0
Scada/UserControls/UserSetValue.Designer.cs

@@ -0,0 +1,115 @@
+namespace Scada
+{
+    partial class UserSetValue
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel();
+            lbl_Name = new Sunny.UI.UILabel();
+            txt_Value = new Sunny.UI.UITextBox();
+            lbl_Unit = new Sunny.UI.UILabel();
+            uiTableLayoutPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // uiTableLayoutPanel1
+            // 
+            uiTableLayoutPanel1.ColumnCount = 3;
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70F));
+            uiTableLayoutPanel1.Controls.Add(lbl_Name, 0, 0);
+            uiTableLayoutPanel1.Controls.Add(txt_Value, 1, 0);
+            uiTableLayoutPanel1.Controls.Add(lbl_Unit, 2, 0);
+            uiTableLayoutPanel1.Dock = DockStyle.Fill;
+            uiTableLayoutPanel1.Location = new Point(0, 0);
+            uiTableLayoutPanel1.Name = "uiTableLayoutPanel1";
+            uiTableLayoutPanel1.RowCount = 1;
+            uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.Size = new Size(337, 46);
+            uiTableLayoutPanel1.TabIndex = 0;
+            uiTableLayoutPanel1.TagString = null;
+            // 
+            // lbl_Name
+            // 
+            lbl_Name.Dock = DockStyle.Fill;
+            lbl_Name.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            lbl_Name.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_Name.Location = new Point(3, 0);
+            lbl_Name.Name = "lbl_Name";
+            lbl_Name.Size = new Size(161, 46);
+            lbl_Name.TabIndex = 0;
+            lbl_Name.Text = "参数名称";
+            lbl_Name.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // txt_Value
+            // 
+            txt_Value.Dock = DockStyle.Fill;
+            txt_Value.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            txt_Value.Location = new Point(171, 5);
+            txt_Value.Margin = new Padding(4, 5, 4, 5);
+            txt_Value.MinimumSize = new Size(1, 16);
+            txt_Value.Name = "txt_Value";
+            txt_Value.Padding = new Padding(5);
+            txt_Value.ShowText = false;
+            txt_Value.Size = new Size(92, 36);
+            txt_Value.TabIndex = 1;
+            txt_Value.TextAlignment = ContentAlignment.MiddleCenter;
+            txt_Value.Watermark = "";
+            txt_Value.TextChanged += txt_Value_TextChanged;
+            // 
+            // lbl_Unit
+            // 
+            lbl_Unit.Dock = DockStyle.Fill;
+            lbl_Unit.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            lbl_Unit.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_Unit.Location = new Point(270, 0);
+            lbl_Unit.Name = "lbl_Unit";
+            lbl_Unit.Size = new Size(64, 46);
+            lbl_Unit.TabIndex = 2;
+            lbl_Unit.Text = "单位";
+            lbl_Unit.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // UserSetValue
+            // 
+            AutoScaleMode = AutoScaleMode.None;
+            Controls.Add(uiTableLayoutPanel1);
+            FillColor = Color.Transparent;
+            Name = "UserSetValue";
+            RectColor = Color.Transparent;
+            Size = new Size(337, 46);
+            uiTableLayoutPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1;
+        private Sunny.UI.UILabel lbl_Name;
+        private Sunny.UI.UITextBox txt_Value;
+        private Sunny.UI.UILabel lbl_Unit;
+    }
+}

+ 94 - 0
Scada/UserControls/UserSetValue.cs

@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Sunny.UI;
+using static Sunny.UI.UITextBox;
+
+namespace Scada
+{
+    public partial class UserSetValue : UIUserControl
+    {
+        public UserSetValue()
+        {
+            InitializeComponent();
+        }
+
+        private string deviceVarName = "名称";
+
+        [Description("设备变量名称")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string DeviceVarName
+        {
+            get { return deviceVarName; }
+            set
+            {
+                deviceVarName = value;
+                this.lbl_Name.Text = deviceVarName;
+            }
+        }
+
+        private string varValue = "";
+        [Description("变量值")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string VarValue
+        {
+            get { return varValue; }
+            set
+            {
+                varValue = value;
+                this.txt_Value.Text = varValue;
+            }
+        }
+
+        private UIEditType dataType = UIEditType.Double;
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("数值类型")]
+        public UIEditType DataType
+        {
+            get { return dataType; }
+            set
+            {
+                dataType = value;
+                this.txt_Value.Type = dataType;
+            }
+        }
+
+        private string unit = "单位";
+        [Description("设置或获取单位")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string Unit
+        {
+            get { return unit; }
+            set
+            {
+                unit = value;
+                this.lbl_Unit.Text = unit;
+            }
+        }
+
+        private void txt_Value_TextChanged(object sender, EventArgs e)
+        {
+            VarValue = this.txt_Value.Text;
+        }
+        private string variableName = "";
+
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("获取变量名称")]
+        public string VariableName
+        {
+            get { return variableName; }
+            set { variableName = value; }
+        }
+    }
+}

+ 120 - 0
Scada/UserControls/UserSetValue.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 115 - 0
Scada/UserControls/UserVarCurrentValue.Designer.cs

@@ -0,0 +1,115 @@
+namespace Scada
+{
+    partial class UserVarCurrentValue
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel();
+            lbl_Name = new Sunny.UI.UILabel();
+            dl_Value = new Sunny.UI.UIDigitalLabel();
+            lbl_Unit = new Sunny.UI.UILabel();
+            uiTableLayoutPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // uiTableLayoutPanel1
+            // 
+            uiTableLayoutPanel1.ColumnCount = 3;
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 125F));
+            uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70F));
+            uiTableLayoutPanel1.Controls.Add(lbl_Name, 0, 0);
+            uiTableLayoutPanel1.Controls.Add(dl_Value, 1, 0);
+            uiTableLayoutPanel1.Controls.Add(lbl_Unit, 2, 0);
+            uiTableLayoutPanel1.Dock = DockStyle.Fill;
+            uiTableLayoutPanel1.Location = new Point(0, 0);
+            uiTableLayoutPanel1.Name = "uiTableLayoutPanel1";
+            uiTableLayoutPanel1.RowCount = 1;
+            uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
+            uiTableLayoutPanel1.Size = new Size(337, 60);
+            uiTableLayoutPanel1.TabIndex = 0;
+            uiTableLayoutPanel1.TagString = null;
+            // 
+            // lbl_Name
+            // 
+            lbl_Name.Dock = DockStyle.Fill;
+            lbl_Name.Font = new Font("微软雅黑", 15F);
+            lbl_Name.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_Name.Location = new Point(3, 0);
+            lbl_Name.Name = "lbl_Name";
+            lbl_Name.Size = new Size(136, 60);
+            lbl_Name.TabIndex = 0;
+            lbl_Name.Text = "名称";
+            lbl_Name.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // dl_Value
+            // 
+            dl_Value.BackColor = Color.Transparent;
+            dl_Value.DecimalPlaces = 1;
+            dl_Value.Dock = DockStyle.Fill;
+            dl_Value.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            dl_Value.ForeColor = Color.SkyBlue;
+            dl_Value.Location = new Point(145, 3);
+            dl_Value.MinimumSize = new Size(1, 1);
+            dl_Value.Name = "dl_Value";
+            dl_Value.Size = new Size(119, 54);
+            dl_Value.TabIndex = 1;
+            dl_Value.TextAlign = HorizontalAlignment.Center;
+            dl_Value.Value = 100.5D;
+            // 
+            // lbl_Unit
+            // 
+            lbl_Unit.Dock = DockStyle.Fill;
+            lbl_Unit.Font = new Font("微软雅黑", 15F);
+            lbl_Unit.ForeColor = Color.FromArgb(48, 48, 48);
+            lbl_Unit.Location = new Point(270, 0);
+            lbl_Unit.Name = "lbl_Unit";
+            lbl_Unit.Size = new Size(64, 60);
+            lbl_Unit.TabIndex = 2;
+            lbl_Unit.Text = "单位";
+            lbl_Unit.TextAlign = ContentAlignment.MiddleCenter;
+            // 
+            // UserVarCurrentValue
+            // 
+            AutoScaleMode = AutoScaleMode.None;
+            BackColor = Color.Transparent;
+            Controls.Add(uiTableLayoutPanel1);
+            FillColor = Color.Transparent;
+            Name = "UserVarCurrentValue";
+            RectColor = Color.Transparent;
+            Size = new Size(337, 60);
+            uiTableLayoutPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1;
+        private Sunny.UI.UILabel lbl_Name;
+        private Sunny.UI.UIDigitalLabel dl_Value;
+        private Sunny.UI.UILabel lbl_Unit;
+    }
+}

+ 78 - 0
Scada/UserControls/UserVarCurrentValue.cs

@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Sunny.UI;
+
+namespace Scada
+{
+    public partial class UserVarCurrentValue : UIUserControl
+    {
+        public UserVarCurrentValue()
+        {
+            InitializeComponent();
+        }
+
+        // 设置设备名称
+        private string deviceVarName = "名称";
+
+        [Description("设置或获取设备变量名称")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string DeviceVarName
+        {
+            get { return deviceVarName; }
+            set
+            {
+                deviceVarName = value;
+                this.lbl_Name.Text = value;
+            }
+        }
+
+        private float varValue;
+        [Description("设置或获取设备变量值")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public float VarValue
+        {
+            get { return varValue; }
+            set
+            {
+                varValue = value;
+                this.dl_Value.Value = varValue;
+            }
+        }
+
+
+        private string unit = "单位";
+        [Description("设置或获取单位")]
+        [Category("自定义属性")]
+        [Browsable(true)]
+        public string Unit
+        {
+            get { return unit; }
+            set
+            {
+                unit = value;
+                this.lbl_Unit.Text = unit;
+            }
+        }
+
+
+        private string variableName = "";
+        [Browsable(true)]
+        [Category("自定义属性")]
+        [Description("获取变量名称")]
+        public string VariableName
+        {
+            get { return variableName; }
+            set { variableName = value; }
+        }
+
+    }
+}

+ 120 - 0
Scada/UserControls/UserVarCurrentValue.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>