diff --git a/BeDesignerSCADA/Adorners/SelectionAdorner.cs b/BeDesignerSCADA/Adorners/SelectionAdorner.cs new file mode 100644 index 00000000..61139545 --- /dev/null +++ b/BeDesignerSCADA/Adorners/SelectionAdorner.cs @@ -0,0 +1,114 @@ +using BeDesignerSCADA.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; + +namespace BeDesignerSCADA.Adorners +{ + internal class SelectionAdorner : Adorner + { + public SelectionAdorner(UIElement adornedEIeent) : base(adornedEIeent) { } + + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + Rect adornerRect = new Rect(AdornedElement.DesiredSize); + SolidColorBrush renderBrush = Brushes.Transparent; + Pen render = new Pen(new SolidColorBrush(Colors.OrangeRed), 1); + render.DashStyle = new DashStyle(new List() { 4, 2 }, 2); + drawingContext.DrawRectangle(renderBrush, render, new Rect(adornerRect.TopLeft.X, adornerRect.TopLeft.Y, adornerRect.Width, adornerRect.Height)); + + MouseDown += SelectionAdorner_MouseDown; + MouseMove += SelectionAdorner_MouseMove; + MouseUp += SelectionAdorner_MouseUp; + + ContextMenu = FindResource("AdornerRightMenu") as ContextMenu; + Tag = CanvasPanel.GetParentObject(AdornedElement); + + this.Focus(); + this.SelectionAdorner_MouseDown(this, null); + this.SelectionAdorner_MouseMove(this, null); + } + + private void SelectionAdorner_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + ReleaseMouseCapture(); + CanvasPanel.GetParentObject(AdornedElement).ClearAlignLine(); + } + + Point lastPoint = new Point(); + double tempX = 0d; + double tempY = 0d; + double movePx = 0d; + private void SelectionAdorner_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) + { + if (Mouse.LeftButton == MouseButtonState.Pressed) + { + if (lastPoint.X == 0 && lastPoint.Y == 0) + { + return; + } + + CaptureMouse(); + var nowPoint = Mouse.GetPosition(CanvasPanel.GetParentObject(AdornedElement)); + double offsetX = nowPoint.X - lastPoint.X; + double offsetY = nowPoint.Y - lastPoint.Y; + lastPoint = nowPoint; + + tempX += offsetX; + tempY += offsetY; + + var canvas = CanvasPanel.GetParentObject(AdornedElement); + movePx = canvas.GridPxiel; + + if (Math.Abs(tempX) >= movePx) + { + offsetX = Math.Round(tempX / movePx) * movePx; + tempX -= offsetX; + canvas.MoveControls(offsetX, 0); + } + + if (Math.Abs(tempY) >= movePx) + { + offsetY = Math.Round(tempY / movePx) * movePx; + tempY -= offsetY; + canvas.MoveControls(0, offsetY); + } + + } + else if (Mouse.MiddleButton == MouseButtonState.Pressed) + { + CaptureMouse(); + var nowPoint = Mouse.GetPosition(CanvasPanel.GetParentObject(AdornedElement)); + int offsetX = (int)(nowPoint.X - lastPoint.X); + int offsetY = (int)(nowPoint.Y - lastPoint.Y); + + CanvasPanel.GetParentObject(AdornedElement).ZoomControls(offsetX, offsetY); + lastPoint = nowPoint; + } + } + + private void SelectionAdorner_MouseDown(object sender, MouseButtonEventArgs e) + { + var canv = CanvasPanel.GetParentObject(AdornedElement); + lastPoint = Mouse.GetPosition(canv); + Keyboard.Focus(canv); + + //if (Keyboard.Modifiers == ModifierKeys.Control) + //{ + // if (canv.SelectedItems.Contains(AdornedElement)) + // { + // canv.SelectedItems.Remove(AdornedElement as FrameworkElement); + // canv.RefreshSelection(); + // } + //} + } + } +} diff --git a/BeDesignerSCADA/Adorners/SelectionAlignLine.cs b/BeDesignerSCADA/Adorners/SelectionAlignLine.cs new file mode 100644 index 00000000..38be84d8 --- /dev/null +++ b/BeDesignerSCADA/Adorners/SelectionAlignLine.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Documents; +using System.Windows.Media; + +namespace BeDesignerSCADA.Adorners +{ + public class SelectionAlignLine : Adorner + { + public SelectionAlignLine(UIElement adornedElement, Point start, Point end) : base(adornedElement) + { + startPoint = start; + endPoint = end; + } + + Point startPoint = default(Point); + Point endPoint = default(Point); + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + Rect adornerRect = new Rect(AdornedElement.DesiredSize); + Pen render = new Pen(new SolidColorBrush(Colors.RoyalBlue), 1); + render.DashCap = PenLineCap.Round; + render.DashStyle = new DashStyle(new List() { 4, 2 }, 2); + drawingContext.DrawLine(render, startPoint, endPoint); + } + } +} diff --git a/BeDesignerSCADA/App.xaml b/BeDesignerSCADA/App.xaml new file mode 100644 index 00000000..94ac0a53 --- /dev/null +++ b/BeDesignerSCADA/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/BeDesignerSCADA/App.xaml.cs b/BeDesignerSCADA/App.xaml.cs new file mode 100644 index 00000000..5da249eb --- /dev/null +++ b/BeDesignerSCADA/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace BeDesignerSCADA +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/BeDesignerSCADA/BeDesignerSCADA.csproj b/BeDesignerSCADA/BeDesignerSCADA.csproj new file mode 100644 index 00000000..5bf728ff --- /dev/null +++ b/BeDesignerSCADA/BeDesignerSCADA.csproj @@ -0,0 +1,112 @@ + + + + WinExe + net6.0-windows + enable + true + Images\fyf.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DLL\Antlr3.Runtime.dll + + + DLL\Unvell.ReoScript.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BeDesignerSCADA/BeDesignerSCADA.sln b/BeDesignerSCADA/BeDesignerSCADA.sln new file mode 100644 index 00000000..5f60da17 --- /dev/null +++ b/BeDesignerSCADA/BeDesignerSCADA.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32210.238 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BeDesignerSCADA", "BeDesignerSCADA.csproj", "{B8AB1764-33B1-49C7-9C20-EC8E1292BD67}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICOTest", "..\ICOTest\ICOTest.csproj", "{3E9DDFC3-7CB2-47D9-BC91-AAFDC8425595}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B8AB1764-33B1-49C7-9C20-EC8E1292BD67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8AB1764-33B1-49C7-9C20-EC8E1292BD67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8AB1764-33B1-49C7-9C20-EC8E1292BD67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8AB1764-33B1-49C7-9C20-EC8E1292BD67}.Release|Any CPU.Build.0 = Release|Any CPU + {3E9DDFC3-7CB2-47D9-BC91-AAFDC8425595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E9DDFC3-7CB2-47D9-BC91-AAFDC8425595}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E9DDFC3-7CB2-47D9-BC91-AAFDC8425595}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E9DDFC3-7CB2-47D9-BC91-AAFDC8425595}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {768373E6-CC1A-4B37-95FC-9934B59C3D02} + EndGlobalSection +EndGlobal diff --git a/BeDesignerSCADA/Common/PropertyHelper.cs b/BeDesignerSCADA/Common/PropertyHelper.cs new file mode 100644 index 00000000..8ac00c8e --- /dev/null +++ b/BeDesignerSCADA/Common/PropertyHelper.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace BeDesignerSCADA.Common +{ + /// + /// 编辑脚本时获取控件属性 + /// + public class PropertyHelper + { + public static string[] ableProperties = new string[] + { "IsChecked", "Value", "CurValue", "StatusValue", "NumberValue", "Text", + "Direction","RefreshData","ChangedText","Content" + }; + public static List GetCustomerControlProperty(List selectItems) + { + List result = new List(); + foreach (var control in selectItems) + { + var typeCtl = control.GetType(); + if (typeCtl.GetProperties().Count(p => ableProperties.Contains(p.Name)) == 0) + continue; + + var pare = new ControlName(control.Name, null); + result.Add(pare); + pare.Properties = typeCtl.GetProperties() + .Where(p => ableProperties.Contains(p.Name)) + .Select(x => new ControlName(x.Name, pare)).ToList(); + } + + return result; + } + } + + public class ControlName + { + public ControlName(string name, ControlName parent) + { + Name = name; + Parent = parent; + } + + public ControlName Parent { get; set; } + + public string Name { get; set; } + + public IEnumerable Properties { get; set; } + } +} diff --git a/BeDesignerSCADA/Controls/CanvasPanel.cs b/BeDesignerSCADA/Controls/CanvasPanel.cs new file mode 100644 index 00000000..581cebe9 --- /dev/null +++ b/BeDesignerSCADA/Controls/CanvasPanel.cs @@ -0,0 +1,902 @@ +using BeDesignerSCADA.Adorners; +using BeDesignerSCADA.Speical; +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using Microsoft.Toolkit.Mvvm.Input; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Media; +using System.Windows.Shapes; +using System.Xml; + +namespace BeDesignerSCADA.Controls +{ + public class CanvasPanel : Canvas + { + public CanvasPanel() + { + UseLayoutRounding = true; + Drop += CanvasPanel_Drop; + CopySelectItemsCommand = new RelayCommand(CopySelectItems); + PasteSelectItemsCommand = new RelayCommand(PasteSelectItems); + DeleteSelectItemsCommand = new RelayCommand(DeleteSelectItems); + SetTopLayerCommand = new RelayCommand(SetTopLayer); + SetBottomLayerCommand = new RelayCommand(SetBottomLayer); + SelectedItems = new ObservableCollection(); + //ResourceDictionary resourceDictionary = new ResourceDictionary(); + //Application.LoadComponent(resourceDictionary, new Uri("/BeDesignerSCADA;component/Themes/Styles.xaml", UriKind.Relative)); + //ContextMenu = resourceDictionary.FindName("CanvasRightMenu") as ContextMenu; + ContextMenu=Application.Current.Resources["CanvasRightMenu"] as ContextMenu; + KeyDown += CanvasPanel_KeyDown; + } + + #region 添加控件 + private void CanvasPanel_Drop(object sender, DragEventArgs e) + { + Type type = e.Data.GetData("System.RuntimeType") as Type; + var t = type.GetCustomAttributes(typeof(ControlTypeAttribute), false); + if (t.Length > 0) + { + Console.WriteLine((t as ControlTypeAttribute[])[0].Group); + } + + try + { + var control = Activator.CreateInstance(type) as FrameworkElement; + control.Name = GetControlName(type); + Children.Add(control); + + var xPos = e.GetPosition(this).X; + var yPos = e.GetPosition(this).Y; + if (xPos % GridPxiel != 0) + xPos = (GridPxiel - xPos % GridPxiel) + xPos; + if (yPos % GridPxiel != 0) + yPos = (GridPxiel - yPos % GridPxiel) + yPos; + + SetLeft(control, xPos); + SetTop(control, yPos); + + SelectedItems = new ObservableCollection() { control }; + SelectedItem = control; + } + catch (Exception) + { + } + + } + + string GetControlName(Type ctrlType) + { + var children = Children.GetEnumerator(); + children.Reset(); + List names = new List(); + while (children.MoveNext()) + { + if (children.Current.GetType().Name == ctrlType.Name) + { + names.Add((children.Current as FrameworkElement).Name); + } + } + + var nameIndex = names.Count; + while (names.Contains($"{ctrlType.Name.ToLower().Replace("the", string.Empty)}{nameIndex}")) + { + nameIndex++; + } + + return $"{ctrlType.Name.ToLower().Replace("the", string.Empty)}{nameIndex}"; + } + #endregion + + #region 初始化 + protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) + { + if (visualAdded is Border || visualRemoved is Border) + { + return; + } + + if (visualAdded is FrameworkElement ctrl) + { + ctrl.PreviewMouseLeftButtonDown += Ctrl_MouseLeftButtonDown; + } + if (visualRemoved is FrameworkElement ctr) + { + ctr.PreviewMouseLeftButtonDown -= Ctrl_MouseLeftButtonDown; + } + + base.OnVisualChildrenChanged(visualAdded, visualRemoved); + } + #endregion + + #region 单击选中项处理 + /// + /// 单击了控件时:不调用框选的刷新方式 + /// + bool isClickedControl = false; + /// + /// 左键按下 + /// + /// + /// + private void Ctrl_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + if (sender is FrameworkElement ctl) + { + var cp = GetParentObject(ctl); + if (Keyboard.Modifiers == ModifierKeys.Control) + { + cp.SelectedItems.Add(ctl); + } + else + { + cp.SelectedItems = new ObservableCollection() { ctl }; + } + isClickedControl = true; + RefreshSelection(); + } + } + /// + /// 获取属性 + /// + /// + /// + /// + public static T GetParentObject(DependencyObject obj) where T : FrameworkElement + { + DependencyObject parent = VisualTreeHelper.GetParent(obj); + while (parent != null) + { + if (parent is T) + { + return (T)parent; + } + parent = VisualTreeHelper.GetParent(parent); + } + return null; + } + #endregion + + #region 右键菜单 + #endregion + + #region 绘制选择框 + Border selectionBorder = new Border() + { + Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#557F7F7F")), + BorderThickness = new Thickness(1), + BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF303030")), + }; + + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonDown(e); + selectionStart = e.GetPosition(this); + if (!this.Children.Contains(selectionBorder)) + { + this.Children.Add(selectionBorder); + this.CaptureMouse(); + } + + } + + Point selectionStart = default; + protected override void OnMouseMove(MouseEventArgs e) + { + if (isClickedControl) + { + return; + } + base.OnMouseMove(e); + if (e.LeftButton == MouseButtonState.Pressed) + { + var nowPoint = e.GetPosition(this); + + var offsetX = nowPoint.X - selectionStart.X; + var offsetY = nowPoint.Y - selectionStart.Y; + Clear(); + + selectionBorder.Width = Math.Abs(offsetX); + selectionBorder.Height = Math.Abs(offsetY); + // 分四种情况绘制 + if (offsetX >= 0 && offsetY >= 0)// 右下 + { + SetLeft(selectionBorder, selectionStart.X); + SetTop(selectionBorder, selectionStart.Y); + } + else if (offsetX > 0 && offsetY < 0)// 右上 + { + SetLeft(selectionBorder, selectionStart.X); + SetBottom(selectionBorder, ActualHeight - selectionStart.Y); + + } + else if (offsetX < 0 && offsetY > 0)// 左下 + { + SetRight(selectionBorder, ActualWidth - selectionStart.X); + SetTop(selectionBorder, selectionStart.Y); + } + else if (offsetX < 0 && offsetY < 0)// 左上 + { + SetRight(selectionBorder, ActualWidth - selectionStart.X); + SetBottom(selectionBorder, ActualHeight - selectionStart.Y); + } + + + } + } + + protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonUp(e); + if (double.IsNaN(GetLeft(selectionBorder))) + { + SetLeft(selectionBorder, ActualWidth - GetRight(selectionBorder) - selectionBorder.ActualWidth); + } + if (double.IsNaN(GetTop(selectionBorder))) + { + SetTop(selectionBorder, ActualHeight - GetBottom(selectionBorder) - selectionBorder.ActualHeight); + } + + FrameSelection(GetLeft(selectionBorder), GetTop(selectionBorder), selectionBorder.Width, selectionBorder.Height); + selectionBorder.Width = 0; + selectionBorder.Height = 0; + this.Children.Remove(selectionBorder); + this.ReleaseMouseCapture(); + } + + private void Clear() + { + SetLeft(selectionBorder, double.NaN); + SetRight(selectionBorder, double.NaN); + SetTop(selectionBorder, double.NaN); + SetBottom(selectionBorder, double.NaN); + } + + #endregion + + #region 选中属性 + public FrameworkElement SelectedItem + { + get { return (FrameworkElement)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(FrameworkElement), typeof(CanvasPanel), new PropertyMetadata(null, OnSelectedItemChanged)); + private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as CanvasPanel)?.RefreshSelection1(); + public void RefreshSelection1() + { + + } + #endregion + + #region 框选 + public ObservableCollection SelectedItems + { + get { return (ObservableCollection)GetValue(SelectedItemsProperty); } + set { SetValue(SelectedItemsProperty, value); } + } + public static readonly DependencyProperty SelectedItemsProperty = + DependencyProperty.Register("SelectedItems", typeof(ObservableCollection), typeof(CanvasPanel), new PropertyMetadata(null, OnSelectedItemsChanged)); + + private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as CanvasPanel)?.RefreshSelection(); + + public void RefreshSelection() + { + foreach (var item in Children) + { + if (!(item is IExecutable)) + continue; + + var ele = item as FrameworkElement; + if (ele == null) continue; + + var layer = AdornerLayer.GetAdornerLayer(ele); + var arr = layer.GetAdorners(ele);//获取该控件上所有装饰器,返回一个数组 + if (arr != null) + { + for (int i = arr.Length - 1; i >= 0; i--) + { + layer.Remove(arr[i]); + } + } + } + + if (SelectedItems != null) + { + foreach (var item in SelectedItems) + { + var layer = AdornerLayer.GetAdornerLayer(item); + layer.Add(new SelectionAdorner(item)); + SelectedItem = item; + } + } + } + + /// + /// 移除所有选择装饰器 + /// + public void ClearSelection() + { + foreach (var item in Children) + { + if (!(item is IExecutable)) + continue; + + var ele = item as FrameworkElement; + if (ele == null) continue; + + var layer = AdornerLayer.GetAdornerLayer(ele); + var arr = layer.GetAdorners(ele);//获取该控件上所有装饰器,返回一个数组 + if (arr != null) + { + for (int i = arr.Length - 1; i >= 0; i--) + { + layer.Remove(arr[i]); + } + } + } + } + + /// + /// 计算框选项 + /// + private void FrameSelection(double x, double y, double width, double height) + { + if (width > 0 || height > 0) + { + isClickedControl = false; + } + if (isClickedControl) + { + isClickedControl = false; + SelectedItems = new ObservableCollection(); + return; + } + SelectedItems = new ObservableCollection(); + foreach (var item in Children) + { + if (item is FrameworkElement ctrl && !(ctrl is Border)) + { + // 框左上角 + var left = GetLeft(ctrl); + var top = GetTop(ctrl); + if (left >= x && left <= x + width && top >= y && top <= y + height) + { + if (!SelectedItems.Contains(ctrl)) + SelectedItems.Add(ctrl); + } + + // 框右下角 + var right = left + ctrl.ActualWidth; + var bottom = top + ctrl.ActualHeight; + if (right >= x && right <= x + width && bottom >= y && bottom <= y + height) + { + if (!SelectedItems.Contains(ctrl)) + SelectedItems.Add(ctrl); + } + + // 框右上角 + if (right >= x && right <= x + width && top >= y && top <= y + height) + { + if (!SelectedItems.Contains(ctrl)) + SelectedItems.Add(ctrl); + } + + // 框左下角 + if (left >= x && left <= x + width && bottom >= y && bottom <= y + height) + { + if (!SelectedItems.Contains(ctrl)) + SelectedItems.Add(ctrl); + } + } + } + + RefreshSelection(); + } + #endregion + + #region 外部调用 + public List GetAllExecChildren() + { + List result = new List(); + foreach (var ctrl in Children) + { + if (ctrl is IExecutable exec) + { + result.Add(ctrl as FrameworkElement); + } + } + + return result; + } + + /// + /// 对齐像素单位 + /// + public int GridPxiel + { + get { return (int)GetValue(GridPxielProperty); } + set { SetValue(GridPxielProperty, value); } + } + public static readonly DependencyProperty GridPxielProperty = + DependencyProperty.Register("GridPxiel", typeof(int), typeof(CanvasPanel), new PropertyMetadata(4)); + + + public void MoveControls(double offsetX, double offsetY) + { + ClearAlignLine(); + + // 获取可对齐的点 + List points = new List(); + foreach (FrameworkElement ctrl in Children) + { + if (!SelectedItems.Contains(ctrl)) + { + // 左上的点 + Point item = new Point(GetLeft(ctrl), GetTop(ctrl)); + points.Add(item); + + // 左下的点 + Point itemlb = new Point(GetLeft(ctrl), GetTop(ctrl) + ctrl.ActualHeight); + points.Add(itemlb); + + // 右下的点 + Point itemrb = new Point(GetLeft(ctrl) + ctrl.ActualWidth, GetTop(ctrl) + ctrl.ActualHeight); + points.Add(itemrb); + + // 右上的点 + Point itemrt = new Point(GetLeft(ctrl) + ctrl.ActualWidth, GetTop(ctrl)); + points.Add(itemrt); + } + } + + // 控件移动 + foreach (var item in SelectedItems) + { + var moveX = GetLeft(item) + offsetX; + moveX = (moveX < 0) ? 0 : moveX; + + var moveY = GetTop(item) + offsetY; + moveY = moveY < 0 ? 0 : moveY; + + if (moveX % GridPxiel != 0) + moveX = (GridPxiel - moveX % GridPxiel) + moveX; + if (moveY % GridPxiel != 0) + moveY = (GridPxiel - moveY % GridPxiel) + moveY; + + SetLeft(item, moveX); + SetTop(item, moveY); + } + + // 计算是否显示对齐线 + var targetItemTop = SelectedItems?.Min(x => GetTop(x)); + var targetItem = SelectedItems.FirstOrDefault(x => GetTop(x) == targetItemTop); + var lefAlign = points.FirstOrDefault(x => Math.Abs(x.X - GetLeft(targetItem)) == 0); + if (lefAlign != default) + { + //SetLeft(targetItem, lefAlign.X); + var layer = AdornerLayer.GetAdornerLayer(this); + layer.Add(new SelectionAlignLine(this, lefAlign, new Point(GetLeft(targetItem), GetTop(targetItem)))); + } + + var topAlign = points.FirstOrDefault(x => Math.Abs(x.Y - GetTop(targetItem)) == 0); + if (topAlign != default) + { + //SetTop(targetItem, topAlign.Y); + var layer = AdornerLayer.GetAdornerLayer(this); + layer.Add(new SelectionAlignLine(this, topAlign, new Point(GetLeft(targetItem), GetTop(targetItem)))); + } + + int px = 20; + // 网格对齐 + if (UseAutoAlignment) + { + foreach (var item in SelectedItems) + { + var left = GetLeft(item); + if (left % px <= 1) + { + SetLeft(item, (int)left / px * px); + } + + var top = GetTop(item); + if (top % px <= 1) + { + SetTop(item, (int)top / px * px); + } + } + } + } + + /// + /// 清除绘制的对齐线 + /// + public void ClearAlignLine() + { + var arr = AdornerLayer.GetAdornerLayer(this).GetAdorners(this); + if (arr != null) + { + for (int i = arr.Length - 1; i >= 0; i--) + { + AdornerLayer.GetAdornerLayer(this).Remove(arr[i]); + } + } + } + + public void ZoomControls(int offsetX, int offsetY) + { + foreach (var item in SelectedItems) + { + if (item.ActualHeight + offsetY > 10) + { + item.Height += offsetY; + } + if (item.ActualWidth + offsetX > 10) + { + item.Width += offsetX; + } + } + } + #endregion + + #region 对齐操作 + /// + /// 是否使用网格对齐 10px + /// + public bool UseAutoAlignment + { + get { return (bool)GetValue(UseAutoAlignmentProperty); } + set { SetValue(UseAutoAlignmentProperty, value); } + } + public static readonly DependencyProperty UseAutoAlignmentProperty = + DependencyProperty.Register("UseAutoAlignment", typeof(bool), typeof(CanvasPanel), new PropertyMetadata(false)); + + + public void AlignLeft() + { + if (SelectedItems == null || SelectedItems.Count == 0) + return; + + var leftMin = SelectedItems.Min(x => Canvas.GetLeft(x)); + foreach (var item in SelectedItems) + { + SetLeft(item, leftMin); + } + } + + public void AlignRight() + { + if (SelectedItems == null || SelectedItems.Count == 0) + return; + + var rightMax = SelectedItems.Max(x => GetLeft(x) + x.ActualWidth); + foreach (var item in SelectedItems) + { + var targetLeft = rightMax - item.ActualWidth; + SetLeft(item, targetLeft); + } + } + + public void AlignCenter() + { + if (SelectedItems == null || SelectedItems.Count == 0) + return; + + var leftmin = SelectedItems.Min(x => GetLeft(x)); + var rightmax = SelectedItems.Max(x => GetLeft(x) + x.ActualWidth); + var center = (rightmax - leftmin) / 2 + leftmin; + + foreach (var item in SelectedItems) + { + var target = center - (item.ActualWidth / 2); + SetLeft(item, target); + } + } + + public void AlignTop() + { + if (SelectedItems == null || SelectedItems.Count == 0) + return; + + var topMin = SelectedItems.Min(x => GetTop(x)); + foreach (var item in SelectedItems) + { + SetTop(item, topMin); + } + } + + public void AlignBottom() + { + if (SelectedItems == null || SelectedItems.Count == 0) + return; + + var botMax = SelectedItems.Max(x => GetTop(x) + x.ActualHeight); + foreach (var item in SelectedItems) + { + var targetLeft = botMax - item.ActualHeight; + SetTop(item, targetLeft); + } + } + + public void VertialLayout() + { + if (SelectedItems == null || SelectedItems.Count < 3) + return; + + var topCtl = SelectedItems.Min(x => GetTop(x) + x.ActualHeight); + var botCtrl = SelectedItems.Max(x => GetTop(x)); + var emptyHeight = botCtrl - topCtl; + + var orderCtrl = SelectedItems.OrderBy(x => GetTop(x)).ToList(); + orderCtrl.RemoveAt(0); + orderCtrl.RemoveAt(orderCtrl.Count - 1); + var useSpace = orderCtrl.Sum(x => x.ActualHeight); + + var ableSpaceAvg = (emptyHeight - useSpace) / (SelectedItems.Count - 1); + double nowPostion = topCtl; + foreach (var item in orderCtrl) + { + SetTop(item, nowPostion + ableSpaceAvg); + nowPostion += item.ActualHeight + ableSpaceAvg; + } + } + + public void HorizontalLayout() + { + if (SelectedItems == null || SelectedItems.Count < 3) + return; + + var leftCtl = SelectedItems.Min(x => GetLeft(x) + x.ActualWidth); + var rightCtrl = SelectedItems.Max(x => GetLeft(x)); + var emptyHeight = rightCtrl - leftCtl; + + var orderCtrl = SelectedItems.OrderBy(x => GetLeft(x)).ToList(); + orderCtrl.RemoveAt(0); + orderCtrl.RemoveAt(orderCtrl.Count - 1); + var useSpace = orderCtrl.Sum(x => x.ActualWidth); + + var ableSpaceAvg = (emptyHeight - useSpace) / (SelectedItems.Count - 1); + double nowPostion = leftCtl; + foreach (var item in orderCtrl) + { + SetLeft(item, nowPostion + ableSpaceAvg); + nowPostion += item.ActualWidth + ableSpaceAvg; + } + } + #endregion + + #region 按键操作 + public RelayCommand CopySelectItemsCommand { get; set; } + public RelayCommand PasteSelectItemsCommand { get; set; } + public RelayCommand DeleteSelectItemsCommand { get; set; } + public RelayCommand SetTopLayerCommand { get; set; } + public RelayCommand SetBottomLayerCommand { get; set; } + + List copyTemp = new List(); + + private void CanvasPanel_KeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control) + { + CopySelectItems(); + } + else if (e.Key == Key.V && Keyboard.Modifiers == ModifierKeys.Control) + { + PasteSelectItems(); + } + else if (e.Key == Key.Delete) + { + DeleteSelectItems(); + } + else if (e.Key == Key.Up) + { + var offset = -1; + foreach (var item in SelectedItems) + { + SetTop(item, (GetTop(item) + offset) < 0 ? 0 : GetTop(item) + offset); + } + e.Handled = true; + } + else if (e.Key == Key.Down) + { + var offset = 1; + foreach (var item in SelectedItems) + { + SetTop(item, (GetTop(item) + offset) < 0 ? 0 : GetTop(item) + offset); + } + e.Handled = true; + } + else if (e.Key == Key.Left) + { + var offset = -1; + foreach (var item in SelectedItems) + { + SetLeft(item, (GetLeft(item) + offset) < 0 ? 0 : GetLeft(item) + offset); + } + e.Handled = true; + + } + else if (e.Key == Key.Right) + { + var offset = 1; + foreach (var item in SelectedItems) + { + SetLeft(item, (GetLeft(item) + offset) < 0 ? 0 : GetLeft(item) + offset); + } + e.Handled = true; + } + } + + /// + /// 复制 + /// + public void CopySelectItems() + { + copyTemp.Clear(); + foreach (var item in SelectedItems) + { + copyTemp.Add(item); + } + } + + /// + /// 粘贴 + /// + public void PasteSelectItems() + { + SelectedItems.Clear(); + foreach (var item in copyTemp) + { + var xml = XamlWriter.Save(item); + var element = XamlReader.Parse(xml) as FrameworkElement; + element.Name += "_1"; + + SetLeft(element, GetLeft(element) + 10); + SetTop(element, GetTop(element) + 10); + + Children.Add(element); + SelectedItems.Add(element); + } + + // 将复制的内容替换 以便处理连续复制 + copyTemp.Clear(); + foreach (var item in SelectedItems) + { + copyTemp.Add(item); + } + RefreshSelection(); + } + + /// + /// 置于顶层 + /// + public void SetTopLayer() + { + if (SelectedItems.Count == 0) + return; + + foreach (var item in SelectedItems) + { + Children.Remove(item); + } + + foreach (var item in SelectedItems) + { + Children.Add(item); + } + } + + /// + /// 置于底层 + /// + public void SetBottomLayer() + { + if (SelectedItems.Count == 0) + return; + + foreach (var item in SelectedItems) + { + Children.Remove(item); + } + + foreach (var item in SelectedItems) + { + Children.Insert(0, item); + } + } + /// + /// 删除 + /// + public void DeleteSelectItems() + { + foreach (var item in SelectedItems) + { + Children.Remove(item); + } + + SelectedItems.Clear(); + RefreshSelection(); + } + #endregion + + #region 运行Xaml 保存 读取 + public List Generator() + { + List elements = new List(); + foreach (var item in Children) + { + // 排除非自定义的控件们 + if (!(item is IExecutable)) + continue; + + var xml = XamlWriter.Save(item); + var ele = XamlReader.Parse(xml) as FrameworkElement; + elements.Add(ele); + } + + return elements; + } + + /// + /// 保存数据到文本 + /// + public string Save() + { + StringBuilder sb = new StringBuilder(); + + foreach (var item in Children) + { + + var xml = XamlWriter.Save(item); + sb.Append(xml + "\r\n"); + } + + return sb.ToString(); + } + + /// + /// 读取文件 + /// + public void Load(string path) + { + Children.Clear(); + FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Unicode)) + { + while (sr.Peek() > -1) + { + string str = sr.ReadLine(); + //if (!str.Contains("NewConveyorBelt")) + { + try + { + var ele = XamlReader.Parse(str) as FrameworkElement; + Children.Add(ele); + } + catch (Exception ex) + { + + } + + } + + } + } + + SelectedItems?.Clear(); + } + #endregion + } +} diff --git a/BeDesignerSCADA/Controls/RunCanvas.xaml b/BeDesignerSCADA/Controls/RunCanvas.xaml new file mode 100644 index 00000000..d07b6dda --- /dev/null +++ b/BeDesignerSCADA/Controls/RunCanvas.xaml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BeDesignerSCADA/Controls/RunCanvas.xaml.cs b/BeDesignerSCADA/Controls/RunCanvas.xaml.cs new file mode 100644 index 00000000..2b8aaa8e --- /dev/null +++ b/BeDesignerSCADA/Controls/RunCanvas.xaml.cs @@ -0,0 +1,133 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.Controls +{ + /// + /// RunCanvas.xaml 的交互逻辑 + /// + public partial class RunCanvas : UserControl + { + public RunCanvas() + { + InitializeComponent(); + Unloaded += (s, e) => Destory(); + } + + /// + /// Dispose子集 + /// + public void Destory() + { + foreach (var item in RootCanvas.Children) + { + if (item is IDisposable disposable) + { + disposable.Dispose(); + } + } + } + + public void Run(List canvas) + { + RootCanvas.Children.Clear(); + foreach (FrameworkElement element in canvas) + { + //if (element.GetType().GetInterface("IExecutable")!=null) + //{ + // element.GetType().GetProperty("IsExecuteState").SetValue(element, true); + //} + + if (element is IExecutable executable) + executable.IsExecuteState = true; + + RootCanvas.Children.Add(element); + RegisterJsName(element); + } + } + + // 注册名称到Js + static void RegisterJsName(FrameworkElement element) + { + Config.GetInstance().SetVariable(element.Name, element); + if (element is Panel panel) + { + foreach (var item in panel.Children) + { + RegisterJsName(item as FrameworkElement); + } + } + } + + #region 拖动与缩放 + private void RootCanvas_MouseMove(object sender, MouseEventArgs e) + { + if (DragEnable.IsChecked == false) + { + return; + } + + if (e.LeftButton == MouseButtonState.Pressed && isPressed) + { + Point point = e.GetPosition(this); + var movex = (point.X - last.X); + var movey = (point.Y - last.Y); + + Translate.X += movex; + Translate.Y += movey; + last = point; + + } + } + + bool isPressed = false; + Point last;//记录上次鼠标坐标位置 + private void RootCanvas_MouseLeftButtoDown(object sender, MouseButtonEventArgs e) + { + last = e.GetPosition(this); + isPressed = true; + } + + private void RootCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + isPressed = false; + } + + // 缩放 + private void RootCanvas_MouseWheel(object sender, MouseWheelEventArgs e) + { + if (ZoomEnable.IsChecked == false) + { + return; + } + var zoomS = (e.Delta / 960d); + var zoom = zoomS + Scale.ScaleX; + if (zoom > 3 || zoom < 0.8) + { + return; + } + Scale.ScaleX = Scale.ScaleY = zoom; + + Point mouse = e.GetPosition(RootCanvas); + Point newMouse = new Point(mouse.X * zoomS, mouse.Y * zoomS); + + Translate.X -= newMouse.X; + Translate.Y -= newMouse.Y; + } + #endregion + } +} diff --git a/BeDesignerSCADA/Converters/BoolToVisibilityConverter.cs b/BeDesignerSCADA/Converters/BoolToVisibilityConverter.cs new file mode 100644 index 00000000..a68e62a3 --- /dev/null +++ b/BeDesignerSCADA/Converters/BoolToVisibilityConverter.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace BeDesignerSCADA.Converters +{ + [ValueConversion(typeof(bool), typeof(Visibility))] + public class BoolToVisibilityConverter : IValueConverter + { + static BoolToVisibilityConverter() + { + Instance = new BoolToVisibilityConverter(); + } + + public static BoolToVisibilityConverter Instance + { + get; + private set; + } + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return ((bool)value) ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BeDesignerSCADA/Converters/HalfNumberConverter.cs b/BeDesignerSCADA/Converters/HalfNumberConverter.cs new file mode 100644 index 00000000..74cbc4d1 --- /dev/null +++ b/BeDesignerSCADA/Converters/HalfNumberConverter.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace BeDesignerSCADA.Converters +{ + public class HalfNumberConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (double.TryParse(value.ToString(), out double val)) + { + return val / 2; + } + + return 0; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + } +} diff --git a/BeDesignerSCADA/Converters/ZoomConverter.cs b/BeDesignerSCADA/Converters/ZoomConverter.cs new file mode 100644 index 00000000..cd1d41fd --- /dev/null +++ b/BeDesignerSCADA/Converters/ZoomConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace BeDesignerSCADA.Converters +{ + public class ZoomConverter : IValueConverter + { + public bool IsHeight { get; set; } + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (double.TryParse(value.ToString(), out double zoom)) + { + return IsHeight ? zoom * 1080 : zoom * 1920; + } + else + { + return IsHeight ? 1080 : 1920; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return value; + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/ArcGauge.cs b/BeDesignerSCADA/CustomerControls/ArcGauge.cs new file mode 100644 index 00000000..a1952dbc --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/ArcGauge.cs @@ -0,0 +1,198 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class ArcGauge : Control, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public ArcGauge() + { + Width = 300; + Height = 300; + SetCurrentValue(ValueProperty, 0d); + SetCurrentValue(MinValueProperty, 0d); + SetCurrentValue(MaxValueProperty, 100d); + } + + private void InitTick() + { + // 画大刻度 + for (int i = 0; i < 11; i++) + { + Line line = new Line(); + line.X1 = 0; + line.Y1 = 0; + line.X2 = 0; + line.Y2 = 12; + line.Stroke = Brushes.White; + line.StrokeThickness = 2; + line.HorizontalAlignment = HorizontalAlignment.Center; + line.RenderTransformOrigin = new Point(0.5, 0.5); + line.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 }; + bdGrid.Children.Add(line); + DrawText(); + } + + // 画小刻度 + for (int i = 0; i < 10; i++) + { + var start = -140 + 28 * i + 2.8; + for (int j = 0; j < 9; j++) + { + Line line = new Line(); + line.X1 = 0; + line.Y1 = 0; + line.X2 = 0; + line.Y2 = 6; + line.Stroke = Brushes.White; + line.StrokeThickness = 1; + line.HorizontalAlignment = HorizontalAlignment.Center; + line.RenderTransformOrigin = new Point(0.5, 0.5); + line.RenderTransform = new RotateTransform() { Angle = start + j * 2.8 }; + bdGrid.Children.Add(line); + } + } + } + + List textLabels = new List(); + private void DrawText() + { + foreach (var item in textLabels) + { + bdGrid.Children.Remove(item); + } + textLabels.Clear(); + + var per = MaxValue / 10; + for (int i = 0; i < 11; i++) + { + TextBlock textBlock = new TextBlock(); + textBlock.Text = $"{MinValue + (per * i)}"; + textBlock.HorizontalAlignment = HorizontalAlignment.Center; + textBlock.RenderTransformOrigin = new Point(0.5, 0.5); + textBlock.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 }; + textBlock.Margin = new Thickness(12); + textBlock.Foreground = Brushes.White; + bdGrid.Children.Add(textBlock); + textLabels.Add(textBlock); + } + } + + static ArcGauge() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ArcGauge), new FrameworkPropertyMetadata(typeof(ArcGauge))); + } + + RotateTransform rotateTransform; + Grid bdGrid; + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + rotateTransform = GetTemplateChild("PointRotate") as RotateTransform; + bdGrid = GetTemplateChild("bdGrid") as Grid; + Refresh(); + InitTick(); + } + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + [Category("值设定")] + public double Value + { + get { return (double)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + public static readonly DependencyProperty ValueProperty = + DependencyProperty.Register("Value", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); + + private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as ArcGauge)?.Refresh(); + + [Category("值设定")] + public double MinValue + { + get { return (double)GetValue(MinValueProperty); } + set { SetValue(MinValueProperty, value); } + } + public static readonly DependencyProperty MinValueProperty = + DependencyProperty.Register("MinValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); + + [Category("值设定")] + public double MaxValue + { + get { return (double)GetValue(MaxValueProperty); } + set { SetValue(MaxValueProperty, value); } + } + + public string ControlType => "控件"; + + public static readonly DependencyProperty MaxValueProperty = + DependencyProperty.Register("MaxValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); + + + private void Refresh() + { + if (rotateTransform == null) + return; + DrawText(); + DoubleAnimation da = new DoubleAnimation(); + da.Duration = new Duration(TimeSpan.FromMilliseconds(350)); + da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; + + if (Value > MaxValue) + { + rotateTransform.Angle = 140; + da.To = 140; + } + else if (Value < MinValue) + { + rotateTransform.Angle = -140; + da.To = -140; + } + else + { + var range = MaxValue - MinValue; + var process = Value / range; + var tAngle = process * 280 - 140; + rotateTransform.Angle = tAngle; + da.To = tAngle; + } + + rotateTransform.BeginAnimation(RotateTransform.AngleProperty, da); + } + + public void Register() + { + Refresh(); + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/DigitalNumber.cs b/BeDesignerSCADA/CustomerControls/DigitalNumber.cs new file mode 100644 index 00000000..5ad81677 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/DigitalNumber.cs @@ -0,0 +1,62 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace BeDesignerSCADA.CustomerControls +{ + public class DigitalNumber : Control, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public DigitalNumber() + { + Width = 80; + Height = 30; + } + public string ControlType => "控件"; + + static DigitalNumber() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(DigitalNumber), new FrameworkPropertyMetadata(typeof(DigitalNumber))); + } + + TextBlock text = null; + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + text = GetTemplateChild("line") as TextBlock; + } + + public double NumberValue + { + get { return (double)GetValue(NumberValueProperty); } + set { SetValue(NumberValueProperty, value); } + } + public static readonly DependencyProperty NumberValueProperty = + DependencyProperty.Register("NumberValue", typeof(double), typeof(DigitalNumber), new UIPropertyMetadata(0.00d)); + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/GraphArrow.xaml b/BeDesignerSCADA/CustomerControls/GraphArrow.xaml new file mode 100644 index 00000000..77844afc --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/GraphArrow.xaml @@ -0,0 +1,14 @@ + + + + + diff --git a/BeDesignerSCADA/CustomerControls/GraphArrow.xaml.cs b/BeDesignerSCADA/CustomerControls/GraphArrow.xaml.cs new file mode 100644 index 00000000..3a2879e7 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/GraphArrow.xaml.cs @@ -0,0 +1,56 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// GraphArrow.xaml 的交互逻辑 + /// + public partial class GraphArrow : UserControl, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public GraphArrow() + { + InitializeComponent(); + Width = 80; + Height = 80; + } + + public string ControlType => "图形"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + IsEnabled = true; + Register(); + Style = null; + } + } + } + + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/GraphStar.xaml b/BeDesignerSCADA/CustomerControls/GraphStar.xaml new file mode 100644 index 00000000..9f1bdbbf --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/GraphStar.xaml @@ -0,0 +1,14 @@ + + + + + diff --git a/BeDesignerSCADA/CustomerControls/GraphStar.xaml.cs b/BeDesignerSCADA/CustomerControls/GraphStar.xaml.cs new file mode 100644 index 00000000..f8de6b8e --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/GraphStar.xaml.cs @@ -0,0 +1,56 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// GraphStar.xaml 的交互逻辑 + /// + public partial class GraphStar : UserControl, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public GraphStar() + { + InitializeComponent(); + Width = 100; + Height = 100; + } + + public string ControlType => "图形"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + IsEnabled = true; + Register(); + Style = null; + } + } + } + + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/KnobButton.cs b/BeDesignerSCADA/CustomerControls/KnobButton.cs new file mode 100644 index 00000000..2f639d7c --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/KnobButton.cs @@ -0,0 +1,240 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class KnobButton : Slider, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + static KnobButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(KnobButton), new FrameworkPropertyMetadata(typeof(KnobButton))); + } + + public KnobButton() + { + SetCurrentValue(WidthProperty, 150d); + SetCurrentValue(HeightProperty, 150d); + SetCurrentValue(MaximumProperty, 100d); + MouseDown += Path_MouseDown; + MouseMove += Path_MouseMove; + MouseWheel += Path_MouseWheel; + MouseLeftButtonUp += KnobButton_MouseLeftButtonUp; + Update(); + } + + #region 设计需要 + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + Register(); + } + } + + /// + /// 注册需要处理的事件 + /// + public void Register() + { + ValueChanged += KnobButton_ValueChanged; ; + } + + private void KnobButton_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { + Config.GetInstance().RunJsScipt(ValueChangedExecute); + } + #endregion + + #region 绘制 + private void InitTick() + { + // 画大刻度 + for (int i = 0; i < 11; i++) + { + Line line = new Line(); + line.X1 = 0; + line.Y1 = 0; + line.X2 = 0; + line.Y2 = 12; + line.Stroke = Brushes.Gray; + line.StrokeThickness = 2; + line.HorizontalAlignment = HorizontalAlignment.Center; + line.RenderTransformOrigin = new Point(0.5, 0.5); + line.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 }; + bdGrid.Children.Add(line); + } + + // 画小刻度 + for (int i = 0; i < 10; i++) + { + var start = -140 + 28 * i + 2.8; + for (int j = 0; j < 9; j++) + { + Line line = new Line(); + line.X1 = 0; + line.Y1 = 0; + line.X2 = 0; + line.Y2 = 6; + line.Stroke = Brushes.Gray; + line.StrokeThickness = 1; + line.HorizontalAlignment = HorizontalAlignment.Center; + line.RenderTransformOrigin = new Point(0.5, 0.5); + line.RenderTransform = new RotateTransform() { Angle = start + j * 2.8 }; + bdGrid.Children.Add(line); + } + } + } + #endregion + protected override void OnValueChanged(double oldValue, double newValue) + { + base.OnValueChanged(oldValue, newValue); + Update(); + } + + protected override void OnMaximumChanged(double oldMaximum, double newMaximum) + { + base.OnMaximumChanged(oldMaximum, newMaximum); + Update(); + } + + protected override void OnMinimumChanged(double oldMinimum, double newMinimum) + { + base.OnMinimumChanged(oldMinimum, newMinimum); + Update(); + } + + public string ValueChangedExecute + { + get { return (string)GetValue(ValueChangedExecuteProperty); } + set { SetValue(ValueChangedExecuteProperty, value); } + } + public static readonly DependencyProperty ValueChangedExecuteProperty = + DependencyProperty.Register("ValueChangedExecute", typeof(string), typeof(KnobButton), new PropertyMetadata(string.Empty)); + + public int Step + { + get { return (int)GetValue(StepProperty); } + set { SetValue(StepProperty, value); } + } + public static readonly DependencyProperty StepProperty = + DependencyProperty.Register("Step", typeof(int), typeof(KnobButton), new PropertyMetadata(1)); + + RotateTransform rotatevalue; + Grid bdGrid; + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + rotatevalue = GetTemplateChild("rotatevalue") as RotateTransform; + bdGrid = GetTemplateChild("bdGrid") as Grid; + Update(); + InitTick(); + } + + private void Update() + { + if (rotatevalue == null) return; + double perangle = 280 / (Maximum - Minimum); + double angle = (perangle * (Value - Minimum)) + 40; + + DoubleAnimation da = new DoubleAnimation(); + da.Duration = new Duration(TimeSpan.FromMilliseconds(350)); + da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; + da.To = angle; + + rotatevalue.Angle = angle; + rotatevalue.BeginAnimation(RotateTransform.AngleProperty, da); + } + + Point lastpoint; + private void Path_MouseMove(object sender, MouseEventArgs e) + { + if (e.LeftButton == MouseButtonState.Released) return; + + CaptureMouse(); + Point point = e.GetPosition(this); + double xmove = point.X - lastpoint.X; + double ymove = point.Y - lastpoint.Y; + + double changeValue = (xmove + ymove) / 10 * Step; + if ((changeValue + Value) > Maximum) + { + if (Value < Maximum) + { + Value = Maximum; + } + return; + } + + if ((changeValue + Value) < Minimum) + { + if (Value > Minimum) + { + Value = Minimum; + } + return; + } + + Value = changeValue + Value; + lastpoint = point; + } + + private void Path_MouseDown(object sender, MouseButtonEventArgs e) + { + if (e.LeftButton == MouseButtonState.Released) return; + lastpoint = e.GetPosition(this); + } + + private void KnobButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + ReleaseMouseCapture(); + } + + private void Path_MouseWheel(object sender, MouseWheelEventArgs e) + { + double changeValue = (e.Delta / 120) * Step; + if ((changeValue + Value) > Maximum) + { + if (Value < Maximum) + { + Value = Maximum; + } + return; + } + + if ((changeValue + Value) < Minimum) + { + if (Value > Minimum) + { + Value = Minimum; + } + return; + } + + Value = Value + changeValue; + Update(); + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/NumberBox.cs b/BeDesignerSCADA/CustomerControls/NumberBox.cs new file mode 100644 index 00000000..3027a1b9 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/NumberBox.cs @@ -0,0 +1,372 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class NumberBox : TextBox, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + static NumberBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberBox), new FrameworkPropertyMetadata(typeof(NumberBox))); + + FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(CURVALUE, new PropertyChangedCallback(OnCurValueChanged)); + CurValueProperty = DependencyProperty.Register("CurValue", typeof(double), typeof(NumberBox), metadata); + + metadata = new FrameworkPropertyMetadata(MINVALUE, new PropertyChangedCallback(OnMinValueChanged)); + MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(NumberBox), metadata); + + metadata = new FrameworkPropertyMetadata(MAXVALUE, new PropertyChangedCallback(OnMaxValueChanged)); + MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(NumberBox), metadata); + + metadata = new FrameworkPropertyMetadata(DIGITS, new PropertyChangedCallback(OnDigitsChanged)); + DigitsProperty = DependencyProperty.Register("Digits", typeof(int), typeof(NumberBox), metadata); + } + public string ControlType => "控件"; + + public NumberBox() + { + Width = 80; + Height = 30; + CurValue = 0.01; + Digits = 2; + + VerticalContentAlignment = VerticalAlignment.Center; + + Style = Application.Current.Resources["DesignNumberBox"] as Style;//FindResource("DesignNumberBox") as Style; + + this.TextChanged += NumberBox_TextChanged; + this.PreviewKeyDown += NumberBox_KeyDown; + this.LostFocus += NumberBox_LostFocus; + DataObject.AddPastingHandler(this, NumberBox_Pasting); + Focusable = false; + } + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + IsEnabled = true; + Register(); + Style = null; + Focusable = true; + } + } + } + + public void Register() + { + } + + #region DependencyProperty + private const double CURVALUE = 0; //当前值 + private const double MINVALUE = double.MinValue; //最小值 + private const double MAXVALUE = double.MaxValue; //最大值 + private const int DIGITS = 15; //小数点精度 + + public static readonly DependencyProperty CurValueProperty; + public static readonly DependencyProperty MinValueProperty; + public static readonly DependencyProperty MaxValueProperty; + public static readonly DependencyProperty DigitsProperty; + + public double CurValue + { + get + { + return (double)GetValue(CurValueProperty); + } + set + { + double v = value; + if (value < MinValue) + { + v = MinValue; + } + else if (value > MaxValue) + { + v = MaxValue; + } + v = Math.Round(v, Digits); + + SetValue(CurValueProperty, v); + // if do not go into OnCurValueChanged then force update ui + if (v != value) + { + this.Text = v.ToString(); + } + } + } + public double MinValue + { + get + { + return (double)GetValue(MinValueProperty); + } + set + { + SetValue(MinValueProperty, value); + } + } + public double MaxValue + { + get + { + return (double)GetValue(MaxValueProperty); + } + set + { + SetValue(MaxValueProperty, value); + } + } + public int Digits + { + get + { + return (int)GetValue(DigitsProperty); + } + set + { + int digits = value; + if (digits <= 0) + { + digits = 0; + } + if (digits > 15) + { + digits = 15; + } + SetValue(DigitsProperty, value); + } + } + + private static void OnCurValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + double value = (double)e.NewValue; + NumberBox numericBox = (NumberBox)sender; + numericBox.Text = value.ToString(); + } + private static void OnMinValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + double minValue = (double)e.NewValue; + NumberBox numericBox = (NumberBox)sender; + numericBox.MinValue = minValue; + } + private static void OnMaxValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + double maxValue = (double)e.NewValue; + NumberBox numericBox = (NumberBox)sender; + numericBox.MaxValue = maxValue; + } + private static void OnDigitsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + int digits = (int)e.NewValue; + NumberBox numericBox = (NumberBox)sender; + numericBox.CurValue = Math.Round(numericBox.CurValue, digits); + numericBox.MinValue = Math.Round(numericBox.MinValue, digits); + numericBox.MaxValue = Math.Round(numericBox.MaxValue, digits); + } + #endregion + + + void NumberBox_TextChanged(object sender, TextChangedEventArgs e) + { + NumberBox numericBox = sender as NumberBox; + if (string.IsNullOrEmpty(numericBox.Text)) + { + return; + } + + TrimZeroStart(); + + double value = MinValue; + if (!Double.TryParse(numericBox.Text, out value)) + { + return; + } + + if (value != this.CurValue) + { + this.CurValue = value; + } + } + + void NumberBox_KeyDown(object sender, KeyEventArgs e) + { + Key key = e.Key; + if (IsControlKeys(key)) + { + return; + } + else if (IsDigit(key)) + { + return; + } + else if (IsSubtract(key)) //- + { + TextBox textBox = sender as TextBox; + string str = textBox.Text; + if (str.Length > 0 && textBox.SelectionStart != 0) + { + e.Handled = true; + } + } + else if (IsDot(key)) //point + { + if (this.Digits > 0) + { + TextBox textBox = sender as TextBox; + string str = textBox.Text; + if (str.Contains('.') || str == "-") + { + e.Handled = true; + } + } + else + { + e.Handled = true; + } + } + else + { + e.Handled = true; + } + } + + void NumberBox_LostFocus(object sender, RoutedEventArgs e) + { + NumberBox numericBox = sender as NumberBox; + if (string.IsNullOrEmpty(numericBox.Text)) + { + numericBox.Text = this.CurValue.ToString(); + } + } + + private void NumberBox_Pasting(object sender, DataObjectPastingEventArgs e) + { + e.CancelCommand(); + } + + private static readonly List _controlKeys = new List + { + Key.Back, + Key.CapsLock, + Key.Down, + Key.End, + Key.Enter, + Key.Escape, + Key.Home, + Key.Insert, + Key.Left, + Key.PageDown, + Key.PageUp, + Key.Right, + Key.Tab, + Key.Up + }; + public static bool IsControlKeys(Key key) + { + return _controlKeys.Contains(key); + } + + public static bool IsDigit(Key key) + { + bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0; + bool retVal; + if (key >= Key.D0 && key <= Key.D9 && !shiftKey) + { + retVal = true; + } + else + { + retVal = key >= Key.NumPad0 && key <= Key.NumPad9; + } + return retVal; + } + + + public static bool IsDot(Key key) + { + bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0; + bool flag = false; + if (key == Key.Decimal) + { + flag = true; + } + if (key == Key.OemPeriod && !shiftKey) + { + flag = true; + } + return flag; + } + public static bool IsSubtract(Key key) + { + bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0; + bool flag = false; + if (key == Key.Subtract) + { + flag = true; + } + if (key == Key.OemMinus && !shiftKey) + { + flag = true; + } + return flag; + } + + private void TrimZeroStart() + { + if (this.Text.Length == 1) + { + return; + } + string resultText = this.Text; + int zeroCount = 0; + foreach (char c in this.Text) + { + if (c == '0') { zeroCount++; } + else { break; } + } + if (zeroCount == 0) + { + return; + } + + if (this.Text.Contains('.')) + { + if (this.Text[zeroCount] != '.') + { + resultText = this.Text.TrimStart('0'); + } + else if (zeroCount > 1) + { + resultText = this.Text.Substring(zeroCount - 1); + } + } + else if (zeroCount > 0) + { + resultText = this.Text.TrimStart('0'); + } + } + + } +} diff --git a/BeDesignerSCADA/CustomerControls/StatusLight.cs b/BeDesignerSCADA/CustomerControls/StatusLight.cs new file mode 100644 index 00000000..7e26f772 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/StatusLight.cs @@ -0,0 +1,101 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class StatusLight : Control, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public StatusLight() + { + Width = 80; + Height = 80; + } + public string ControlType => "控件"; + + static StatusLight() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(StatusLight), new FrameworkPropertyMetadata(typeof(StatusLight))); + } + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + /// + /// 状态值 + /// + [Category("值设定")] + public int StatusValue + { + get { return (int)GetValue(StatusValueProperty); } + set { SetValue(StatusValueProperty, value); } + } + public static readonly DependencyProperty StatusValueProperty = + DependencyProperty.Register("StatusValue", typeof(int), typeof(StatusLight), new UIPropertyMetadata(0, OnStatusChanged)); + + private static void OnStatusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as StatusLight).Refresh(); + + private void Refresh() + { + if (image != null) + { + switch (StatusValue) + { + case 0: + image.Source = new BitmapImage(new Uri("pack://application:,,,/Images/State0.png", UriKind.Absolute)); + break; + case -1: + image.Source = new BitmapImage(new Uri("pack://application:,,,/Images/State11.png", UriKind.Absolute)); + break; + case 1: + image.Source = new BitmapImage(new Uri("pack://application:,,,/Images/State1.png", UriKind.Absolute)); + break; + case 2: + image.Source = new BitmapImage(new Uri("pack://application:,,,/Images/State2.png", UriKind.Absolute)); + break; + default: + break; + } + } + } + + Image image; + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + image = GetTemplateChild("ima") as Image; + Refresh(); + } + + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/SwitchButton.cs b/BeDesignerSCADA/CustomerControls/SwitchButton.cs new file mode 100644 index 00000000..3ad12d34 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/SwitchButton.cs @@ -0,0 +1,150 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + + +namespace BeDesignerSCADA.CustomerControls +{ + [TemplatePart(Name = ELLIPSE, Type = typeof(FrameworkElement))] + [TemplatePart(Name = TranslateX, Type = typeof(TranslateTransform))] + public class SwitchButton : ToggleButton, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public SwitchButton() + { + SetCurrentValue(WidthProperty, 120d); + SetCurrentValue(HeightProperty, 40d); + } + + public const string ELLIPSE = "ELLIPSE"; + public const string TranslateX = "TranslateX"; + static SwitchButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(SwitchButton), new FrameworkPropertyMetadata(typeof(SwitchButton))); + } + + /// + /// 不勾选时执行代码 + /// + [Category("事件")] + public string UnCheckedExec + { + get { return (string)GetValue(UnCheckedExecProperty); } + set { SetValue(UnCheckedExecProperty, value); } + } + public static readonly DependencyProperty UnCheckedExecProperty = + DependencyProperty.Register("UnCheckedExec", typeof(string), typeof(SwitchButton), new PropertyMetadata(string.Empty)); + + /// + /// 勾选时执行代码 + /// + [Category("事件")] + public string CheckedExec + { + get { return (string)GetValue(CheckedExecProperty); } + set { SetValue(CheckedExecProperty, value); } + } + public static readonly DependencyProperty CheckedExecProperty = + DependencyProperty.Register("CheckedExec", typeof(string), typeof(SwitchButton), new PropertyMetadata(string.Empty)); + + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + ellipse.Width = Height - 8; + ellipse.Height = Height - 8; + Refresh(); + } + + TranslateTransform transX; + Ellipse ellipse; + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + ellipse = GetTemplateChild(ELLIPSE) as Ellipse; + transX = GetTemplateChild(TranslateX) as TranslateTransform; + } + protected override void OnChecked(RoutedEventArgs e) + { + base.OnChecked(e); + Refresh(); + } + protected override void OnUnchecked(RoutedEventArgs e) + { + base.OnUnchecked(e); + Refresh(); + } + + void Refresh() + { + if (ellipse == null) + { + return; + } + DoubleAnimation da = new DoubleAnimation(); + da.Duration = new Duration(TimeSpan.FromMilliseconds(250)); + da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; + if (IsChecked == true) + { + da.To = ActualWidth - ellipse.ActualWidth - 5; + ellipse.SetCurrentValue(Ellipse.FillProperty, Background); + } + else + { + da.To = 3; + ellipse.SetCurrentValue(Ellipse.FillProperty, Brushes.Gray); + } + + transX.BeginAnimation(TranslateTransform.XProperty, da); + } + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + public void Register() + { + Checked += TheCheckBox_Checked; + Unchecked += TheCheckBox_Unchecked; + } + private void TheCheckBox_Unchecked(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(UnCheckedExec); + } + + private void TheCheckBox_Checked(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(CheckedExec); + } + public string ControlType => "控件"; + + } + + +} diff --git a/BeDesignerSCADA/CustomerControls/TheButton.xaml b/BeDesignerSCADA/CustomerControls/TheButton.xaml new file mode 100644 index 00000000..27ec3078 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheButton.xaml @@ -0,0 +1,9 @@ + diff --git a/BeDesignerSCADA/CustomerControls/TheButton.xaml.cs b/BeDesignerSCADA/CustomerControls/TheButton.xaml.cs new file mode 100644 index 00000000..6de02811 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheButton.xaml.cs @@ -0,0 +1,77 @@ + +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheButton.xaml 的交互逻辑 + /// + public partial class TheButton : Button, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheButton() + { + InitializeComponent(); + Content = "按钮"; + Width = 80; + Height = 30; + Style = Application.Current.Resources["DesignButton"] as Style;//FindResource("DesignButton") as Style; + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Style = null; + Register(); + } + } + } + + [Category("事件")] + public string ClickExec + { + get { return (string)GetValue(ClickExecProperty); } + set { SetValue(ClickExecProperty, value); } + } + public static readonly DependencyProperty ClickExecProperty = + DependencyProperty.Register("ClickExec", typeof(string), typeof(TheButton), new PropertyMetadata(string.Empty)); + + /// + /// 注册需要处理的事件 + /// + public void Register() + { + this.Click += MyButton_Click; + } + + private void MyButton_Click(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(ClickExec); + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheCheckBox.xaml b/BeDesignerSCADA/CustomerControls/TheCheckBox.xaml new file mode 100644 index 00000000..5da52623 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheCheckBox.xaml @@ -0,0 +1,9 @@ + + diff --git a/BeDesignerSCADA/CustomerControls/TheCheckBox.xaml.cs b/BeDesignerSCADA/CustomerControls/TheCheckBox.xaml.cs new file mode 100644 index 00000000..82f2d5f1 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheCheckBox.xaml.cs @@ -0,0 +1,92 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheCheckBox.xaml 的交互逻辑 + /// + public partial class TheCheckBox : CheckBox, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheCheckBox() + { + InitializeComponent(); + Content = "勾选框"; + VerticalContentAlignment = VerticalAlignment.Center; + } + + public string ControlType => "控件"; + + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + /// + /// 不勾选时执行代码 + /// + [Category("事件")] + public string UnCheckedExec + { + get { return (string)GetValue(UnCheckedExecProperty); } + set { SetValue(UnCheckedExecProperty, value); } + } + public static readonly DependencyProperty UnCheckedExecProperty = + DependencyProperty.Register("UnCheckedExec", typeof(string), typeof(TheCheckBox), new PropertyMetadata(string.Empty)); + + /// + /// 勾选时执行代码 + /// + [Category("事件")] + public string CheckedExec + { + get { return (string)GetValue(CheckedExecProperty); } + set { SetValue(CheckedExecProperty, value); } + } + public static readonly DependencyProperty CheckedExecProperty = + DependencyProperty.Register("CheckedExec", typeof(string), typeof(TheCheckBox), new PropertyMetadata(string.Empty)); + + public void Register() + { + Checked += TheCheckBox_Checked; + Unchecked += TheCheckBox_Unchecked; + } + + private void TheCheckBox_Unchecked(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(UnCheckedExec); + } + + private void TheCheckBox_Checked(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(CheckedExec); + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheComboBox.xaml b/BeDesignerSCADA/CustomerControls/TheComboBox.xaml new file mode 100644 index 00000000..c7e906cc --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheComboBox.xaml @@ -0,0 +1,9 @@ + + diff --git a/BeDesignerSCADA/CustomerControls/TheComboBox.xaml.cs b/BeDesignerSCADA/CustomerControls/TheComboBox.xaml.cs new file mode 100644 index 00000000..65400db4 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheComboBox.xaml.cs @@ -0,0 +1,75 @@ +using BeDesignerSCADA.Speical; +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheComboBox.xaml 的交互逻辑 + /// + public partial class TheComboBox : ComboBox, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheComboBox() + { + InitializeComponent(); + VerticalContentAlignment = VerticalAlignment.Center; + ItemsString = new ItemsList() { "AA", "BB" }; + Style = Application.Current.Resources["DesignComboBox"] as Style; + Width = 80; + Height = 30; + Focusable = false; + } + public string ControlType => "控件"; + + public ItemsList ItemsString + { + get { return (ItemsList)GetValue(ItemsStringProperty); } + set { SetValue(ItemsStringProperty, value); } + } + + public static readonly DependencyProperty ItemsStringProperty = + DependencyProperty.Register("ItemsString", typeof(ItemsList), typeof(TheComboBox), new PropertyMetadata(null)); + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Focusable = true; + IsEnabled = true; + Register(); + Style = null; + } + } + } + + public void Register() + { + // 运行时进行项目绑定 + Binding binding = new Binding(); + binding.RelativeSource = new RelativeSource() { Mode = RelativeSourceMode.Self }; + binding.Path = new PropertyPath("ItemsString"); + SetBinding(ItemsSourceProperty, binding); + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheGroupBox.xaml b/BeDesignerSCADA/CustomerControls/TheGroupBox.xaml new file mode 100644 index 00000000..266ff664 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheGroupBox.xaml @@ -0,0 +1,9 @@ + + diff --git a/BeDesignerSCADA/CustomerControls/TheGroupBox.xaml.cs b/BeDesignerSCADA/CustomerControls/TheGroupBox.xaml.cs new file mode 100644 index 00000000..4ac5b7aa --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheGroupBox.xaml.cs @@ -0,0 +1,58 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheGroupBox.xaml 的交互逻辑 + /// + public partial class TheGroupBox : GroupBox, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheGroupBox() + { + InitializeComponent(); + Width = 150; + Height = 150; + Header = "分组"; + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + /// + /// 注册需要处理的事件 + /// + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheImage.xaml b/BeDesignerSCADA/CustomerControls/TheImage.xaml new file mode 100644 index 00000000..28b2aae5 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheImage.xaml @@ -0,0 +1,9 @@ + + diff --git a/BeDesignerSCADA/CustomerControls/TheImage.xaml.cs b/BeDesignerSCADA/CustomerControls/TheImage.xaml.cs new file mode 100644 index 00000000..a25fdc3a --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheImage.xaml.cs @@ -0,0 +1,57 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheImage.xaml 的交互逻辑 + /// + public partial class TheImage : Image, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheImage() + { + InitializeComponent(); + Stretch = Stretch.UniformToFill; + SetCurrentValue(SourceProperty, new BitmapImage(new Uri("pack://application:,,,/Images/win.png", UriKind.Absolute))); + Width = 120; + Height = 40; + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + public void Register() + { + + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheRadioButton.cs b/BeDesignerSCADA/CustomerControls/TheRadioButton.cs new file mode 100644 index 00000000..a2cbed76 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheRadioButton.cs @@ -0,0 +1,59 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class TheRadioButton : RadioButton, IExecutable, IDisposable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheRadioButton() + { + SetCurrentValue(ContentProperty, "单选按钮"); + } + static TheRadioButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TheRadioButton), new FrameworkPropertyMetadata(typeof(TheRadioButton))); + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + Style = null; + } + } + } + + public void Register() + { + + } + + public void Dispose() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheSlider.cs b/BeDesignerSCADA/CustomerControls/TheSlider.cs new file mode 100644 index 00000000..62918e6c --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheSlider.cs @@ -0,0 +1,69 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class TheSlider : Slider, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + static TheSlider() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TheSlider), new FrameworkPropertyMetadata(typeof(TheSlider))); + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + Style = null; + } + } + } + + public string ValueChangedExecute + { + get { return (string)GetValue(ValueChangedExecuteProperty); } + set { SetValue(ValueChangedExecuteProperty, value); } + } + public static readonly DependencyProperty ValueChangedExecuteProperty = + DependencyProperty.Register("ValueChangedExecute", typeof(string), typeof(TheSlider), new PropertyMetadata(string.Empty)); + + + public void Register() + { + ValueChanged += TheSlider_ValueChanged; + } + + private void TheSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { + Config.GetInstance().RunJsScipt(ValueChangedExecute); + } + + public void Dispose() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheTextBlock.xaml b/BeDesignerSCADA/CustomerControls/TheTextBlock.xaml new file mode 100644 index 00000000..5127fbd4 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheTextBlock.xaml @@ -0,0 +1,9 @@ + + diff --git a/BeDesignerSCADA/CustomerControls/TheTextBlock.xaml.cs b/BeDesignerSCADA/CustomerControls/TheTextBlock.xaml.cs new file mode 100644 index 00000000..d0dd347c --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheTextBlock.xaml.cs @@ -0,0 +1,55 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheTextBlock.xaml 的交互逻辑 + /// + public partial class TheTextBlock : TextBlock, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheTextBlock() + { + InitializeComponent(); + Text = "文本块"; + Width = 80; + Height = 30; + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheTextBox.cs b/BeDesignerSCADA/CustomerControls/TheTextBox.cs new file mode 100644 index 00000000..8014d840 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheTextBox.cs @@ -0,0 +1,61 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA.CustomerControls +{ + public class TheTextBox : TextBox, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + static TheTextBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TheTextBox), new FrameworkPropertyMetadata(typeof(TheTextBox))); + } + + public TheTextBox() + { + Width = 80; + Height = 30; + Text = "0.01"; + VerticalContentAlignment = VerticalAlignment.Center; + Style = Application.Current.Resources["DesignTheTextBox"] as Style;//FindResource("DesignTheTextBox") as Style; + Focusable = false; + } + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + IsEnabled = true; + Focusable = true; + Register(); + Style = null; + } + } + } + + public void Register() + { + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheTimer.cs b/BeDesignerSCADA/CustomerControls/TheTimer.cs new file mode 100644 index 00000000..eed8d263 --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheTimer.cs @@ -0,0 +1,99 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System.Windows.Threading; + +namespace BeDesignerSCADA.CustomerControls +{ + public class TheTimer : Control, IExecutable, IDisposable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheTimer() + { + Width = 40; + Height = 40; + } + static TheTimer() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TheTimer), new FrameworkPropertyMetadata(typeof(TheTimer))); + } + + public string ControlType => "控件"; + + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + Style = null; + } + } + } + + DispatcherTimer timer = new DispatcherTimer(); + public void Register() + { + timer.Interval = TimeSpan.FromMilliseconds(Interval); + timer.Tick += Timer_Tick; + timer.Start(); + } + + private void Timer_Tick(object sender, EventArgs e) + { + Config.GetInstance().RunJsScipt(TikcExecute); + } + + public void Start() => timer.Start(); + public void Stop() => timer.Stop(); + + public void Dispose() + { + timer.Stop(); + } + + /// + /// 时间间隔 + /// + public int Interval + { + get { return (int)GetValue(IntervalProperty); } + set { SetValue(IntervalProperty, value); } + } + public static readonly DependencyProperty IntervalProperty = + DependencyProperty.Register("Interval", typeof(int), typeof(TheTimer), new PropertyMetadata(0)); + + + /// + /// 执行内容 + /// + [Category("事件")] + public string TikcExecute + { + get { return (string)GetValue(TikcExecuteProperty); } + set { SetValue(TikcExecuteProperty, value); } + } + public static readonly DependencyProperty TikcExecuteProperty = + DependencyProperty.Register("TikcExecute", typeof(string), typeof(TheTimer), new PropertyMetadata(string.Empty)); + } +} diff --git a/BeDesignerSCADA/CustomerControls/TheToggleButton.xaml b/BeDesignerSCADA/CustomerControls/TheToggleButton.xaml new file mode 100644 index 00000000..99974dcf --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheToggleButton.xaml @@ -0,0 +1,9 @@ + + diff --git a/BeDesignerSCADA/CustomerControls/TheToggleButton.xaml.cs b/BeDesignerSCADA/CustomerControls/TheToggleButton.xaml.cs new file mode 100644 index 00000000..a2b9c8aa --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/TheToggleButton.xaml.cs @@ -0,0 +1,96 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// TheToggleButton.xaml 的交互逻辑 + /// + public partial class TheToggleButton : ToggleButton, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + public TheToggleButton() + { + InitializeComponent(); + Content = "开关"; + Width = 80; + Height = 30; + Style = Application.Current.Resources["DesignToggleButton"] as Style;//FindResource("DesignToggleButton") as Style; + VerticalContentAlignment = VerticalAlignment.Center; + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Style = Application.Current.Resources["ExecuteToggleButton"] as Style;//FindResource("ExecuteToggleButton") as Style; + + Register(); + } + } + } + + /// + /// 不勾选时执行代码 + /// + [Category("事件")] + public string UnCheckedExec + { + get { return (string)GetValue(UnCheckedExecProperty); } + set { SetValue(UnCheckedExecProperty, value); } + } + public static readonly DependencyProperty UnCheckedExecProperty = + DependencyProperty.Register("UnCheckedExec", typeof(string), typeof(TheToggleButton), new PropertyMetadata(string.Empty)); + + /// + /// 勾选时执行代码 + /// + [Category("事件")] + public string CheckedExec + { + get { return (string)GetValue(CheckedExecProperty); } + set { SetValue(CheckedExecProperty, value); } + } + public static readonly DependencyProperty CheckedExecProperty = + DependencyProperty.Register("CheckedExec", typeof(string), typeof(TheToggleButton), new PropertyMetadata(string.Empty)); + + public void Register() + { + Checked += TheCheckBox_Checked; + Unchecked += TheCheckBox_Unchecked; + } + + private void TheCheckBox_Unchecked(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(UnCheckedExec); + } + + private void TheCheckBox_Checked(object sender, RoutedEventArgs e) + { + Config.GetInstance().RunJsScipt(CheckedExec); + } + } +} diff --git a/BeDesignerSCADA/CustomerControls/WaveProgressBar.cs b/BeDesignerSCADA/CustomerControls/WaveProgressBar.cs new file mode 100644 index 00000000..b5150c5d --- /dev/null +++ b/BeDesignerSCADA/CustomerControls/WaveProgressBar.cs @@ -0,0 +1,187 @@ +using BPASmartClient.Compiler; +using BPASmartClient.SCADAControl; +using System; +using System.Windows; +using System.Windows.Controls.Primitives; +using System.Windows.Media; + +namespace BeDesignerSCADA.CustomerControls +{ + /// + /// 波浪进度条 + /// + [TemplatePart(Name = ElementWave, Type = typeof(FrameworkElement))] + [TemplatePart(Name = ElementClip, Type = typeof(FrameworkElement))] + public class WaveProgressBar : RangeBase, IExecutable + { + public event EventHandler PropertyChange; //声明一个事件 + + private const string ElementWave = "PART_Wave"; + + private const string ElementClip = "PART_Clip"; + + private FrameworkElement _waveElement; + + private const double TranslateTransformMinY = -20; + + private double _translateTransformYRange; + + private TranslateTransform _translateTransform; + + public WaveProgressBar() + { + Loaded += (s, e) => UpdateWave(Value); + SetCurrentValue(WidthProperty, 200d); + SetCurrentValue(HeightProperty, 200d); + SetCurrentValue(ValueProperty, 50d); + } + + static WaveProgressBar() + { + FocusableProperty.OverrideMetadata(typeof(WaveProgressBar), + new FrameworkPropertyMetadata(ValueBoxes.FalseBox)); + MaximumProperty.OverrideMetadata(typeof(WaveProgressBar), + new FrameworkPropertyMetadata(ValueBoxes.Double100Box)); + } + + protected override void OnValueChanged(double oldValue, double newValue) + { + base.OnValueChanged(oldValue, newValue); + + UpdateWave(newValue); + } + + private void UpdateWave(double value) + { + if (_translateTransform == null || IsVerySmall(Maximum)) return; + var scale = 1 - value / Maximum; + var y = _translateTransformYRange * scale + TranslateTransformMinY; + _translateTransform.Y = y; + } + + public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06; + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _waveElement = GetTemplateChild(ElementWave) as FrameworkElement; + var clipElement = GetTemplateChild(ElementClip) as FrameworkElement; + + if (_waveElement != null && clipElement != null) + { + _translateTransform = new TranslateTransform + { + Y = clipElement.Height + }; + _translateTransformYRange = clipElement.Height - TranslateTransformMinY; + _waveElement.RenderTransform = new TransformGroup + { + Children = { _translateTransform } + }; + } + } + + public static readonly DependencyProperty TextProperty = DependencyProperty.Register( + "Text", typeof(string), typeof(WaveProgressBar), new PropertyMetadata(default(string))); + + public string Text + { + get => (string)GetValue(TextProperty); + set => SetValue(TextProperty, value); + } + + public static readonly DependencyProperty ShowTextProperty = DependencyProperty.Register( + "ShowText", typeof(bool), typeof(WaveProgressBar), new PropertyMetadata(ValueBoxes.TrueBox)); + + public bool ShowText + { + get => (bool)GetValue(ShowTextProperty); + set => SetValue(ShowTextProperty, ValueBoxes.BooleanBox(value)); + } + + public static readonly DependencyProperty WaveFillProperty = DependencyProperty.Register( + "WaveFill", typeof(Brush), typeof(WaveProgressBar), new PropertyMetadata(default(Brush))); + + public Brush WaveFill + { + get => (Brush)GetValue(WaveFillProperty); + set => SetValue(WaveFillProperty, value); + } + + public static readonly DependencyProperty WaveThicknessProperty = DependencyProperty.Register( + "WaveThickness", typeof(double), typeof(WaveProgressBar), new PropertyMetadata(ValueBoxes.Double0Box)); + + public double WaveThickness + { + get => (double)GetValue(WaveThicknessProperty); + set => SetValue(WaveThicknessProperty, value); + } + + public static readonly DependencyProperty WaveStrokeProperty = DependencyProperty.Register( + "WaveStroke", typeof(Brush), typeof(WaveProgressBar), new PropertyMetadata(default(Brush))); + + public Brush WaveStroke + { + get => (Brush)GetValue(WaveStrokeProperty); + set => SetValue(WaveStrokeProperty, value); + } + + public string ControlType => "控件"; + + private bool isExecuteState; + public bool IsExecuteState + { + get { return isExecuteState; } + set + { + isExecuteState = value; + if (IsExecuteState) + { + Register(); + } + } + } + + public void Register() + { + } + } + + internal static class ValueBoxes + { + internal static object TrueBox = true; + + internal static object FalseBox = false; + + internal static object Double0Box = .0; + + internal static object Double01Box = .1; + + internal static object Double1Box = 1.0; + + internal static object Double10Box = 10.0; + + internal static object Double20Box = 20.0; + + internal static object Double100Box = 100.0; + + internal static object Double200Box = 200.0; + + internal static object Double300Box = 300.0; + + internal static object DoubleNeg1Box = -1.0; + + internal static object Int0Box = 0; + + internal static object Int1Box = 1; + + internal static object Int2Box = 2; + + internal static object Int5Box = 5; + + internal static object Int99Box = 99; + + internal static object BooleanBox(bool value) => value ? TrueBox : FalseBox; + } +} diff --git a/BeDesignerSCADA/DLL/Antlr3.Runtime.dll b/BeDesignerSCADA/DLL/Antlr3.Runtime.dll new file mode 100644 index 00000000..34bd478f Binary files /dev/null and b/BeDesignerSCADA/DLL/Antlr3.Runtime.dll differ diff --git a/BeDesignerSCADA/DLL/Unvell.ReoScript.dll b/BeDesignerSCADA/DLL/Unvell.ReoScript.dll new file mode 100644 index 00000000..eae3ea23 Binary files /dev/null and b/BeDesignerSCADA/DLL/Unvell.ReoScript.dll differ diff --git a/BeDesignerSCADA/Fonts/ds-digib.ttf b/BeDesignerSCADA/Fonts/ds-digib.ttf new file mode 100644 index 00000000..064ad478 Binary files /dev/null and b/BeDesignerSCADA/Fonts/ds-digib.ttf differ diff --git a/BeDesignerSCADA/Helper/Config.cs b/BeDesignerSCADA/Helper/Config.cs new file mode 100644 index 00000000..a4b26b71 --- /dev/null +++ b/BeDesignerSCADA/Helper/Config.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Unvell.ReoScript; + +namespace BeDesignerSCADA.Helper +{ + internal class Config + { + private static ScriptRunningMachine srm { get; } = new ScriptRunningMachine(); + + static Config() + { + srm.WorkMode |= + // Enable DirectAccess + MachineWorkMode.AllowDirectAccess + // Ignore exceptions in CLR calling (by default) + | MachineWorkMode.IgnoreCLRExceptions + // Enable CLR Event Binding + | MachineWorkMode.AllowCLREventBind; + + RegisterFunction(); + } + + /// + /// 运行脚本 + /// + /// + public static void RunJsScipt(string script) + { + try + { + srm.Run(script); + } + catch (Exception e) + { + MessageBox.Show(e.Message, "脚本错误"); + } + } + + /// + /// 注册对象到js + /// + public static void SetVariable(string name, object obj) + { + srm.SetGlobalVariable(name, obj); + } + + /// + /// 注册方法到Js + /// + private static void RegisterFunction() + { + srm["ShowMessage"] = new NativeFunctionObject("ShowMessage", (ctx, owner, args) => + { + StringBuilder sb = new StringBuilder(); + foreach (var item in args) + { + sb.Append(item.ToString()); + } + + MessageBox.Show($"{sb}", "提示"); + return null; + }); + + srm["SetICDValue"] = new NativeFunctionObject("SetICDValue", (ctx, owner, args) => + { + MessageBox.Show($"发送ICD数据", "提示"); + return null; + }); + } + } +} diff --git a/BeDesignerSCADA/Images/State0.png b/BeDesignerSCADA/Images/State0.png new file mode 100644 index 00000000..46230fad Binary files /dev/null and b/BeDesignerSCADA/Images/State0.png differ diff --git a/BeDesignerSCADA/Images/State1.png b/BeDesignerSCADA/Images/State1.png new file mode 100644 index 00000000..971dcb64 Binary files /dev/null and b/BeDesignerSCADA/Images/State1.png differ diff --git a/BeDesignerSCADA/Images/State11.png b/BeDesignerSCADA/Images/State11.png new file mode 100644 index 00000000..51f70e42 Binary files /dev/null and b/BeDesignerSCADA/Images/State11.png differ diff --git a/BeDesignerSCADA/Images/State2.png b/BeDesignerSCADA/Images/State2.png new file mode 100644 index 00000000..1b9a084d Binary files /dev/null and b/BeDesignerSCADA/Images/State2.png differ diff --git a/BeDesignerSCADA/Images/bj.png b/BeDesignerSCADA/Images/bj.png new file mode 100644 index 00000000..f6b621e0 Binary files /dev/null and b/BeDesignerSCADA/Images/bj.png differ diff --git a/BeDesignerSCADA/Images/fyf.ico b/BeDesignerSCADA/Images/fyf.ico new file mode 100644 index 00000000..346bbc6c Binary files /dev/null and b/BeDesignerSCADA/Images/fyf.ico differ diff --git a/BeDesignerSCADA/Images/gaugeMask.png b/BeDesignerSCADA/Images/gaugeMask.png new file mode 100644 index 00000000..fcd90e18 Binary files /dev/null and b/BeDesignerSCADA/Images/gaugeMask.png differ diff --git a/BeDesignerSCADA/Images/hbl.ico b/BeDesignerSCADA/Images/hbl.ico new file mode 100644 index 00000000..cf89051a Binary files /dev/null and b/BeDesignerSCADA/Images/hbl.ico differ diff --git a/BeDesignerSCADA/Images/ico.ico b/BeDesignerSCADA/Images/ico.ico new file mode 100644 index 00000000..379235a4 Binary files /dev/null and b/BeDesignerSCADA/Images/ico.ico differ diff --git a/BeDesignerSCADA/Images/redis.png b/BeDesignerSCADA/Images/redis.png new file mode 100644 index 00000000..351f368e Binary files /dev/null and b/BeDesignerSCADA/Images/redis.png differ diff --git a/BeDesignerSCADA/Images/timericon.png b/BeDesignerSCADA/Images/timericon.png new file mode 100644 index 00000000..ab1581f9 Binary files /dev/null and b/BeDesignerSCADA/Images/timericon.png differ diff --git a/BeDesignerSCADA/Images/win.png b/BeDesignerSCADA/Images/win.png new file mode 100644 index 00000000..d6f24242 Binary files /dev/null and b/BeDesignerSCADA/Images/win.png differ diff --git a/BeDesignerSCADA/Images/wx.jpg b/BeDesignerSCADA/Images/wx.jpg new file mode 100644 index 00000000..0690f5fd Binary files /dev/null and b/BeDesignerSCADA/Images/wx.jpg differ diff --git a/BeDesignerSCADA/Images/zfb.jpg b/BeDesignerSCADA/Images/zfb.jpg new file mode 100644 index 00000000..f42a3c29 Binary files /dev/null and b/BeDesignerSCADA/Images/zfb.jpg differ diff --git a/BeDesignerSCADA/Images/光柱.png b/BeDesignerSCADA/Images/光柱.png new file mode 100644 index 00000000..da3a0b42 Binary files /dev/null and b/BeDesignerSCADA/Images/光柱.png differ diff --git a/BeDesignerSCADA/MainWindow.xaml b/BeDesignerSCADA/MainWindow.xaml new file mode 100644 index 00000000..32129c55 --- /dev/null +++ b/BeDesignerSCADA/MainWindow.xaml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 绑定: + + + + + + + + + + + + + + + + + + + + diff --git a/BeDesignerSCADA/MainWindow.xaml.cs b/BeDesignerSCADA/MainWindow.xaml.cs new file mode 100644 index 00000000..bc7a404a --- /dev/null +++ b/BeDesignerSCADA/MainWindow.xaml.cs @@ -0,0 +1,441 @@ +using BeDesignerSCADA.ViewModel; +using BPASmart.Model; +using BPASmartClient.Compiler; +using BPASmartClient.DATABUS; +using BPASmartClient.MessageName; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Forms; +using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeDesignerSCADA +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + MainViewModel viewModel=new MainViewModel(); + public MainWindow() + { + InitializeComponent(); + //Loading(); + this.DataContext = viewModel; + viewModel.Loaded(cav); + //控件加载 + Assembly assembly = Assembly.LoadFile($"{System.AppDomain.CurrentDomain.BaseDirectory}\\BPASmartClient.SCADAControl.dll"); + //Assembly assembly = Assembly.GetExecutingAssembly(); + var controls = assembly.GetTypes().Where(t => t.GetInterface("IExecutable") != null); + CtlList.ItemsSource = controls; + viewModel.propertyGrid = kzxy; + //LoadFile(); + } + + #region 加载数据中心与事件中心 + public void Loading() + { + //try + //{ + // Assembly assembly1 = Assembly.LoadFile($"{System.AppDomain.CurrentDomain.BaseDirectory}\\BPASmartClient.MessageName.dll"); + // Type type = assembly1.GetType("BPASmartClient.MessageName.MessageName"); + // var control = Activator.CreateInstance(type); + // var fildes = control.GetType().GetFields(); + // foreach (var fi in fildes) + // { + // EventModel eventModel = new EventModel(); + // eventModel.EventValue = fi.GetValue(control)?.ToString(); + // eventModel.EventName = fi.Name; + // foreach (var item in fi.CustomAttributes) + // { + // if (item.AttributeType.Name == "CategoryAttribute") + // { + // eventModel.Category = item.ConstructorArguments.Count() > 0 ? item.ConstructorArguments[0].Value?.ToString() : ""; + // } + // else if (item.AttributeType.Name == "DescriptionAttribute") + // { + // eventModel.Description = item.ConstructorArguments.Count() > 0 ? item.ConstructorArguments[0].Value?.ToString() : ""; + // } + // else if (item.AttributeType.Name == "BrowsableAttribute") + // { + // eventModel.Browsable = item.ConstructorArguments.Count() > 0 ? (bool)item.ConstructorArguments[0].Value : true; + // } + // } + // if (!string.IsNullOrEmpty(eventModel.Category)) + // { + // if (Class_DataBus.GetInstance().EventData.ContainsKey(eventModel.Category)) + // Class_DataBus.GetInstance().EventData[eventModel.Category].Add(eventModel); + // else + // { + // Class_DataBus.GetInstance().EventData[eventModel.Category] = new List { eventModel }; + // } + // } + // } + + + // type = assembly1.GetType("BPASmartClient.MessageName.DataName"); + // control = Activator.CreateInstance(type); + // fildes = control.GetType().GetFields(); + // foreach (var fi in fildes) + // { + // ALLModel aLLModel = new ALLModel(); + // aLLModel.DataValue = fi.GetValue(control)?.ToString(); + // aLLModel.DataName = fi.Name; + // foreach (var item in fi.CustomAttributes) + // { + // if (item.AttributeType.Name == "CategoryAttribute") + // { + // aLLModel.Category = item.ConstructorArguments.Count() > 0 ? item.ConstructorArguments[0].Value?.ToString() : ""; + // } + // else if (item.AttributeType.Name == "DescriptionAttribute") + // { + // aLLModel.Description = item.ConstructorArguments.Count() > 0 ? item.ConstructorArguments[0].Value?.ToString() : ""; + // } + // else if (item.AttributeType.Name == "BrowsableAttribute") + // { + // aLLModel.Browsable = item.ConstructorArguments.Count() > 0 ? (bool)item.ConstructorArguments[0].Value : true; + // } + // } + // if (!string.IsNullOrEmpty(aLLModel.Category)) + // { + // if (Class_DataBus.GetInstance().ALLData.ContainsKey(aLLModel.Category)) + // Class_DataBus.GetInstance().ALLData[aLLModel.Category].Add(aLLModel); + // else + // { + // Class_DataBus.GetInstance().ALLData[aLLModel.Category] = new List { aLLModel }; + // } + // } + + // } + + + //} + //catch (Exception ex) + //{ + // System.Windows.MessageBox.Show(ex.Message); + //} + } + + /// + /// 加载本地文件 + /// + public void LoadFile() + { + //加载配置数据 + FJson.Read(); + viewModel.DevNameList = new System.Collections.ObjectModel.ObservableCollection(); + viewModel.DevValueList = new System.Collections.ObjectModel.ObservableCollection(); + FJson.Data.CommunicationDevices?.ToList().ForEach(data => + { + viewModel.DevNameList.Add(data.DeviceName); + data.VarTableModels?.ToList().ForEach((data) => { + + if(!viewModel.DevValueList.Contains(data.VarName) && !string.IsNullOrEmpty(data.VarName)) + viewModel.DevValueList.Add(data.VarName); + }); + }); + //CommunicationModel model = new CommunicationModel(); + //Type typeData = model.GetType(); + //PropertyInfo[] properties = typeData.GetProperties(); + //foreach (PropertyInfo property in properties) + //{ + // viewModel.DevValueList.Add(property.Name); + + //} + //ICommunicationDevice DeviceType; + //DeviceType = FJson.Data.CommunicationDevices.ElementAt(0).CommDevice; + //VariableInfo variable = new VariableInfo(DeviceType); + //PropertyInfo[] prope = variable.GetType().GetProperties(); + //foreach (var item in prope) + //{ + // viewModel.DevValueList.Add(item.Name); + //} + } + #endregion + + #region 位置调整 + /// + /// 左对齐 + /// + /// + /// + private void AglinLeftBtn_Click(object sender, RoutedEventArgs e) + { + cav.AlignLeft(); + } + /// + /// 底部对齐 + /// + /// + /// + private void AglinBottomBtn_Click(object sender, RoutedEventArgs e) + { + cav.AlignBottom(); + } + /// + /// 顶部对齐 + /// + /// + /// + private void AglinTopBtn_Click(object sender, RoutedEventArgs e) + { + cav.AlignTop(); + } + /// + /// 右对齐 + /// + /// + /// + private void AglinRightBtn_Click(object sender, RoutedEventArgs e) + { + cav.AlignRight(); + } + /// + /// 居中 + /// + /// + /// + private void AglinCenterBtn_Click(object sender, RoutedEventArgs e) + { + cav.AlignCenter(); + } + /// + /// 垂直分布 + /// + /// + /// + private void VerticalLayoutBtn_Click(object sender, RoutedEventArgs e) + { + cav.VertialLayout(); + } + /// + /// 水平分布 + /// + /// + /// + private void HorizontalLayoutBtn_Click(object sender, RoutedEventArgs e) + { + cav.HorizontalLayout(); + } + #endregion + + #region 其他事件操作 + /// + /// 运行 + /// + /// + /// + private void RunBtn_Click(object sender, RoutedEventArgs e) + { + if (sender is System.Windows.Controls.Button btn) + { + if (btn.Tag.ToString() == "运行") + { + cav.ClearSelection(); + runCanvas.Run(cav.Generator()); + } + else if (btn.Tag.ToString() == "停止") + { + runCanvas.Destory(); + } + } + } + + /// + /// 加载 + /// + /// + /// + private void LoadBtn_Click(object sender, RoutedEventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "布局文件|*.lay"; + if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + cav.Load(ofd.FileName); + } + + DoubleAnimation da = new DoubleAnimation(-200, 0, new Duration(TimeSpan.FromMilliseconds(250))); + da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; + CanvasTranslate.BeginAnimation(TranslateTransform.XProperty, da); + + DoubleAnimation daop = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromMilliseconds(250))); + daop.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; + cav.BeginAnimation(OpacityProperty, daop); + } + + /// + /// 保存 + /// + /// + /// + private void SaveBtn_Click(object sender, RoutedEventArgs e) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "布局文件|*.lay"; + + if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string str = cav.Save(); + File.WriteAllText(sfd.FileName, str, Encoding.Unicode); + } + } + + /// + /// 模拟消息发送 + /// + /// + /// + private void MNBtn_Click(object sender, RoutedEventArgs e) + { + + } + #endregion + + #region 左侧控件栏移动 + private void CtlList_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) + { + if (CtlList.SelectedItem != null && e.LeftButton == MouseButtonState.Pressed) + { + DragDrop.DoDragDrop(CtlList, CtlList.SelectedItem, System.Windows.DragDropEffects.Copy); + codeEditor.Text = cav.Save(); + } + } + + /// + /// 显示代码 + /// + /// + /// + private void showCode_Click(object sender, RoutedEventArgs e) + { + codeEditor.Text = cav.Save(); + } + + /// + /// 编辑 + /// + /// + /// + private void ToggleButton_Click(object sender, RoutedEventArgs e) + { + try + { + if (sender is ToggleButton) + { + ToggleButton toggle = (ToggleButton)sender; + Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyGridCommand = toggle.DataContext as Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem; + if (propertyGridCommand != null) + { + viewModel.Edit(propertyGridCommand); + } + } + } + catch (Exception ex) + { + + } + } + + /// + /// 变量编辑 + /// + /// + /// + private void ComboBoxValue_TextChanged(object sender,TextChangedEventArgs e) + { + try + { + if (sender is System.Windows.Controls.ComboBox) + { + System.Windows.Controls.ComboBox toggle = (System.Windows.Controls.ComboBox)sender; + Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyGridCommand = toggle.DataContext as Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem; + if (toggle.Tag != null) + propertyGridCommand.Value = "{" + $"Binding {toggle.Tag}.{toggle.Text}" + "}"; + else + propertyGridCommand.Value = "{" + $"Binding {toggle.Tag}." + "}"; + } + } + catch (Exception ex) + { + + } + } + private void valuebox_DropDownOpened(object sender,EventArgs e) + { + try + { + viewModel.DevValueList = new System.Collections.ObjectModel.ObservableCollection(); + + if (sender is System.Windows.Controls.ComboBox) + { + System.Windows.Controls.ComboBox toggle = (System.Windows.Controls.ComboBox)sender; + if (toggle.Tag == null) return; + if (Class_DataBus.GetInstance().Dic_DeviceData.ContainsKey(toggle.Tag.ToString())) + { + Class_DataBus.GetInstance().Dic_DeviceData[toggle.Tag.ToString()].Keys?.ToList().ForEach(key => { viewModel.DevValueList.Add(key); }); + } + } + } + catch (Exception ex) + { + + } + + } + /// + /// 设备名称选择 + /// + /// + /// + private void ComboBoxName_TextChanged(object sender,TextChangedEventArgs e) + { + try + { + if (sender is System.Windows.Controls.ComboBox) + { + System.Windows.Controls.ComboBox toggle = (System.Windows.Controls.ComboBox)sender; + Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyGridCommand = toggle.DataContext as Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem; + if(toggle.Tag!=null) + propertyGridCommand.Value = "{" + $"Binding {toggle.Text}.{toggle.Tag}" + "}"; + else + propertyGridCommand.Value = "{" + $"Binding {toggle.Text}." + "}"; + + } + } + catch (Exception ex) + { + + } + } + + + private void namebox_DropDownOpened(object sender,EventArgs e) + { + viewModel.DevNameList = new System.Collections.ObjectModel.ObservableCollection(); + Class_DataBus.GetInstance().Dic_DeviceData.Keys?.ToList().ForEach(key => { viewModel.DevNameList.Add(key); }); + } + #endregion + + + } + + +} diff --git a/BeDesignerSCADA/Speical/ControlTypeAttribute.cs b/BeDesignerSCADA/Speical/ControlTypeAttribute.cs new file mode 100644 index 00000000..e27b9bbe --- /dev/null +++ b/BeDesignerSCADA/Speical/ControlTypeAttribute.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeDesignerSCADA.Speical +{ + [AttributeUsage(AttributeTargets.Class)] + public class ControlTypeAttribute : Attribute + { + public string Group { get; set; } + } +} diff --git a/BeDesignerSCADA/Speical/ItemsList.cs b/BeDesignerSCADA/Speical/ItemsList.cs new file mode 100644 index 00000000..9b6d143d --- /dev/null +++ b/BeDesignerSCADA/Speical/ItemsList.cs @@ -0,0 +1,37 @@ +using Microsoft.Toolkit.Mvvm.Input; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeDesignerSCADA.Speical +{ + /// + /// 因ObservableCollection无法序列化,继承并实例化一个 + /// + public class ItemsList : ObservableCollection + { + public ItemsList() + { + AddCommand = new RelayCommand(AddItem); + DeleteCommand = new RelayCommand(DeleteItem); + } + + private void DeleteItem(string obj) + { + if (!string.IsNullOrEmpty(obj)) + Remove(obj); + } + + public RelayCommand AddCommand { get; } + public RelayCommand DeleteCommand { get; } + private void AddItem(string txt) + { + if (!string.IsNullOrEmpty(txt)) + Add(txt); + } + + } +} diff --git a/BeDesignerSCADA/Themes/Styles.xaml b/BeDesignerSCADA/Themes/Styles.xaml new file mode 100644 index 00000000..3b41d9d1 --- /dev/null +++ b/BeDesignerSCADA/Themes/Styles.xaml @@ -0,0 +1,686 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +