@@ -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<double>() { 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<CanvasPanel>(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<CanvasPanel>(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<CanvasPanel>(AdornedElement)); | |||
double offsetX = nowPoint.X - lastPoint.X; | |||
double offsetY = nowPoint.Y - lastPoint.Y; | |||
lastPoint = nowPoint; | |||
tempX += offsetX; | |||
tempY += offsetY; | |||
var canvas = CanvasPanel.GetParentObject<CanvasPanel>(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<CanvasPanel>(AdornedElement)); | |||
int offsetX = (int)(nowPoint.X - lastPoint.X); | |||
int offsetY = (int)(nowPoint.Y - lastPoint.Y); | |||
CanvasPanel.GetParentObject<CanvasPanel>(AdornedElement).ZoomControls(offsetX, offsetY); | |||
lastPoint = nowPoint; | |||
} | |||
} | |||
private void SelectionAdorner_MouseDown(object sender, MouseButtonEventArgs e) | |||
{ | |||
var canv = CanvasPanel.GetParentObject<CanvasPanel>(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(); | |||
// } | |||
//} | |||
} | |||
} | |||
} |
@@ -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<double>() { 4, 2 }, 2); | |||
drawingContext.DrawLine(render, startPoint, endPoint); | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<Application x:Class="BeDesignerSCADA.App" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:local="clr-namespace:BeDesignerSCADA" | |||
StartupUri="MainWindow.xaml"> | |||
<Application.Resources> | |||
</Application.Resources> | |||
</Application> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// Interaction logic for App.xaml | |||
/// </summary> | |||
public partial class App : Application | |||
{ | |||
} | |||
} |
@@ -0,0 +1,112 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<OutputType>WinExe</OutputType> | |||
<TargetFramework>net6.0-windows</TargetFramework> | |||
<Nullable>enable</Nullable> | |||
<UseWPF>true</UseWPF> | |||
<ApplicationIcon>Images\fyf.ico</ApplicationIcon> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Compile Remove="ArcGauge.cs" /> | |||
<Compile Remove="AssemblyInfo.cs" /> | |||
<Compile Remove="DigitalNumber.cs" /> | |||
<Compile Remove="GraphArrow.xaml.cs" /> | |||
<Compile Remove="GraphStar.xaml.cs" /> | |||
<Compile Remove="Helper\Config.cs" /> | |||
<Compile Remove="KnobButton.cs" /> | |||
<Compile Remove="NumberBox.cs" /> | |||
<Compile Remove="StatusLight.cs" /> | |||
<Compile Remove="SwitchButton.cs" /> | |||
<Compile Remove="TheButton.xaml.cs" /> | |||
<Compile Remove="TheCheckBox.xaml.cs" /> | |||
<Compile Remove="TheComboBox.xaml.cs" /> | |||
<Compile Remove="TheGroupBox.xaml.cs" /> | |||
<Compile Remove="TheImage.xaml.cs" /> | |||
<Compile Remove="TheRadioButton.cs" /> | |||
<Compile Remove="TheSlider.cs" /> | |||
<Compile Remove="TheTextBlock.xaml.cs" /> | |||
<Compile Remove="TheTextBox.cs" /> | |||
<Compile Remove="TheTimer.cs" /> | |||
<Compile Remove="TheToggleButton.xaml.cs" /> | |||
<Compile Remove="WaveProgressBar.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Remove="Fonts\ds-digib.ttf" /> | |||
<None Remove="Images\bj.png" /> | |||
<None Remove="Images\fyf.ico" /> | |||
<None Remove="Images\gaugeMask.png" /> | |||
<None Remove="Images\hbl.ico" /> | |||
<None Remove="Images\ico.ico" /> | |||
<None Remove="Images\redis.png" /> | |||
<None Remove="Images\State0.png" /> | |||
<None Remove="Images\State1.png" /> | |||
<None Remove="Images\State11.png" /> | |||
<None Remove="Images\State2.png" /> | |||
<None Remove="Images\timericon.png" /> | |||
<None Remove="Images\win.png" /> | |||
<None Remove="Images\wx.jpg" /> | |||
<None Remove="Images\zfb.jpg" /> | |||
<None Remove="Images\光柱.png" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Content Include="Images\fyf.ico" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="AvalonEdit" Version="6.1.3.50" /> | |||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.4.0" /> | |||
<PackageReference Include="MahApps.Metro.IconPacks" Version="4.11.0" /> | |||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" /> | |||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.0" /> | |||
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" /> | |||
<PackageReference Include="MQTTnet" Version="3.1.2" /> | |||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> | |||
<PackageReference Include="StackExchange.Redis" Version="2.6.66" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="Antlr3.Runtime"> | |||
<HintPath>DLL\Antlr3.Runtime.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Unvell.ReoScript"> | |||
<HintPath>DLL\Unvell.ReoScript.dll</HintPath> | |||
</Reference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Resource Include="Fonts\ds-digib.ttf" /> | |||
<Resource Include="Images\bj.png" /> | |||
<Resource Include="Images\fyf.ico" /> | |||
<Resource Include="Images\gaugeMask.png" /> | |||
<Resource Include="Images\hbl.ico" /> | |||
<Resource Include="Images\ico.ico" /> | |||
<Resource Include="Images\redis.png" /> | |||
<Resource Include="Images\State0.png" /> | |||
<Resource Include="Images\State1.png" /> | |||
<Resource Include="Images\State11.png" /> | |||
<Resource Include="Images\State2.png" /> | |||
<Resource Include="Images\timericon.png" /> | |||
<Resource Include="Images\win.png" /> | |||
<Resource Include="Images\wx.jpg" /> | |||
<Resource Include="Images\zfb.jpg" /> | |||
<Resource Include="Images\光柱.png" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="Helper\" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmart.Model\BPASmart.Model.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.Compiler\BPASmartClient.Compiler.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.DATABUS\BPASmartClient.DATABUS.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.MessageName\BPASmartClient.MessageName.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.SCADAControl\BPASmartClient.SCADAControl.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -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 |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// 编辑脚本时获取控件属性 | |||
/// </summary> | |||
public class PropertyHelper | |||
{ | |||
public static string[] ableProperties = new string[] | |||
{ "IsChecked", "Value", "CurValue", "StatusValue", "NumberValue", "Text", | |||
"Direction","RefreshData","ChangedText","Content" | |||
}; | |||
public static List<ControlName> GetCustomerControlProperty(List<FrameworkElement> selectItems) | |||
{ | |||
List<ControlName> result = new List<ControlName>(); | |||
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<ControlName> Properties { get; set; } | |||
} | |||
} |
@@ -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<FrameworkElement>(); | |||
//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<FrameworkElement>() { control }; | |||
SelectedItem = control; | |||
} | |||
catch (Exception) | |||
{ | |||
} | |||
} | |||
string GetControlName(Type ctrlType) | |||
{ | |||
var children = Children.GetEnumerator(); | |||
children.Reset(); | |||
List<string> names = new List<string>(); | |||
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 单击选中项处理 | |||
/// <summary> | |||
/// 单击了控件时:不调用框选的刷新方式 | |||
/// </summary> | |||
bool isClickedControl = false; | |||
/// <summary> | |||
/// 左键按下 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void Ctrl_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) | |||
{ | |||
if (sender is FrameworkElement ctl) | |||
{ | |||
var cp = GetParentObject<CanvasPanel>(ctl); | |||
if (Keyboard.Modifiers == ModifierKeys.Control) | |||
{ | |||
cp.SelectedItems.Add(ctl); | |||
} | |||
else | |||
{ | |||
cp.SelectedItems = new ObservableCollection<FrameworkElement>() { ctl }; | |||
} | |||
isClickedControl = true; | |||
RefreshSelection(); | |||
} | |||
} | |||
/// <summary> | |||
/// 获取属性 | |||
/// </summary> | |||
/// <typeparam name="T"></typeparam> | |||
/// <param name="obj"></param> | |||
/// <returns></returns> | |||
public static T GetParentObject<T>(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<FrameworkElement> SelectedItems | |||
{ | |||
get { return (ObservableCollection<FrameworkElement>)GetValue(SelectedItemsProperty); } | |||
set { SetValue(SelectedItemsProperty, value); } | |||
} | |||
public static readonly DependencyProperty SelectedItemsProperty = | |||
DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<FrameworkElement>), 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; | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 移除所有选择装饰器 | |||
/// </summary> | |||
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]); | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 计算框选项 | |||
/// </summary> | |||
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<FrameworkElement>(); | |||
return; | |||
} | |||
SelectedItems = new ObservableCollection<FrameworkElement>(); | |||
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<FrameworkElement> GetAllExecChildren() | |||
{ | |||
List<FrameworkElement> result = new List<FrameworkElement>(); | |||
foreach (var ctrl in Children) | |||
{ | |||
if (ctrl is IExecutable exec) | |||
{ | |||
result.Add(ctrl as FrameworkElement); | |||
} | |||
} | |||
return result; | |||
} | |||
/// <summary> | |||
/// 对齐像素单位 | |||
/// </summary> | |||
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<Point> points = new List<Point>(); | |||
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); | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 清除绘制的对齐线 | |||
/// </summary> | |||
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 对齐操作 | |||
/// <summary> | |||
/// 是否使用网格对齐 10px | |||
/// </summary> | |||
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<FrameworkElement> copyTemp = new List<FrameworkElement>(); | |||
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; | |||
} | |||
} | |||
/// <summary> | |||
/// 复制 | |||
/// </summary> | |||
public void CopySelectItems() | |||
{ | |||
copyTemp.Clear(); | |||
foreach (var item in SelectedItems) | |||
{ | |||
copyTemp.Add(item); | |||
} | |||
} | |||
/// <summary> | |||
/// 粘贴 | |||
/// </summary> | |||
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(); | |||
} | |||
/// <summary> | |||
/// 置于顶层 | |||
/// </summary> | |||
public void SetTopLayer() | |||
{ | |||
if (SelectedItems.Count == 0) | |||
return; | |||
foreach (var item in SelectedItems) | |||
{ | |||
Children.Remove(item); | |||
} | |||
foreach (var item in SelectedItems) | |||
{ | |||
Children.Add(item); | |||
} | |||
} | |||
/// <summary> | |||
/// 置于底层 | |||
/// </summary> | |||
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); | |||
} | |||
} | |||
/// <summary> | |||
/// 删除 | |||
/// </summary> | |||
public void DeleteSelectItems() | |||
{ | |||
foreach (var item in SelectedItems) | |||
{ | |||
Children.Remove(item); | |||
} | |||
SelectedItems.Clear(); | |||
RefreshSelection(); | |||
} | |||
#endregion | |||
#region 运行Xaml 保存 读取 | |||
public List<FrameworkElement> Generator() | |||
{ | |||
List<FrameworkElement> elements = new List<FrameworkElement>(); | |||
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; | |||
} | |||
/// <summary> | |||
/// 保存数据到文本 | |||
/// </summary> | |||
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(); | |||
} | |||
/// <summary> | |||
/// 读取文件 | |||
/// </summary> | |||
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 | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
<UserControl x:Class="BeDesignerSCADA.Controls.RunCanvas" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.Controls" | |||
xmlns:con="clr-namespace:BeDesignerSCADA.Converters" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
<UserControl.Resources> | |||
<con:ZoomConverter x:Key="ZoomX" IsHeight="False"/> | |||
<con:ZoomConverter x:Key="ZoomY" IsHeight="True"/> | |||
</UserControl.Resources> | |||
<Grid ClipToBounds="True"> | |||
<Canvas x:Name="RootCanvas" ClipToBounds="True" Background="Transparent" MouseLeftButtonUp="RootCanvas_MouseLeftButtonUp" | |||
MouseMove="RootCanvas_MouseMove" MouseLeftButtonDown="RootCanvas_MouseLeftButtoDown" MouseWheel="RootCanvas_MouseWheel"> | |||
<Canvas.RenderTransform> | |||
<TransformGroup> | |||
<ScaleTransform x:Name="Scale"/> | |||
<TranslateTransform x:Name="Translate"/> | |||
</TransformGroup> | |||
</Canvas.RenderTransform> | |||
</Canvas> | |||
<Grid VerticalAlignment="Bottom" Background="#4B959595"> | |||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="8 0"> | |||
<CheckBox x:Name="DragEnable" Content="拖动" Margin="4"/> | |||
<CheckBox x:Name="ZoomEnable" Content="缩放" Margin="4"/> | |||
</StackPanel> | |||
</Grid> | |||
</Grid> | |||
</UserControl> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// RunCanvas.xaml 的交互逻辑 | |||
/// </summary> | |||
public partial class RunCanvas : UserControl | |||
{ | |||
public RunCanvas() | |||
{ | |||
InitializeComponent(); | |||
Unloaded += (s, e) => Destory(); | |||
} | |||
/// <summary> | |||
/// Dispose子集 | |||
/// </summary> | |||
public void Destory() | |||
{ | |||
foreach (var item in RootCanvas.Children) | |||
{ | |||
if (item is IDisposable disposable) | |||
{ | |||
disposable.Dispose(); | |||
} | |||
} | |||
} | |||
public void Run(List<FrameworkElement> 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 | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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<TextBlock> textLabels = new List<TextBlock>(); | |||
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(); | |||
} | |||
} | |||
} |
@@ -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() | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
<UserControl x:Class="BeDesignerSCADA.CustomerControls.GraphArrow" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
x:Name="root" | |||
d:DesignHeight="44" d:DesignWidth="60" Foreground="#22DCF7"> | |||
<Grid> | |||
<Path Data="M571.5,161.75L629,161.75 629,147.5 657.5,176 629,204.5 629,190.25 571.5,190.25z" | |||
Stretch="Fill" Fill="{Binding ElementName=root,Path=Foreground}"/> | |||
</Grid> | |||
</UserControl> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// GraphArrow.xaml 的交互逻辑 | |||
/// </summary> | |||
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() | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
<UserControl x:Class="BeDesignerSCADA.CustomerControls.GraphStar" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
x:Name="root" | |||
d:DesignHeight="1056" d:DesignWidth="1094" Foreground="#78C94F"> | |||
<Grid> | |||
<Path Data="M132.5,205.601L206.22,205.602 229,131.5 251.78,205.602 325.5,205.601 265.859,251.398 288.64,325.5 229,279.702 169.36,325.5 192.141,251.398z" | |||
Fill="{Binding ElementName=root,Path=Foreground}" Stretch="Fill"/> | |||
</Grid> | |||
</UserControl> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// GraphStar.xaml 的交互逻辑 | |||
/// </summary> | |||
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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
/// <summary> | |||
/// 注册需要处理的事件 | |||
/// </summary> | |||
public void Register() | |||
{ | |||
ValueChanged += KnobButton_ValueChanged; ; | |||
} | |||
private void KnobButton_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> 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(); | |||
} | |||
} | |||
} |
@@ -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<Key> _controlKeys = new List<Key> | |||
{ | |||
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'); | |||
} | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 状态值 | |||
/// </summary> | |||
[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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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))); | |||
} | |||
/// <summary> | |||
/// 不勾选时执行代码 | |||
/// </summary> | |||
[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)); | |||
/// <summary> | |||
/// 勾选时执行代码 | |||
/// </summary> | |||
[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 => "控件"; | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<Button x:Class="BeDesignerSCADA.CustomerControls.TheButton" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</Button> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheButton.xaml 的交互逻辑 | |||
/// </summary> | |||
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)); | |||
/// <summary> | |||
/// 注册需要处理的事件 | |||
/// </summary> | |||
public void Register() | |||
{ | |||
this.Click += MyButton_Click; | |||
} | |||
private void MyButton_Click(object sender, RoutedEventArgs e) | |||
{ | |||
Config.GetInstance().RunJsScipt(ClickExec); | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<CheckBox x:Class="BeDesignerSCADA.CustomerControls.TheCheckBox" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</CheckBox> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheCheckBox.xaml 的交互逻辑 | |||
/// </summary> | |||
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(); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 不勾选时执行代码 | |||
/// </summary> | |||
[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)); | |||
/// <summary> | |||
/// 勾选时执行代码 | |||
/// </summary> | |||
[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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<ComboBox x:Class="BeDesignerSCADA.CustomerControls.TheComboBox" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</ComboBox> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheComboBox.xaml 的交互逻辑 | |||
/// </summary> | |||
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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<GroupBox x:Class="BeDesignerSCADA.CustomerControls.TheGroupBox" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</GroupBox> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheGroupBox.xaml 的交互逻辑 | |||
/// </summary> | |||
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(); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 注册需要处理的事件 | |||
/// </summary> | |||
public void Register() | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<Image x:Class="BeDesignerSCADA.CustomerControls.TheImage" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</Image> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheImage.xaml 的交互逻辑 | |||
/// </summary> | |||
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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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<double> e) | |||
{ | |||
Config.GetInstance().RunJsScipt(ValueChangedExecute); | |||
} | |||
public void Dispose() | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<TextBlock x:Class="BeDesignerSCADA.CustomerControls.TheTextBlock" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</TextBlock> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheTextBlock.xaml 的交互逻辑 | |||
/// </summary> | |||
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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
/// <summary> | |||
/// 时间间隔 | |||
/// </summary> | |||
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)); | |||
/// <summary> | |||
/// 执行内容 | |||
/// </summary> | |||
[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)); | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<ToggleButton x:Class="BeDesignerSCADA.CustomerControls.TheToggleButton" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.CustomerControls" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
</ToggleButton> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// TheToggleButton.xaml 的交互逻辑 | |||
/// </summary> | |||
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(); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 不勾选时执行代码 | |||
/// </summary> | |||
[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)); | |||
/// <summary> | |||
/// 勾选时执行代码 | |||
/// </summary> | |||
[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); | |||
} | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// 波浪进度条 | |||
/// </summary> | |||
[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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
/// <summary> | |||
/// 运行脚本 | |||
/// </summary> | |||
/// <param name="script"></param> | |||
public static void RunJsScipt(string script) | |||
{ | |||
try | |||
{ | |||
srm.Run(script); | |||
} | |||
catch (Exception e) | |||
{ | |||
MessageBox.Show(e.Message, "脚本错误"); | |||
} | |||
} | |||
/// <summary> | |||
/// 注册对象到js | |||
/// </summary> | |||
public static void SetVariable(string name, object obj) | |||
{ | |||
srm.SetGlobalVariable(name, obj); | |||
} | |||
/// <summary> | |||
/// 注册方法到Js | |||
/// </summary> | |||
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; | |||
}); | |||
} | |||
} | |||
} |
@@ -0,0 +1,296 @@ | |||
<Window x:Name="window" x:Class="BeDesignerSCADA.MainWindow" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:local="clr-namespace:BeDesignerSCADA" | |||
xmlns:s="clr-namespace:BeDesignerSCADA.Converters" | |||
xmlns:icon="http://metro.mahapps.com/winfx/xaml/iconpacks" | |||
xmlns:avae="http://icsharpcode.net/sharpdevelop/avalonedit" | |||
xmlns:ctl="clr-namespace:BeDesignerSCADA.Controls" | |||
xmlns:mypro="http://schemas.xceed.com/wpf/xaml/toolkit" | |||
mc:Ignorable="d" | |||
WindowStartupLocation="CenterScreen" | |||
Title="黑菠萝科技-[组态软件1.0]" Height="900" Width="1400" Icon="/Images/ico.ico" > | |||
<Window.Resources> | |||
<ResourceDictionary> | |||
<ResourceDictionary.MergedDictionaries> | |||
<ResourceDictionary Source="/BeDesignerSCADA;component/Themes/Styles.xaml" /> | |||
<ResourceDictionary Source="/BPASmartClient.SCADAControl;component/Themes/Generic.xaml" /> | |||
</ResourceDictionary.MergedDictionaries> | |||
</ResourceDictionary> | |||
</Window.Resources> | |||
<Grid x:Name="grid"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="240"/> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="350"/> | |||
</Grid.ColumnDefinitions> | |||
<!--<icon:PackIconMaterial x:Name="icon" Kind="LineScan" BorderThickness="1" VerticalAlignment="Stretch" Width="24" HorizontalAlignment="Stretch"/>--> | |||
<!--左侧控件栏--> | |||
<Border BorderThickness="1" BorderBrush="{StaticResource AccentBrush}" Margin="4"> | |||
<ListBox x:Name="CtlList" Background="Transparent" ItemTemplate="{DynamicResource ToolBoxStyle}" BorderThickness="0" PreviewMouseMove="CtlList_PreviewMouseMove"> | |||
</ListBox> | |||
</Border> | |||
<!--中间控制区域--> | |||
<DockPanel Grid.Column="1"> | |||
<!--按钮控制--> | |||
<DockPanel LastChildFill="False" DockPanel.Dock="Top" Height="24" Margin="4 4 4 0"> | |||
<Button Margin="0" Width="24" Padding="0" Click="AglinLeftBtn_Click" ToolTip="左对齐"> | |||
<icon:PackIconModern Kind="AlignLeft"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" Click="AglinRightBtn_Click" ToolTip="右对齐"> | |||
<icon:PackIconModern Kind="AlignRight"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" Click="AglinCenterBtn_Click" ToolTip="中心对齐"> | |||
<icon:PackIconModern Kind="AlignCenter"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" Click="AglinTopBtn_Click" ToolTip="上对齐"> | |||
<icon:PackIconModern Kind="BorderTop"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" Click="AglinBottomBtn_Click" ToolTip="下对齐"> | |||
<icon:PackIconModern Kind="BorderBottom"/> | |||
</Button> | |||
<Button Margin="16 0 0 0" Width="24" Padding="0" Click="HorizontalLayoutBtn_Click" ToolTip="水平分布"> | |||
<icon:PackIconModern Kind="BorderHorizontal"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" Click="VerticalLayoutBtn_Click" ToolTip="垂直分布"> | |||
<icon:PackIconModern Kind="BorderVertical"/> | |||
</Button> | |||
<ToggleButton IsChecked="{Binding UseAutoAlignment, ElementName=cav, Mode=TwoWay}" ToolTip="使用对齐网格" Margin="4 0 0 0" Width="24" Padding="0"> | |||
<icon:PackIconModern Kind="CellAlign"/> | |||
</ToggleButton> | |||
<Button Margin="16 0 0 0" Width="24" Padding="0" ToolTip="复制" Command="{Binding ElementName=cav, Path=CopySelectItemsCommand}"> | |||
<icon:PackIconModern Kind="PageCopy"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" ToolTip="粘贴" Command="{Binding ElementName=cav, Path=PasteSelectItemsCommand}"> | |||
<icon:PackIconModern Kind="ClipboardPaste"/> | |||
</Button> | |||
<Button Margin="4 0 0 0" Width="24" Padding="0" ToolTip="删除" Command="{Binding ElementName=cav, Path=DeleteSelectItemsCommand}"> | |||
<icon:PackIconModern Kind="Delete"/> | |||
</Button> | |||
<Button x:Name="RunBtn" Margin="16 0 0 0" Padding="0" Click="RunBtn_Click" Command="{Binding RunUiCommand}"> | |||
<Button.Style> | |||
<Style TargetType="Button"> | |||
<Setter Property="Tag" Value="运行"/> | |||
<Setter Property="Content"> | |||
<Setter.Value> | |||
<StackPanel Orientation="Horizontal" Margin="8 0"> | |||
<icon:PackIconModern Kind="ControlPlay" VerticalAlignment="Center" Foreground="#28B60F" Width="8"/> | |||
<TextBlock Text="运行" Margin="4 0" VerticalAlignment="Center"/> | |||
</StackPanel> | |||
</Setter.Value> | |||
</Setter> | |||
<Style.Triggers> | |||
<DataTrigger Binding="{Binding IsRunning}" Value="True"> | |||
<Setter Property="Tag" Value="停止"/> | |||
<Setter Property="Content"> | |||
<Setter.Value> | |||
<StackPanel Orientation="Horizontal" Margin="8 0"> | |||
<icon:PackIconModern Kind="ControlStop" VerticalAlignment="Center" Foreground="#B60F0F" Width="8"/> | |||
<TextBlock Text="停止" Margin="4 0" VerticalAlignment="Center"/> | |||
</StackPanel> | |||
</Setter.Value> | |||
</Setter> | |||
</DataTrigger> | |||
</Style.Triggers> | |||
</Style> | |||
</Button.Style> | |||
</Button> | |||
<Button x:Name="SaveBtn" Margin="16 0 0 0" Padding="0" Click="SaveBtn_Click"> | |||
<StackPanel Orientation="Horizontal" Margin="8 0"> | |||
<icon:PackIconModern Kind="Save" VerticalAlignment="Center" Width="12"/> | |||
<TextBlock Text="保存" Margin="4 0" VerticalAlignment="Center"/> | |||
</StackPanel> | |||
</Button> | |||
<Button x:Name="LoadBtn" Margin="4 0 0 0" Padding="0" Click="LoadBtn_Click"> | |||
<StackPanel Orientation="Horizontal" Margin="8 0"> | |||
<icon:PackIconModern Kind="DiskDownload" VerticalAlignment="Center" Width="14"/> | |||
<TextBlock Text="加载" Margin="4 0" VerticalAlignment="Center"/> | |||
</StackPanel> | |||
</Button> | |||
<Button x:Name="MNBtn" Margin="4 0 0 0" Padding="0" Click="MNBtn_Click"> | |||
<StackPanel Orientation="Horizontal" Margin="8 0"> | |||
<icon:PackIconModern Kind="MessageSend" VerticalAlignment="Center" Width="14"/> | |||
<TextBlock Text="模拟消息" Margin="4 0" VerticalAlignment="Center"/> | |||
</StackPanel> | |||
</Button> | |||
<ToggleButton x:Name="showCode" Click="showCode_Click" DockPanel.Dock="Right" Margin="4 0 0 0" Padding="4 0"> | |||
<icon:Material Kind="FileCode"/> | |||
</ToggleButton> | |||
<Slider DockPanel.Dock="Right" Width="100" Maximum="16" Minimum="1" Margin="4 0 0 0" | |||
HorizontalContentAlignment="Center" Value="{Binding ElementName=cav,Path=GridPxiel}" ></Slider> | |||
<TextBlock DockPanel.Dock="Right" Text="对齐:" VerticalAlignment="Center" Margin="16 0 0 0"/> | |||
</DockPanel> | |||
<!--中间画布--> | |||
<Border BorderThickness="1" BorderBrush="{StaticResource AccentBrush}" Margin="4"> | |||
<Border.Background> | |||
<ImageBrush ImageSource="/Images/bj.png" Stretch="UniformToFill"/> | |||
</Border.Background> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="auto"/> | |||
</Grid.ColumnDefinitions> | |||
<ctl:CanvasPanel x:Name="cav" Visibility="{Binding CanvasPanelVisibility}" SelectedItem="{Binding CanSelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" AllowDrop="True" RenderTransformOrigin="0.5,0.5" ClipToBounds="True" UseLayoutRounding="True" Focusable="True" SnapsToDevicePixels="True"> | |||
<ctl:CanvasPanel.Background> | |||
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute"> | |||
<VisualBrush.Visual> | |||
<Rectangle Width="20" Height="20" StrokeDashArray="4,2" StrokeThickness="0.5" Stroke="#CBCBCB"> | |||
<Rectangle.Style> | |||
<Style TargetType="{x:Type Rectangle}"> | |||
<Style.Triggers> | |||
<DataTrigger Binding="{Binding UseAutoAlignment, RelativeSource={RelativeSource AncestorType={x:Type ctl:CanvasPanel}, Mode=FindAncestor}}" Value="True"> | |||
<Setter Property="Visibility" Value="Visible"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding UseAutoAlignment, RelativeSource={RelativeSource AncestorType={x:Type ctl:CanvasPanel}, Mode=FindAncestor}}" Value="False"> | |||
<Setter Property="Visibility" Value="Collapsed"/> | |||
</DataTrigger> | |||
</Style.Triggers> | |||
</Style> | |||
</Rectangle.Style> | |||
</Rectangle> | |||
</VisualBrush.Visual> | |||
</VisualBrush> | |||
</ctl:CanvasPanel.Background> | |||
<ctl:CanvasPanel.RenderTransform> | |||
<TransformGroup> | |||
<TranslateTransform x:Name="CanvasTranslate"/> | |||
</TransformGroup> | |||
</ctl:CanvasPanel.RenderTransform> | |||
</ctl:CanvasPanel> | |||
<ctl:RunCanvas x:Name="runCanvas" Visibility="{Binding RunCanvasVisibility}" > | |||
</ctl:RunCanvas> | |||
<avae:TextEditor x:Name="codeEditor" ShowLineNumbers="True" Padding="4" WordWrap="True" IsReadOnly="True" SyntaxHighlighting="XML" BorderThickness="1 0 0 0" BorderBrush="{StaticResource ControlBorderBrush}" Grid.Column="1" Width="480" Visibility="{Binding ElementName=showCode, Path=IsChecked, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"/> | |||
</Grid> | |||
</Border> | |||
</DockPanel> | |||
<GridSplitter HorizontalAlignment="Right" Grid.Column="1" VerticalAlignment="Stretch" Width="5" Background="Transparent"/> | |||
<!--右侧属性栏--> | |||
<Grid Grid.Column="2"> | |||
<TabControl SelectedIndex="0"> | |||
<TabItem Header="控制协议"> | |||
<mypro:PropertyGrid x:Name="kzxy" SelectedObject="{Binding PropeObject}" | |||
Margin="10" ShowAdvancedOptions="True" ShowDescriptionByTooltip="True" | |||
FontSize="14" ShowTitle="False" ShowSortOptions="False" ShowSearchBox="False" | |||
CategoryGroupHeaderTemplate="{DynamicResource Category}"> | |||
<mypro:PropertyGrid.EditorDefinitions> | |||
<!--EditorTemplateDefinition可添加多个--> | |||
<!--要修改编辑模板的属性的名称--> | |||
<mypro:EditorTemplateDefinition TargetProperties="点击事件,值改变事件,定时触发,勾选事件,取消勾选事件" > | |||
<mypro:EditorTemplateDefinition.EditingTemplate> | |||
<DataTemplate> | |||
<!--此处可自由发挥--> | |||
<Grid> | |||
<!-- Command生效: DataTemplate的DataContext指代不明确,需要改为父类的DataContext。 参数Value表示原对象--> | |||
<!--Command="{Binding Path=DataContext.PropeSetCommand ,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=xctk:PropertyGrid}}"--> | |||
<!--DataContext="{Binding DataContext, ElementName=window}" Command="{Binding PropeSetCommand}" CommandParameter="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"--> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="*" x:Name="key"/> | |||
<ColumnDefinition Width="35"/> | |||
</Grid.ColumnDefinitions> | |||
<TextBox Width="{Binding Width, ElementName=key}" Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap"></TextBox> | |||
<ToggleButton Grid.Column="1" Height="25" Content="编辑" Width="30" HorizontalAlignment="Left" Click="ToggleButton_Click"></ToggleButton> | |||
</Grid> | |||
</DataTemplate> | |||
</mypro:EditorTemplateDefinition.EditingTemplate> | |||
</mypro:EditorTemplateDefinition> | |||
<mypro:EditorTemplateDefinition TargetProperties="代码过滤脚本" > | |||
<mypro:EditorTemplateDefinition.EditingTemplate> | |||
<DataTemplate> | |||
<!--此处可自由发挥--> | |||
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> | |||
<TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" TextWrapping="Wrap"></TextBox> | |||
</ScrollViewer> | |||
</DataTemplate> | |||
</mypro:EditorTemplateDefinition.EditingTemplate> | |||
</mypro:EditorTemplateDefinition> | |||
<mypro:EditorTemplateDefinition TargetProperties="设备解析变量" > | |||
<mypro:EditorTemplateDefinition.EditingTemplate> | |||
<DataTemplate> | |||
<!--此处可自由发挥--> | |||
<Grid> | |||
<ComboBox Grid.Column="1" Height="25" Width="{Binding Width, ElementName=com}" Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" | |||
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},Path=DataContext.DevValueList}" | |||
></ComboBox> | |||
</Grid> | |||
</DataTemplate> | |||
</mypro:EditorTemplateDefinition.EditingTemplate> | |||
</mypro:EditorTemplateDefinition> | |||
<mypro:EditorTemplateDefinition TargetProperties="设备名称" > | |||
<mypro:EditorTemplateDefinition.EditingTemplate> | |||
<DataTemplate> | |||
<!--此处可自由发挥--> | |||
<Grid> | |||
<ComboBox Grid.Column="1" Height="25" Width="{Binding Width, ElementName=com}" Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" | |||
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},Path=DataContext.DevNameList}" | |||
></ComboBox> | |||
</Grid> | |||
</DataTemplate> | |||
</mypro:EditorTemplateDefinition.EditingTemplate> | |||
</mypro:EditorTemplateDefinition> | |||
<mypro:EditorTemplateDefinition TargetProperties="文本,文本1,标题,变量" > | |||
<mypro:EditorTemplateDefinition.EditingTemplate> | |||
<DataTemplate> | |||
<!--此处可自由发挥--> | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<Grid Margin="0,5,0,5"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="40" /> | |||
<ColumnDefinition Width="*" x:Name="key"/> | |||
<ColumnDefinition Width="*" x:Name="Text"/> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock>绑定:</TextBlock> | |||
<ComboBox x:Name="namebox" DropDownOpened="namebox_DropDownOpened" Grid.Column="1" Height="25" IsTextSearchEnabled="True" IsEditable="True" Tag="{Binding Text, ElementName=valuebox}" Width="{Binding Width, ElementName=key}" TextBoxBase.TextChanged="ComboBoxName_TextChanged" | |||
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},Path=DataContext.DevNameList}"> | |||
</ComboBox> | |||
<ComboBox x:Name="valuebox" DropDownOpened="valuebox_DropDownOpened" Grid.Column="2" Height="25" IsTextSearchEnabled="True" IsEditable="True" Tag="{Binding Text, ElementName=namebox}" Width="{Binding Width, ElementName=Text}" TextBoxBase.TextChanged="ComboBoxValue_TextChanged" | |||
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},Path=DataContext.DevValueList}"/> | |||
</Grid> | |||
<TextBox Grid.Row="2" x:Name="wenben" Width="{Binding Width, ElementName=Text}" Padding="5" Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap"></TextBox> | |||
</Grid> | |||
</DataTemplate> | |||
</mypro:EditorTemplateDefinition.EditingTemplate> | |||
</mypro:EditorTemplateDefinition> | |||
</mypro:PropertyGrid.EditorDefinitions> | |||
</mypro:PropertyGrid> | |||
</TabItem> | |||
<TabItem Header="控件样式"> | |||
<mypro:PropertyGrid x:Name="dsdsdsd" | |||
Margin="10" ShowAdvancedOptions="True" ShowDescriptionByTooltip="True" | |||
FontSize="14" ShowTitle="False" ShowSortOptions="False" ShowSearchBox="False" | |||
CategoryGroupHeaderTemplate="{DynamicResource Category}" SelectedObject="{Binding SelectedItem,ElementName=cav,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> | |||
</TabItem> | |||
</TabControl> | |||
</Grid> | |||
</Grid> | |||
</Window> |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// Interaction logic for MainWindow.xaml | |||
/// </summary> | |||
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> { 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> { aLLModel }; | |||
// } | |||
// } | |||
// } | |||
//} | |||
//catch (Exception ex) | |||
//{ | |||
// System.Windows.MessageBox.Show(ex.Message); | |||
//} | |||
} | |||
/// <summary> | |||
/// 加载本地文件 | |||
/// </summary> | |||
public void LoadFile() | |||
{ | |||
//加载配置数据 | |||
FJson<CommunicationPar>.Read(); | |||
viewModel.DevNameList = new System.Collections.ObjectModel.ObservableCollection<string>(); | |||
viewModel.DevValueList = new System.Collections.ObjectModel.ObservableCollection<string>(); | |||
FJson<CommunicationPar>.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<CommunicationPar>.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 位置调整 | |||
/// <summary> | |||
/// 左对齐 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void AglinLeftBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.AlignLeft(); | |||
} | |||
/// <summary> | |||
/// 底部对齐 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void AglinBottomBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.AlignBottom(); | |||
} | |||
/// <summary> | |||
/// 顶部对齐 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void AglinTopBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.AlignTop(); | |||
} | |||
/// <summary> | |||
/// 右对齐 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void AglinRightBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.AlignRight(); | |||
} | |||
/// <summary> | |||
/// 居中 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void AglinCenterBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.AlignCenter(); | |||
} | |||
/// <summary> | |||
/// 垂直分布 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void VerticalLayoutBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.VertialLayout(); | |||
} | |||
/// <summary> | |||
/// 水平分布 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void HorizontalLayoutBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
cav.HorizontalLayout(); | |||
} | |||
#endregion | |||
#region 其他事件操作 | |||
/// <summary> | |||
/// 运行 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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(); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 加载 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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); | |||
} | |||
/// <summary> | |||
/// 保存 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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); | |||
} | |||
} | |||
/// <summary> | |||
/// 模拟消息发送 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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(); | |||
} | |||
} | |||
/// <summary> | |||
/// 显示代码 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void showCode_Click(object sender, RoutedEventArgs e) | |||
{ | |||
codeEditor.Text = cav.Save(); | |||
} | |||
/// <summary> | |||
/// 编辑 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 变量编辑 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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<string>(); | |||
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) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 设备名称选择 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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<string>(); | |||
Class_DataBus.GetInstance().Dic_DeviceData.Keys?.ToList().ForEach(key => { viewModel.DevNameList.Add(key); }); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// 因ObservableCollection无法序列化,继承并实例化一个 | |||
/// </summary> | |||
public class ItemsList : ObservableCollection<string> | |||
{ | |||
public ItemsList() | |||
{ | |||
AddCommand = new RelayCommand<string>(AddItem); | |||
DeleteCommand = new RelayCommand<string>(DeleteItem); | |||
} | |||
private void DeleteItem(string obj) | |||
{ | |||
if (!string.IsNullOrEmpty(obj)) | |||
Remove(obj); | |||
} | |||
public RelayCommand<string> AddCommand { get; } | |||
public RelayCommand<string> DeleteCommand { get; } | |||
private void AddItem(string txt) | |||
{ | |||
if (!string.IsNullOrEmpty(txt)) | |||
Add(txt); | |||
} | |||
} | |||
} |
@@ -0,0 +1,686 @@ | |||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:icon="http://metro.mahapps.com/winfx/xaml/iconpacks" | |||
xmlns:con="clr-namespace:BeDesignerSCADA.Converters" | |||
xmlns:dxmvmm="clr-namespace:BeDesignerSCADA.Converters" | |||
xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore" | |||
xmlns:ctrl="clr-namespace:BeDesignerSCADA.CustomerControls"> | |||
<!--#region 主题笔刷 --> | |||
<LinearGradientBrush x:Key="NormalBackground" StartPoint="0.5,0" EndPoint="0.5,1"> | |||
<GradientStopCollection> | |||
<GradientStop Color="White" /> | |||
<GradientStop Color="#D0D0D0" Offset="0.5"/> | |||
<GradientStop Color="#E3E3E3" Offset="1"/> | |||
</GradientStopCollection> | |||
</LinearGradientBrush> | |||
<SolidColorBrush x:Key="AccentBrush" Color="#2B79E2"/> | |||
<SolidColorBrush x:Key="ControlBorderBrush" Color="LightGray"/> | |||
<SolidColorBrush x:Key="ControlBackground" Color="White"/> | |||
<SolidColorBrush x:Key="ControlForeground" Color="Black"/> | |||
<!--#endregion--> | |||
<!--#region 转换器 --> | |||
<con:HalfNumberConverter x:Key="HalfNumber"/> | |||
<!--#endregion--> | |||
<!--#region 编辑模板 --> | |||
<DataTemplate x:Key="EventEditTemplate"> | |||
<DockPanel Height="24"> | |||
<Button DockPanel.Dock="Right" Command="{Binding DataContext.EditCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}" | |||
Content="..." CommandParameter="{Binding .}" Margin="2"/> | |||
<TextBlock Text="{Binding Value}" VerticalAlignment="Center" Margin="4 0 0 0"/> | |||
</DockPanel> | |||
</DataTemplate> | |||
<DataTemplate x:Key="ListEditTemplate"> | |||
<DockPanel MaxHeight="100"> | |||
<DockPanel DockPanel.Dock="Top"> | |||
<Button DockPanel.Dock="Right" Command="{Binding Value.AddCommand}" | |||
CommandParameter="{Binding ElementName=AddTxt, Path=Text}" Margin="2" Padding="2"> | |||
<icon:PackIconModern Kind="EditAdd"/> | |||
</Button> | |||
<Button DockPanel.Dock="Right" Command="{Binding Value.DeleteCommand}" | |||
CommandParameter="{Binding ElementName=list, Path=SelectedItem}" Margin="2" Padding="2"> | |||
<icon:PackIconModern Kind="Delete" /> | |||
</Button> | |||
<TextBox x:Name="AddTxt" Margin="2"/> | |||
</DockPanel> | |||
<ListBox x:Name="list" ItemsSource="{Binding Value}" Margin="2"/> | |||
</DockPanel> | |||
</DataTemplate> | |||
<DataTemplate x:Key="ImagePathEditTemplate"> | |||
<DockPanel> | |||
<Button DockPanel.Dock="Right" Content="..." Padding="0" Margin="2" Width="20" Height="20" | |||
Command="{Binding DataContext.SelectPathCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}" CommandParameter="{Binding .}"/> | |||
<TextBox DockPanel.Dock="Right" x:Name="AddTxt" Text="{Binding Value}" BorderThickness="0"/> | |||
</DockPanel> | |||
</DataTemplate> | |||
<!--#endregion--> | |||
<!--#region 为某些获取焦点的控件设计设计时样式 --> | |||
<Style TargetType="ComboBox" x:Key="DesignComboBox"> | |||
<Setter Property="Focusable" Value="False" /> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ComboBox"> | |||
<Border BorderThickness="1" BorderBrush="{StaticResource ControlBorderBrush}"> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="auto"/> | |||
</Grid.ColumnDefinitions> | |||
<Border Background="{StaticResource ControlBackground}"/> | |||
<Border Grid.Column="1" Background="{StaticResource ControlBackground}" BorderThickness="0" IsEnabled="False"> | |||
<Path Data="M0,0 8,0 4,4z" Fill="{StaticResource ControlForeground}" Margin="3" VerticalAlignment="Center"/> | |||
</Border> | |||
</Grid> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<!--<Style TargetType="Button" x:Key="DesignButton"> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="Button"> | |||
<Border BorderThickness="1" BorderBrush="{StaticResource ControlBorderBrush}" Background="{StaticResource ControlBackground}"> | |||
<TextBlock Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}" | |||
FontWeight="{TemplateBinding FontWeight}" HorizontalAlignment="Center" VerticalAlignment="Center"/> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style>--> | |||
<Style TargetType="ToggleButton" x:Key="DesignToggleButton"> | |||
<Setter Property="Foreground" Value="{StaticResource ControlForeground}" /> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ToggleButton"> | |||
<Border BorderThickness="1" Background="{StaticResource NormalBackground}" BorderBrush="{StaticResource ControlBorderBrush}" CornerRadius="2"> | |||
<TextBlock Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}" | |||
FontWeight="{TemplateBinding FontWeight}" HorizontalAlignment="Center" VerticalAlignment="Center"/> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="ToggleButton" x:Key="ExecuteToggleButton"> | |||
<Setter Property="Foreground" Value="{StaticResource ControlForeground}" /> | |||
<Setter Property="Foreground" Value="{StaticResource ControlForeground}" /> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ToggleButton"> | |||
<Border x:Name="bd" BorderThickness="1" Background="{StaticResource NormalBackground}" BorderBrush="{StaticResource ControlBorderBrush}" CornerRadius="2"> | |||
<TextBlock Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}" | |||
FontWeight="{TemplateBinding FontWeight}" HorizontalAlignment="Center" VerticalAlignment="Center"/> | |||
</Border> | |||
<ControlTemplate.Triggers> | |||
<Trigger Property="IsChecked" Value="True"> | |||
<Setter Property="Background" TargetName="bd"> | |||
<Setter.Value> | |||
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> | |||
<GradientStopCollection> | |||
<GradientStop Color="#6AD456" /> | |||
<GradientStop Color="#1DAE06" Offset="0.5"/> | |||
<GradientStop Color="#8BDC7C" Offset="1"/> | |||
</GradientStopCollection> | |||
</LinearGradientBrush> | |||
</Setter.Value> | |||
</Setter> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<!--#endregion--> | |||
<DataTemplate x:Key="ToolBoxStyle"> | |||
<Grid Margin="2" Background="Transparent"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="30"/> | |||
<ColumnDefinition/> | |||
</Grid.ColumnDefinitions> | |||
<icon:PackIconMaterial x:Name="icon" Kind="Ellipse" BorderThickness="1" VerticalAlignment="Stretch" Width="24" HorizontalAlignment="Stretch"/> | |||
<TextBlock x:Name="txt" Grid.Column="1" Text="{Binding Name}" Margin="4"/> | |||
</Grid> | |||
<DataTemplate.Triggers> | |||
<DataTrigger Binding="{Binding Name}" Value="TheButton"> | |||
<Setter Property="Kind" TargetName="icon" Value="GestureTapButton"/> | |||
<Setter Property="Text" TargetName="txt" Value="按钮"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheTimer"> | |||
<Setter Property="Kind" TargetName="icon" Value="Timer"/> | |||
<Setter Property="Text" TargetName="txt" Value="计时器"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheCheckBox"> | |||
<Setter Property="Kind" TargetName="icon" Value="CheckboxMarked"/> | |||
<Setter Property="Text" TargetName="txt" Value="勾选框"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="DigitalNumber"> | |||
<Setter Property="Kind" TargetName="icon" Value="LedStrip"/> | |||
<Setter Property="Text" TargetName="txt" Value="液晶数字"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheComboBox"> | |||
<Setter Property="Kind" TargetName="icon" Value="ViewList"/> | |||
<Setter Property="Text" TargetName="txt" Value="下拉框"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheImage"> | |||
<Setter Property="Kind" TargetName="icon" Value="Image"/> | |||
<Setter Property="Text" TargetName="txt" Value="图片"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheTextBlock"> | |||
<Setter Property="Kind" TargetName="icon" Value="TagText"/> | |||
<Setter Property="Text" TargetName="txt" Value="文本块"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="ArcGauge"> | |||
<Setter Property="Kind" TargetName="icon" Value="Gauge"/> | |||
<Setter Property="Text" TargetName="txt" Value="仪表盘"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="StatusLight"> | |||
<Setter Property="Kind" TargetName="icon" Value="CeilingLight"/> | |||
<Setter Property="Text" TargetName="txt" Value="状态灯"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheToggleButton"> | |||
<Setter Property="Kind" TargetName="icon" Value="CheckOutline"/> | |||
<Setter Property="Text" TargetName="txt" Value="开关按钮"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheGroupBox"> | |||
<Setter Property="Kind" TargetName="icon" Value="Group"/> | |||
<Setter Property="Text" TargetName="txt" Value="分组"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheTextBox"> | |||
<Setter Property="Kind" TargetName="icon" Value="TextBox"/> | |||
<Setter Property="Text" TargetName="txt" Value="文本框"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="NumberBox"> | |||
<Setter Property="Kind" TargetName="icon" Value="Numeric8Box"/> | |||
<Setter Property="Text" TargetName="txt" Value="数值框"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="GraphArrow"> | |||
<Setter Property="Kind" TargetName="icon" Value="ArrowRightBold"/> | |||
<Setter Property="Text" TargetName="txt" Value="箭头"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="GraphStar"> | |||
<Setter Property="Kind" TargetName="icon" Value="Star"/> | |||
<Setter Property="Text" TargetName="txt" Value="五角星"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheSlider"> | |||
<Setter Property="Kind" TargetName="icon" Value="ArrowDownBold"/> | |||
<Setter Property="Text" TargetName="txt" Value="滑块"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheRadioButton"> | |||
<Setter Property="Kind" TargetName="icon" Value="RadioboxMarked"/> | |||
<Setter Property="Text" TargetName="txt" Value="单选按钮"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="SwitchButton"> | |||
<Setter Property="Kind" TargetName="icon" Value="ToggleSwitch"/> | |||
<Setter Property="Text" TargetName="txt" Value="开关"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="KnobButton"> | |||
<Setter Property="Kind" TargetName="icon" Value="Ellipse"/> | |||
<Setter Property="Text" TargetName="txt" Value="旋钮"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="Silos"> | |||
<Setter Property="Kind" TargetName="icon" Value="StoreSettings"/> | |||
<Setter Property="Text" TargetName="txt" Value="物料仓"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="NewConveyorBelt"> | |||
<Setter Property="Kind" TargetName="icon" Value="ArrowLeftRightBoldOutline"/> | |||
<Setter Property="Text" TargetName="txt" Value="滚动线"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheDataGrid"> | |||
<Setter Property="Kind" TargetName="icon" Value="LineScan"/> | |||
<Setter Property="Text" TargetName="txt" Value="表格"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheListBox"> | |||
<Setter Property="Kind" TargetName="icon" Value="LineScan"/> | |||
<Setter Property="Text" TargetName="txt" Value="列表控件"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheRedis"> | |||
<Setter Property="Kind" TargetName="icon" Value="AlphaDBoxOutline"/> | |||
<Setter Property="Text" TargetName="txt" Value="Redis控件"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="WaveProgressBar"> | |||
<Setter Property="Kind" TargetName="icon" Value="Wave"/> | |||
<Setter Property="Text" TargetName="txt" Value="进度条波浪"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheProgressBar"> | |||
<Setter Property="Kind" TargetName="icon" Value="LineScan"/> | |||
<Setter Property="Text" TargetName="txt" Value="进度条正常"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheRedProgressBar"> | |||
<Setter Property="Kind" TargetName="icon" Value="LineScan"/> | |||
<Setter Property="Text" TargetName="txt" Value="进度条圆形红"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheBlueProgressBar"> | |||
<Setter Property="Kind" TargetName="icon" Value="LineScan"/> | |||
<Setter Property="Text" TargetName="txt" Value="进度条圆形蓝"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheGreenProgressBar"> | |||
<Setter Property="Kind" TargetName="icon" Value="LineScan"/> | |||
<Setter Property="Text" TargetName="txt" Value="进度条圆形绿"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheAPI"> | |||
<Setter Property="Kind" TargetName="icon" Value="AlphaABoxOutline"/> | |||
<Setter Property="Text" TargetName="txt" Value="API接口"/> | |||
</DataTrigger> | |||
<DataTrigger Binding="{Binding Name}" Value="TheMQTT"> | |||
<Setter Property="Kind" TargetName="icon" Value="AlphaMBoxOutline"/> | |||
<Setter Property="Text" TargetName="txt" Value="MQTT"/> | |||
</DataTrigger> | |||
</DataTemplate.Triggers> | |||
</DataTemplate> | |||
<FontFamily x:Key="Digital"> | |||
pack://application:,,,/Fonts/#DS-Digital | |||
</FontFamily> | |||
<!--#region 右键菜单--> | |||
<ContextMenu x:Key="CanvasRightMenu" DataContext="{Binding PlacementTarget,RelativeSource={RelativeSource Self}}" FontFamily="Microsoft YaHei Ui"> | |||
<MenuItem Header="复制" Command="{Binding CopySelectItemsCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconModern Kind="PageCopy" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
<MenuItem Header="粘贴" Command="{Binding PasteSelectItemsCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconModern Kind="ClipboardPaste" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
<MenuItem Header="删除" Command="{Binding DeleteSelectItemsCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconModern Kind="Delete" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
</ContextMenu> | |||
<ContextMenu x:Key="AdornerRightMenu" DataContext="{Binding PlacementTarget.Tag,RelativeSource={RelativeSource Mode=Self}}" FontFamily="Microsoft YaHei Ui"> | |||
<MenuItem Header="复制" Command="{Binding CopySelectItemsCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconModern Kind="PageCopy" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
<MenuItem Header="粘贴" Command="{Binding PasteSelectItemsCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconModern Kind="ClipboardPaste" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
<MenuItem Header="删除" Command="{Binding DeleteSelectItemsCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconModern Kind="Delete" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
<MenuItem Header="置于顶层" Command="{Binding SetTopLayerCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconMaterial Kind="ArrangeSendToBack" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
<MenuItem Header="置于底层" Command="{Binding SetBottomLayerCommand}"> | |||
<MenuItem.Icon> | |||
<icon:PackIconMaterial Kind="ArrangeBringToFront" HorizontalAlignment="Center" Width="10"/> | |||
</MenuItem.Icon> | |||
</MenuItem> | |||
</ContextMenu> | |||
<!--#endregion--> | |||
<!--#region 控件集合--> | |||
<!--<Style TargetType="ctrl:DigitalNumber"> | |||
<Setter Property="Background" Value="#FF1A1E22"/> | |||
<Setter Property="Foreground" Value="#FF0AA74D"/> | |||
<Setter Property="NumberValue" Value="0.01"/> | |||
<Setter Property="FontSize" Value="20"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ctrl:DigitalNumber"> | |||
<Grid Background="{TemplateBinding Background}"> | |||
<TextBlock x:Name="line" VerticalAlignment="Center" HorizontalAlignment="Center" | |||
FontFamily="{StaticResource Digital}" FontSize="{TemplateBinding FontSize}" | |||
Text="{Binding NumberValue,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ctrl:DigitalNumber},Mode=TwoWay}" | |||
Foreground="{TemplateBinding Foreground}"/> | |||
</Grid> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:TheTimer}"> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type ctrl:TheTimer}"> | |||
<Border Background="{TemplateBinding Background}" | |||
BorderBrush="{TemplateBinding BorderBrush}" | |||
BorderThickness="{TemplateBinding BorderThickness}"> | |||
<Grid> | |||
<Image Source="../Images/timericon.png" RenderOptions.BitmapScalingMode="Fant"/> | |||
</Grid> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:StatusLight}"> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type ctrl:StatusLight}"> | |||
<Border Width="{Binding Path=ActualHeight,RelativeSource={RelativeSource Self}}"> | |||
<Grid> | |||
<Image x:Name="ima" Source="../Images/State0.png" RenderOptions.BitmapScalingMode="Fant"> | |||
</Image> | |||
</Grid> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:ArcGauge}"> | |||
<Setter Property="Background" Value="#646464"/> | |||
<Setter Property="Foreground" Value="Black"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type ctrl:ArcGauge}"> | |||
<Border Margin="10"> | |||
<Grid Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}"> | |||
<Ellipse Fill="#FF3B3B3B"/> | |||
<Grid RenderTransformOrigin="0.5,0.5" Margin="2"> | |||
<Grid.RenderTransform> | |||
<TransformGroup> | |||
<RotateTransform Angle="{Binding Path=Angle,ElementName=PointRotate}"/> | |||
</TransformGroup> | |||
</Grid.RenderTransform> | |||
<Ellipse Width="16" Height="14" Fill="Orange" VerticalAlignment="Top" > | |||
<Ellipse.Effect> | |||
<BlurEffect Radius="12"/> | |||
</Ellipse.Effect> | |||
</Ellipse> | |||
</Grid> | |||
<Grid x:Name="bdGrid" Margin="12" UseLayoutRounding="True" ClipToBounds="True"> | |||
<Ellipse> | |||
<Ellipse.Fill> | |||
<RadialGradientBrush> | |||
<GradientStop Color="#4D000000"/> | |||
</RadialGradientBrush> | |||
</Ellipse.Fill> | |||
</Ellipse> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="2*"/> | |||
<ColumnDefinition/> | |||
</Grid.ColumnDefinitions> | |||
<Grid.RowDefinitions> | |||
<RowDefinition/> | |||
<RowDefinition Height="2*"/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<Ellipse Stroke="#464646" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/> | |||
<Ellipse Stroke="#959595" Margin="4" StrokeThickness="6" Grid.Column="1" Grid.Row="1"/> | |||
<Ellipse Stroke="#464646" Margin="14" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/> | |||
</Grid> | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<Path Data="M5,0 5,0 10,120 0,120z" Fill="#0FA9CE" Stretch="Uniform" Margin="0 30 0 0" RenderTransformOrigin="0.5,1" HorizontalAlignment="Center"> | |||
<Path.RenderTransform> | |||
<TransformGroup> | |||
<RotateTransform x:Name="PointRotate"/> | |||
</TransformGroup> | |||
</Path.RenderTransform> | |||
</Path> | |||
</Grid> | |||
<Ellipse Width="28" Height="28" Fill="Black"> | |||
<Ellipse.Effect> | |||
<DropShadowEffect Color="#0FA9CE" ShadowDepth="0" Direction="0" BlurRadius="16"/> | |||
</Ellipse.Effect> | |||
</Ellipse> | |||
<Border VerticalAlignment="Bottom" BorderBrush="#10ABD1" BorderThickness="2" Margin="0 0 0 12" Background="Black" Padding="4 2" HorizontalAlignment="Center"> | |||
<TextBlock Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent},StringFormat={}{0:f1}}" FontSize="16" Width="46" TextAlignment="Center" Foreground="White"/> | |||
</Border> | |||
</Grid> | |||
</Grid> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:TheTextBox}" BasedOn="{StaticResource {x:Type TextBox}}"/> | |||
<Style x:Key="DesignTheTextBox" TargetType="{x:Type ctrl:TheTextBox}"> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ctrl:TheTextBox"> | |||
<Border BorderBrush="{StaticResource ControlBorderBrush}" BorderThickness="1" Background="{StaticResource ControlBackground}"> | |||
<TextBlock Margin="4 0 0 0" Text="{TemplateBinding Text}" VerticalAlignment="Center"/> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:NumberBox}" BasedOn="{StaticResource {x:Type TextBox}}"> | |||
<Setter Property="input:InputMethod.IsInputMethodEnabled" Value="False"/> | |||
</Style> | |||
<Style x:Key="DesignNumberBox" TargetType="{x:Type ctrl:NumberBox}"> | |||
<Setter Property="input:InputMethod.IsInputMethodEnabled" Value="False"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ctrl:NumberBox"> | |||
<Border BorderBrush="{StaticResource ControlBorderBrush}" BorderThickness="1" Background="{StaticResource ControlBackground}"> | |||
<TextBlock Margin="4 0 0 0" Text="{TemplateBinding Text}" VerticalAlignment="Center" Foreground="BlueViolet"/> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:TheSlider}" BasedOn="{StaticResource {x:Type Slider}}"> | |||
<Setter Property="Width" Value="140"/> | |||
<Setter Property="Maximum" Value="100"/> | |||
<Setter Property="IsSnapToTickEnabled" Value="True"/> | |||
<Setter Property="Minimum" Value="0"/> | |||
<Setter Property="AutoToolTipPlacement" Value="BottomRight"/> | |||
<Setter Property="SmallChange" Value="0.1"/> | |||
<Setter Property="LargeChange" Value="0.1"/> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:TheRadioButton}" BasedOn="{StaticResource {x:Type RadioButton}}"> | |||
<Setter Property="VerticalContentAlignment" Value="Center" /> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:WaveProgressBar}"> | |||
<Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" /> | |||
<Setter Property="BorderThickness" Value="1"/> | |||
<Setter Property="WaveFill" Value="#36E7AE"/> | |||
<Setter Property="WaveThickness" Value="2"/> | |||
<Setter Property="WaveStroke" Value="#3649E7"/> | |||
<Setter Property="ShowText" Value="True" /> | |||
<Setter Property="Background" Value="Transparent" /> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ctrl:WaveProgressBar"> | |||
<ControlTemplate.Resources> | |||
<Storyboard x:Key="StoryboardOnLoaded" RepeatBehavior="Forever"> | |||
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="PART_Wave"> | |||
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="-400"/> | |||
</DoubleAnimationUsingKeyFrames> | |||
</Storyboard> | |||
</ControlTemplate.Resources> | |||
<StackPanel> | |||
<Border Background="{TemplateBinding Background}"> | |||
<Viewbox> | |||
<Border x:Name="PART_Clip" BorderThickness="{TemplateBinding BorderThickness}" ClipToBounds="True" | |||
BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="100" Width="200" Height="200"> | |||
<Border.Clip> | |||
<EllipseGeometry RadiusX="100" RadiusY="100" Center="100,100"/> | |||
</Border.Clip> | |||
<Grid> | |||
<Path x:Name="PART_Wave" Stroke="{TemplateBinding WaveStroke}" ClipToBounds="True" StrokeThickness="{TemplateBinding WaveThickness}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="600" Height="250" Fill="{TemplateBinding WaveFill}" Stretch="Fill" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" Margin="0,0,-400,-20"> | |||
<Path.Data> | |||
<PathGeometry> | |||
<PathFigure StartPoint="0,1"> | |||
<PolyBezierSegment Points="0.5,1 0.5,0 1,0"/> | |||
<PolyBezierSegment Points="1.5,0 1.5,1 2,1"/> | |||
<PolyBezierSegment Points="2.5,1 2.5,0 3,0"/> | |||
<PolyLineSegment Points="3,0 3,10, 0,10 0,1"/> | |||
</PathFigure> | |||
</PathGeometry> | |||
</Path.Data> | |||
</Path> | |||
<TextBlock Visibility="{Binding ShowText,RelativeSource={RelativeSource TemplatedParent},Converter={x:Static dxmvmm:BoolToVisibilityConverter.Instance}}" | |||
HorizontalAlignment="Center" VerticalAlignment="Center" | |||
Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" | |||
Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent},StringFormat={}{0:f2}%}"/> | |||
</Grid> | |||
</Border> | |||
</Viewbox> | |||
</Border> | |||
</StackPanel> | |||
<ControlTemplate.Triggers> | |||
<EventTrigger RoutedEvent="FrameworkElement.Loaded" SourceName="PART_Wave"> | |||
<BeginStoryboard Name="BeginStoryboardWave" Storyboard="{StaticResource StoryboardOnLoaded}"/> | |||
</EventTrigger> | |||
<EventTrigger RoutedEvent="FrameworkElement.Unloaded" SourceName="PART_Wave"> | |||
<StopStoryboard BeginStoryboardName="BeginStoryboardWave"/> | |||
</EventTrigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:SwitchButton}"> | |||
<Setter Property="Background" Value="#00F4D5"/> | |||
<Setter Property="BorderBrush" Value="LightGray"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ctrl:SwitchButton"> | |||
<Border CornerRadius="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=ActualHeight,Converter={StaticResource HalfNumber}}" | |||
BorderThickness="1" Background="{StaticResource ControlBackground}" BorderBrush="{TemplateBinding BorderBrush}"> | |||
<Grid> | |||
<Ellipse x:Name="ELLIPSE" HorizontalAlignment="Left" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" | |||
Fill="Gray" Stroke="{StaticResource ControlBorderBrush}" StrokeThickness="1"> | |||
<Ellipse.RenderTransform> | |||
<TransformGroup> | |||
<TranslateTransform x:Name="TranslateX" X="2"/> | |||
</TransformGroup> | |||
</Ellipse.RenderTransform> | |||
</Ellipse> | |||
</Grid> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<Style TargetType="{x:Type ctrl:KnobButton}"> | |||
<Setter Property="Background" Value="#0068F4"/> | |||
<Setter Property="BorderBrush" Value="LightGray"/> | |||
<Setter Property="Foreground" Value="Black"/> | |||
<Setter Property="FontSize" Value="20"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ctrl:KnobButton"> | |||
<Grid x:Name="bdGrid" Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"> | |||
<Grid Margin="16" RenderTransformOrigin="0.5,0.5"> | |||
<Grid.RenderTransform> | |||
<RotateTransform x:Name="rotatevalue" Angle="00"/> | |||
</Grid.RenderTransform> | |||
<Ellipse Margin="4" Fill="#FFF6F6F6" Stroke="{StaticResource ControlBorderBrush}" > | |||
<Ellipse.Effect> | |||
<DropShadowEffect ShadowDepth="2" BlurRadius="8" Direction="-90" Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Background.(SolidColorBrush.Color)}"/> | |||
</Ellipse.Effect> | |||
</Ellipse> | |||
<Ellipse Margin="12" Fill="{TemplateBinding Background}" Width="8" Height="8" VerticalAlignment="Bottom"> | |||
</Ellipse> | |||
</Grid> | |||
<TextBlock Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent}, StringFormat={}{0:F2}}" | |||
VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}"/> | |||
</Grid> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style>--> | |||
<!--#endregion--> | |||
<!--#region 控制集合--> | |||
<Style TargetType="{x:Type ToggleButton}" > | |||
<Setter Property="Foreground" Value="White"/> | |||
<Setter Property="FontFamily" Value="Microsoft YaHei"/> | |||
<Setter Property="FontSize" Value="12"/> | |||
<Setter Property="FontWeight" Value="Bold"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="ToggleButton"> | |||
<Border BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="0" CornerRadius="2"> | |||
<Border.Background> | |||
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> | |||
<GradientStop Color="#FF71E0C6" Offset="0.0" /> | |||
<GradientStop Color="#FF43A88D" Offset="0.2" /> | |||
<GradientStop Color="#FF5BB07D" Offset="0.0" /> | |||
</LinearGradientBrush> | |||
</Border.Background> | |||
<ContentPresenter Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" ></ContentPresenter> | |||
</Border> | |||
<ControlTemplate.Triggers> | |||
<Trigger Property="ButtonBase.IsPressed" Value="True"> | |||
<Setter Property="UIElement.Effect"> | |||
<Setter.Value> | |||
<DropShadowEffect BlurRadius="10" Color="#276AB0" Direction="0" Opacity="0.9" RenderingBias="Performance" ShadowDepth="0" /> | |||
</Setter.Value> | |||
</Setter> | |||
<Setter Property="RenderTransform"> | |||
<Setter.Value> | |||
<ScaleTransform ScaleX="0.9" ScaleY="0.9" /> | |||
</Setter.Value> | |||
</Setter> | |||
<Setter Property="RenderTransformOrigin" Value=".5,.5" /> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<DataTemplate x:Key="Category"> | |||
<TextBlock Text="{Binding}" FontSize="20" Foreground="#4EB9E4" /> | |||
</DataTemplate> | |||
<!--#endregion--> | |||
</ResourceDictionary> |
@@ -0,0 +1,50 @@ | |||
<Window x:Class="BeDesignerSCADA.View.JsEditWindow" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:local="clr-namespace:BeDesignerSCADA.View" | |||
xmlns:avae="http://icsharpcode.net/sharpdevelop/avalonedit" | |||
mc:Ignorable="d" | |||
Title="编辑脚本" Height="600" Width="920" | |||
Background="White" | |||
BorderBrush="#FFDEDEDE" | |||
BorderThickness="1" | |||
ResizeMode="NoResize" | |||
WindowStartupLocation="CenterOwner" | |||
WindowStyle="None"> | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition/> | |||
<RowDefinition Height="40"/> | |||
</Grid.RowDefinitions> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="*"/> | |||
<ColumnDefinition Width="3*"/> | |||
</Grid.ColumnDefinitions> | |||
<TabControl Margin="4"> | |||
<TabItem Header="属性"> | |||
<TreeView x:Name="Tree" Margin="0" AllowDrop="False" MouseMove="Tree_MouseMove"> | |||
<TreeView.ItemTemplate> | |||
<HierarchicalDataTemplate ItemsSource="{Binding Path=Properties}"> | |||
<TextBlock Text="{Binding Name}"/> | |||
</HierarchicalDataTemplate> | |||
</TreeView.ItemTemplate> | |||
</TreeView> | |||
</TabItem> | |||
</TabControl> | |||
<avae:TextEditor AllowDrop="True" Margin="4" Drop="txtBox_Drop" BorderThickness="1" BorderBrush="LightGray" x:Name="txtBox" DragOver="txtBox_DragOver" Grid.Column="1" Padding="4" HorizontalScrollBarVisibility="Disabled" | |||
SyntaxHighlighting="JavaScript" ShowLineNumbers="True" FontSize="16" FontFamily="Consolas"/> | |||
</Grid> | |||
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right"> | |||
<Button Width="80" Height="30" Content="取消" x:Name="CancelBtn" Click="CancelBtn_Click" IsCancel="True"/> | |||
<Button Width="80" Height="30" Content="确认" x:Name="ConfirmBtn" Margin="8 0 4 0" Click="ConfirmBtn_Click"/> | |||
</StackPanel> | |||
</Grid> | |||
</Window> |
@@ -0,0 +1,94 @@ | |||
using BeDesignerSCADA.Common; | |||
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.Shapes; | |||
namespace BeDesignerSCADA.View | |||
{ | |||
/// <summary> | |||
/// JsEditWindow.xaml 的交互逻辑 | |||
/// </summary> | |||
public partial class JsEditWindow : Window | |||
{ | |||
public JsEditWindow() | |||
{ | |||
InitializeComponent(); | |||
Owner = Application.Current.MainWindow; | |||
Closing += (s, e) => { e.Cancel = true; Hide(); }; | |||
} | |||
public static JsEditWindow Instance { get; } = new JsEditWindow(); | |||
public static string ShowEdit(string script, List<FrameworkElement> selectItems) | |||
{ | |||
// 获取所有控件的可用属性 | |||
var pros = PropertyHelper.GetCustomerControlProperty(selectItems); | |||
Instance.Tree.ItemsSource = pros; | |||
Instance.txtBox.Text = script; | |||
Instance.ShowDialog(); | |||
if (Instance.IsOk) | |||
{ | |||
return Instance.txtBox.Text; | |||
} | |||
else | |||
{ | |||
return script; | |||
} | |||
} | |||
public bool IsOk { get; set; } | |||
private void CancelBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
IsOk = false; | |||
Close(); | |||
} | |||
private void ConfirmBtn_Click(object sender, RoutedEventArgs e) | |||
{ | |||
IsOk = true; | |||
Close(); | |||
} | |||
private void Tree_MouseMove(object sender, MouseEventArgs e) | |||
{ | |||
if (Tree.SelectedItem != null && e.LeftButton == MouseButtonState.Pressed) | |||
{ | |||
DragDrop.DoDragDrop(Tree, Tree.SelectedItem, System.Windows.DragDropEffects.Copy); | |||
} | |||
} | |||
private void txtBox_Drop(object sender, DragEventArgs e) | |||
{ | |||
e.Effects = DragDropEffects.Copy; | |||
var data = ((ControlName)e.Data.GetData("BeDesignerSCADA.Common.ControlName")); | |||
var str = $"{(data.Parent == null ? string.Empty : (data.Parent.Name + "."))}{data.Name}"; | |||
var position = txtBox.GetPositionFromPoint(e.GetPosition(txtBox)); | |||
if (position == null) | |||
{ | |||
txtBox.Text += str; | |||
return; | |||
} | |||
var offset = txtBox.Document.GetOffset(position.Value.Location); | |||
txtBox.SelectionStart = offset; | |||
txtBox.Document.Insert(offset, str); | |||
} | |||
private void txtBox_DragOver(object sender, DragEventArgs e) | |||
{ | |||
e.Effects = DragDropEffects.Copy; | |||
} | |||
} | |||
} |
@@ -0,0 +1,80 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BeDesignerSCADA.ViewModel | |||
{ | |||
/// <summary> | |||
/// 事件Model | |||
/// </summary> | |||
public class EventModel | |||
{ | |||
/// <summary> | |||
/// 事件id | |||
/// </summary> | |||
public string EventId { get; set; } | |||
/// <summary> | |||
/// 事件名称 | |||
/// </summary> | |||
public string EventName { get; set; } | |||
/// <summary> | |||
/// 事件值 | |||
/// </summary> | |||
public string EventValue { get; set; } | |||
/// <summary> | |||
/// 特性:分组 | |||
/// </summary> | |||
public string Category { get; set; } | |||
/// <summary> | |||
/// 特性:描述 | |||
/// </summary> | |||
public string Description { get; set; } | |||
/// <summary> | |||
/// 特性:是否启用 | |||
/// </summary> | |||
public bool Browsable { get; set; } | |||
public EventModel() | |||
{ | |||
EventId=Guid.NewGuid().ToString(); | |||
} | |||
} | |||
/// <summary> | |||
/// 数据Model | |||
/// </summary> | |||
public class ALLModel | |||
{ | |||
/// <summary> | |||
/// 数据id | |||
/// </summary> | |||
public string DataId { get; set; } | |||
/// <summary> | |||
/// 数据名称 | |||
/// </summary> | |||
public string DataName { get; set; } | |||
/// <summary> | |||
/// 数据值 | |||
/// </summary> | |||
public string DataValue { get; set; } | |||
/// <summary> | |||
/// 特性:分组 | |||
/// </summary> | |||
public string Category { get; set; } | |||
/// <summary> | |||
/// 特性:描述 | |||
/// </summary> | |||
public string Description { get; set; } | |||
/// <summary> | |||
/// 特性:是否启用 | |||
/// </summary> | |||
public bool Browsable { get; set; } | |||
public ALLModel() | |||
{ | |||
DataId = Guid.NewGuid().ToString(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,871 @@ | |||
using BeDesignerSCADA.Common; | |||
using BeDesignerSCADA.Controls; | |||
using BeDesignerSCADA.View; | |||
using BPASmartClient.Compiler; | |||
using BPASmartClient.DATABUS; | |||
using BPASmartClient.MessageName; | |||
using BPASmartClient.MessageName.EnumHelp; | |||
using BPASmartClient.MessageName.发送消息Model; | |||
using BPASmartClient.MessageName.接收消息Model; | |||
using ICSharpCode.AvalonEdit; | |||
using Microsoft.Toolkit.Mvvm.ComponentModel; | |||
using Microsoft.Toolkit.Mvvm.Input; | |||
using Microsoft.Win32; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.ComponentModel; | |||
using System.Linq; | |||
using System.Reflection; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using System.Windows.Input; | |||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; | |||
namespace BeDesignerSCADA.ViewModel | |||
{ | |||
/// <summary> | |||
/// 主函数 ViewModel | |||
/// </summary> | |||
public class MainViewModel :ObservableObject | |||
{ | |||
public MainViewModel() | |||
{ | |||
IsRunning = false; | |||
//启动 或者 停止 | |||
RunUiCommand = new RelayCommand(() => | |||
{ | |||
IsRunning = !IsRunning; | |||
}); | |||
} | |||
#region 变量 | |||
/// <summary> | |||
/// 设置 | |||
/// </summary> | |||
public Xceed.Wpf.Toolkit.PropertyGrid.PropertyGrid propertyGrid = null; | |||
/// <summary> | |||
/// 是否正在运行状态 | |||
/// </summary> | |||
private bool _IsRunning = false; | |||
public bool IsRunning | |||
{ | |||
get | |||
{ | |||
return _IsRunning; | |||
} | |||
set | |||
{ | |||
_IsRunning = value; | |||
if (value) | |||
{ | |||
RunCanvasVisibility = Visibility.Visible; | |||
CanvasPanelVisibility = Visibility.Hidden; | |||
} | |||
else | |||
{ | |||
RunCanvasVisibility = Visibility.Hidden; | |||
CanvasPanelVisibility = Visibility.Visible; | |||
} | |||
OnPropertyChanged("IsRunning"); | |||
} | |||
} | |||
/// <summary> | |||
/// 画布是否显示 | |||
/// </summary> | |||
private Visibility _CanvasPanelVisibility; | |||
public Visibility CanvasPanelVisibility | |||
{ | |||
get | |||
{ | |||
return _CanvasPanelVisibility; | |||
} | |||
set | |||
{ | |||
if (_CanvasPanelVisibility == value) | |||
return; | |||
_CanvasPanelVisibility = value; | |||
OnPropertyChanged("CanvasPanelVisibility"); | |||
} | |||
} | |||
/// <summary> | |||
/// 运行代码是否显示 | |||
/// </summary> | |||
private Visibility _RunCanvasVisibility; | |||
public Visibility RunCanvasVisibility | |||
{ | |||
get | |||
{ | |||
return _RunCanvasVisibility; | |||
} | |||
set | |||
{ | |||
if (_RunCanvasVisibility == value) | |||
return; | |||
_RunCanvasVisibility = value; | |||
OnPropertyChanged("RunCanvasVisibility"); | |||
} | |||
} | |||
/// <summary> | |||
/// 当前代码Xaml | |||
/// </summary> | |||
private string _XamlCode; | |||
public string XamlCode | |||
{ | |||
get | |||
{ | |||
return _XamlCode; | |||
} | |||
set | |||
{ | |||
if (_XamlCode == value) | |||
return; | |||
_XamlCode = value; | |||
OnPropertyChanged("XamlCode"); | |||
} | |||
} | |||
/// <summary> | |||
/// 选中控件 | |||
/// </summary> | |||
private FrameworkElement _CanSelectedItem; | |||
public FrameworkElement CanSelectedItem | |||
{ | |||
get | |||
{ | |||
return _CanSelectedItem; | |||
} | |||
set | |||
{ | |||
if (_CanSelectedItem == value) | |||
return; | |||
_CanSelectedItem = value; | |||
DataSX(); | |||
OnPropertyChanged("CanSelectedItem"); | |||
} | |||
} | |||
private PropertyGridCommand _pro; | |||
public PropertyGridCommand PropeObject | |||
{ | |||
get | |||
{ | |||
return _pro; | |||
} | |||
set | |||
{ | |||
_pro = value; | |||
OnPropertyChanged("PropeObject"); | |||
} | |||
} | |||
private ObservableCollection<string> _DevNameList; | |||
public ObservableCollection<string> DevNameList | |||
{ | |||
get | |||
{ | |||
return _DevNameList; | |||
} | |||
set | |||
{ | |||
_DevNameList = value; | |||
OnPropertyChanged("DevNameList"); | |||
} | |||
} | |||
private ObservableCollection<string> _DevValueList; | |||
public ObservableCollection<string> DevValueList | |||
{ | |||
get | |||
{ | |||
return _DevValueList; | |||
} | |||
set | |||
{ | |||
_DevValueList = value; | |||
OnPropertyChanged("DevValueList"); | |||
} | |||
} | |||
#endregion | |||
#region 命令 | |||
/// <summary> | |||
/// 启动或者停止 | |||
/// </summary> | |||
public RelayCommand RunUiCommand { get; set; } | |||
#endregion | |||
#region 常用函数 | |||
/// <summary> | |||
/// 显示当前xaml代码 | |||
/// </summary> | |||
public void ShowCode(TextEditor textEditor) | |||
{ | |||
textEditor.Text = canvasPanel.Save(); | |||
} | |||
#endregion | |||
#region 脚本编辑数据 | |||
public CanvasPanel canvasPanel; | |||
/// <summary> | |||
/// 加载 | |||
/// </summary> | |||
/// <param name="obj"></param> | |||
public void Loaded(object obj) | |||
{ | |||
canvasPanel = obj as CanvasPanel; | |||
} | |||
/// <summary> | |||
/// 编辑 | |||
/// </summary> | |||
/// <param name="obj"></param> | |||
public void Edit(object obj) | |||
{ | |||
string result = JsEditWindow.ShowEdit(((Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem)obj).Value?.ToString(),canvasPanel.GetAllExecChildren()); | |||
((Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem)obj).Value = result; | |||
} | |||
#endregion | |||
#region 图片选择路径 | |||
public void SelectPath(object obj) | |||
{ | |||
OpenFileDialog ofd = new OpenFileDialog(); | |||
ofd.Filter = "图片|*.jpg;*.png;*.gif;*.jpeg;*.bmp"; | |||
if (ofd.ShowDialog() == true) | |||
{ | |||
//((DevExpress.Xpf.Editors.EditableDataObject)obj).Value = ofd.FileName; | |||
} | |||
} | |||
#endregion | |||
#region 属性填充 | |||
Dictionary<string,string> EventName = new Dictionary<string,string> { | |||
{"Name","名称" }, | |||
{"Text","文本" }, | |||
{"Content","按钮文本" }, | |||
{"Title","标题" }, | |||
{"Value","变量" }, | |||
{"ClickExec","点击事件" }, | |||
{"ValueChangedExecute" , "值改变事件"}, | |||
{"TikcExecute" , "定时触发"}, | |||
{"CheckedExec" , "勾选事件"}, | |||
{"UnCheckedExec" , "取消勾选事件"}, | |||
{"EventReceiveNameList" , "接收消息集"}, | |||
//{"DataSouceType" , "数据来源类型"}, | |||
{ "TimeCount" , "定时间隔"}, | |||
{ "InterfaceMode" , "接口类型"}, | |||
{ "InterfaceParameters" , "接口参数"}, | |||
{ "DataSouceInformation" , "连接信息"}, | |||
{ "DeviceName" , "设备名称"}, | |||
{ "DeviceValuleName" , "设备解析变量"}, | |||
{"FDataSouce" , "数据源"}, | |||
{ "Code" , "代码过滤脚本"}, | |||
{ "GenerateData" , "数据结果"}, | |||
}; | |||
//{"EventSendNameList" , "发送事件集"} | |||
/// <summary> | |||
/// 数据刷新 | |||
/// </summary> | |||
public void DataSX() | |||
{ | |||
//if (CanSelectedItem is System.Windows.Controls.Control) | |||
{ | |||
//属性变量 | |||
PropertyGridCommand cmd = new PropertyGridCommand(); | |||
var content = CanSelectedItem;// as System.Windows.Controls.Control; | |||
if (content is IExecutable executable) | |||
executable.PropertyChange += Executable_PropertyChange; | |||
foreach (var item in EventName) | |||
{ | |||
System.Reflection.PropertyInfo info = content.GetType().GetProperty(item.Key); | |||
var propName = info?.GetValue(content,null); | |||
if (info != null && item.Key == "Content" ? (propName is string) : true) | |||
{ | |||
//var taget = this.GetType().GetMembers().Where(t => t.Name.Equals("BrowsableTrue")).FirstOrDefault(); | |||
//var datas= CustomAttributeData.GetCustomAttributes(taget)[0]; | |||
//cmd.GetType().GetProperty(item.Value).CustomAttributes.Append(datas); | |||
cmd.GetType().GetProperty(item.Value).SetValue(cmd,propName); | |||
} | |||
} | |||
cmd.PropertyChanged += Cmd_PropertyChanged; | |||
PropeObject = cmd; | |||
} | |||
} | |||
private void Executable_PropertyChange(object? sender,EventArgs e) | |||
{ | |||
System.Windows.Controls.Control content = CanSelectedItem as System.Windows.Controls.Control; | |||
System.Reflection.PropertyInfo info = content.GetType().GetProperty("GenerateData"); | |||
var propName = info?.GetValue(content,null); | |||
PropeObject.GetType().GetProperty("数据结果").SetValue(PropeObject,propName); | |||
DevNameList = new System.Collections.ObjectModel.ObservableCollection<string>(); | |||
DevValueList = new System.Collections.ObjectModel.ObservableCollection<string>(); | |||
Class_DataBus.GetInstance().Dic_DeviceData.Keys?.ToList().ForEach(key => { DevNameList.Add(key); }); | |||
} | |||
[Browsable(true)] | |||
public void BrowsableTrue() { } | |||
[Browsable(false)] | |||
public void BrowsableFalse() { } | |||
/// <summary> | |||
/// 修改属性后 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void Cmd_PropertyChanged(object? sender,PropertyChangedEventArgs e) | |||
{ | |||
try | |||
{ | |||
string name = e.PropertyName; | |||
foreach (var item in EventName) | |||
{ | |||
if (item.Value == name) | |||
{ | |||
name = item.Key; | |||
} | |||
} | |||
PropertyGridCommand hotinfo = (PropertyGridCommand)sender; | |||
System.Reflection.PropertyInfo info = hotinfo.GetType().GetProperty(e.PropertyName); | |||
var propName = info?.GetValue(hotinfo,null); | |||
ProGridSetValue(name,propName); | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
/// <summary> | |||
/// 设置变量 | |||
/// </summary> | |||
/// <param name="value"></param> | |||
public void ProGridSetValue(string Name,object value) | |||
{ | |||
try | |||
{ | |||
// if (CanSelectedItem is System.Windows.Controls.Control) | |||
{ | |||
var content = CanSelectedItem;// as System.Windows.Controls.Control; | |||
if (Name == "Content" ? (content is BPASmartClient.SCADAControl.CustomerControls.TheButton) : true) | |||
{ | |||
System.Reflection.PropertyInfo info = content.GetType().GetProperty(Name); | |||
info?.SetValue(content,value,null); | |||
} | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
#endregion | |||
#region 设置 | |||
/// <summary> | |||
/// 设置Browsable特性的值 | |||
/// </summary> | |||
/// <param name="obj"></param> | |||
/// <param name="propertyName"></param> | |||
/// <param name="visible"></param> | |||
public void SetPropertyVisibility(object obj,string propertyName,bool visible) | |||
{ | |||
//Type type = typeof(BrowsableAttribute); | |||
//PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); | |||
//AttributeCollection attrs = props[propertyName].Attributes; | |||
//type.GetProperty("Browsable").SetValue(attrs[type], visible); | |||
//AttributeCollection attributes = | |||
// TypeDescriptor.GetProperties(obj)[propertyName].Attributes; | |||
//// Checks to see if the property is browsable. | |||
//BrowsableAttribute myAttribute = (BrowsableAttribute)attributes[typeof( | |||
//BrowsableAttribute)]; | |||
//if (myAttribute.Browsable) | |||
//{ | |||
// // Insert code here. | |||
//} | |||
//PropertyDescriptorCollection appSetingAttributes = TypeDescriptor.GetProperties(obj); | |||
//Type type = typeof(BrowsableAttribute); | |||
//FieldInfo fieldInfo = type.GetField("_displayName", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance); | |||
//fieldInfo.SetValue(appSetingAttributes["TextID"].Attributes[displayType], "修改后的文本ID"); | |||
} | |||
/// <summary> | |||
/// 设置Category特性的值 | |||
/// </summary> | |||
/// <param name="obj"></param> | |||
/// <param name="propertyName"></param> | |||
/// <param name="str"></param> | |||
public void SetCategoryValue(object obj,string propertyName,string str) | |||
{ | |||
Type type = typeof(CategoryAttribute); | |||
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); | |||
AttributeCollection attrs = props[propertyName].Attributes; | |||
FieldInfo fld = type.GetField("categoryValue",BindingFlags.Instance | BindingFlags.NonPublic); | |||
fld?.SetValue(attrs[type],str); | |||
} | |||
/// <summary> | |||
/// 获取类的属性成员的Category特性的值 | |||
/// </summary> | |||
/// <param name="obj"></param> | |||
/// <param name="propertyName"></param> | |||
/// <returns></returns> | |||
public string GetCategoryValue(object obj,string propertyName) | |||
{ | |||
Type type = typeof(CategoryAttribute); | |||
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); | |||
AttributeCollection attrs = props[propertyName].Attributes; | |||
FieldInfo fld = type.GetField("categoryValue",BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); | |||
var str = fld?.GetValue(attrs[type])?.ToString(); | |||
return str; | |||
} | |||
/// <summary> | |||
/// 设置类的CategoryOrderAttribute特性的值 | |||
/// </summary> | |||
/// <param name="obj"></param> | |||
/// <param name="categoryOrders"></param> | |||
public void SetCategoryOrderValue(object obj,CategoryOrderAttribute[] categoryOrders) | |||
{ | |||
TypeDescriptor.AddAttributes(obj.GetType(),categoryOrders); | |||
} | |||
/// <summary> | |||
/// 使用反射设置嵌套属性的值 | |||
/// </summary> | |||
/// <param name="obj">对象 </param> | |||
/// <param name="propename">第一层属性</param> | |||
/// <param name="targetname">目标属性(是第一层属性的成员)</param> | |||
/// <param name="val">赋的值</param> | |||
private void NestPropeSetValue(object obj,string propename,string targetname,object val) | |||
{ | |||
PropertyInfo[] propertyInfos = obj.GetType().GetProperties(); | |||
var prope = propertyInfos.Single(x => propename == x.PropertyType.Name); | |||
var value = prope.GetValue(obj,null); | |||
var pr = value.GetType().GetProperties().Single(x => x.Name == targetname); | |||
pr?.SetValue(value,val); | |||
} | |||
#endregion | |||
} | |||
[CategoryOrder("基本属性",1), CategoryOrder("事件",2)]//分组在排序 | |||
public class PropertyGridCommand :ObservableObject | |||
{ | |||
private string _名称; | |||
private string _文本; | |||
private string _标题; | |||
private string _文本1; | |||
private object _变量; | |||
[Category("基本属性"), Description("Name"), Browsable(true), PropertyOrder(1)] | |||
public string 名称 | |||
{ | |||
get | |||
{ | |||
return _名称; | |||
} | |||
set | |||
{ | |||
if (_名称 == value) | |||
return; | |||
_名称 = value; | |||
OnPropertyChanged("名称"); | |||
} | |||
} | |||
[Category("基本属性"), Description("Text"), Browsable(true), PropertyOrder(3)] | |||
public string 文本 | |||
{ | |||
get | |||
{ | |||
return _文本; | |||
} | |||
set | |||
{ | |||
if (_文本 == value) | |||
return; | |||
_文本 = value; | |||
OnPropertyChanged("文本"); | |||
} | |||
} | |||
[Category("基本属性"), Description("Title"), Browsable(true), PropertyOrder(2)] | |||
public string 标题 | |||
{ | |||
get | |||
{ | |||
return _标题; | |||
} | |||
set | |||
{ | |||
if (_标题 == value) | |||
return; | |||
_标题 = value; | |||
OnPropertyChanged("标题"); | |||
} | |||
} | |||
[Category("基本属性"), Description("Content"), Browsable(true), PropertyOrder(3)] | |||
public string 按钮文本 | |||
{ | |||
get | |||
{ | |||
return _文本1; | |||
} | |||
set | |||
{ | |||
if (_文本1 == value) | |||
return; | |||
_文本1 = value; | |||
OnPropertyChanged("按钮文本"); | |||
} | |||
} | |||
[Category("基本属性"), Description("Value"), Browsable(true), PropertyOrder(4)] | |||
public object 变量 | |||
{ | |||
get | |||
{ | |||
return _变量; | |||
} | |||
set | |||
{ | |||
if (_变量 == value) | |||
return; | |||
_变量 = value; | |||
OnPropertyChanged("变量"); | |||
} | |||
} | |||
//[Category("基本属性"), Description("Content"), Browsable(true), PropertyOrder(2)] | |||
//public string 内容 { get; set; } | |||
//[Category("基本属性"), Description("Header"), Browsable(true), PropertyOrder(3)] | |||
//public string 标题 { get; set; } | |||
//[Category("基本属性"), Description("Text"), Browsable(true), PropertyOrder(4)] | |||
//public object 文本 { get; set; } | |||
//[Category("基本属性"), Description("NumberValue"), Browsable(true), PropertyOrder(5)] | |||
//public object 值 { get; set; } | |||
//[Category("基本属性"), Description("CurValue"), Browsable(true), PropertyOrder(5)] | |||
//public object 数值 { get; set; } | |||
//[Category("基本属性"), Description("StatusValue"), Browsable(true), PropertyOrder(6)] | |||
//public string 状态值 { get; set; } | |||
//[Category("基本属性"), Description("IsChecked"), Browsable(true), PropertyOrder(7)] | |||
//public string 勾选状态 { get; set; } | |||
//[Category("基本属性"), Description("Value"), Browsable(true), PropertyOrder(7)] | |||
//public string 数值1 { get; set; } | |||
//[Category("基本属性"), Description("MaxValue"), Browsable(true), PropertyOrder(8)] | |||
//public string 最大值 { get; set; } | |||
//[Category("基本属性"), Description("MinValue"), Browsable(true), PropertyOrder(9)] | |||
//public object 最小值 { get; set; } | |||
//[Category("基本属性"), Description("Maximum"), Browsable(true), PropertyOrder(8)] | |||
//public string 最大值1 { get; set; } | |||
//[Category("基本属性"), Description("Minimum"), Browsable(true), PropertyOrder(9)] | |||
//public object 最小值1 { get; set; } | |||
//[Category("基本属性"), Description("Interval"), Browsable(true), PropertyOrder(10)] | |||
//public object 间隔 { get; set; } | |||
//[Category("基本属性"), Description("左边距"), Browsable(true), PropertyOrder(11)] | |||
//public string 左边距 { get; set; } | |||
//[Category("基本属性"), Description("上边距"), Browsable(true), PropertyOrder(12)] | |||
//public string 上边距 { get; set; } | |||
//事件处理中心 | |||
private string _点击事件; | |||
private string _值改变事件; | |||
private string _定时触发; | |||
private string _勾选事件; | |||
private string _取消勾选事件; | |||
private ObservableCollection<EventReceiveMessage> _接收消息集; | |||
[Category("事件-内部触发"), Description("ClickExec"), Browsable(true), PropertyOrder(1)] | |||
public string 点击事件 | |||
{ | |||
get | |||
{ | |||
return _点击事件; | |||
} | |||
set | |||
{ | |||
if (_点击事件 == value) | |||
return; | |||
_点击事件 = value; | |||
OnPropertyChanged("点击事件"); | |||
} | |||
} | |||
[Category("事件-内部触发"), Description("ValueChangedExecute"), Browsable(true), PropertyOrder(2)] | |||
public string 值改变事件 | |||
{ | |||
get | |||
{ | |||
return _值改变事件; | |||
} | |||
set | |||
{ | |||
if (_值改变事件 == value) | |||
return; | |||
_值改变事件 = value; | |||
OnPropertyChanged("值改变事件"); | |||
} | |||
} | |||
[Category("事件-内部触发"), Description("TikcExecute"), Browsable(true), PropertyOrder(3)] | |||
public string 定时触发 | |||
{ | |||
get | |||
{ | |||
return _定时触发; | |||
} | |||
set | |||
{ | |||
if (_定时触发 == value) | |||
return; | |||
_定时触发 = value; | |||
OnPropertyChanged("定时触发"); | |||
} | |||
} | |||
[Category("事件-内部触发"), Description("CheckedExec"), Browsable(true), PropertyOrder(4)] | |||
public string 勾选事件 | |||
{ | |||
get | |||
{ | |||
return _勾选事件; | |||
} | |||
set | |||
{ | |||
if (_勾选事件 == value) | |||
return; | |||
_勾选事件 = value; | |||
OnPropertyChanged("勾选事件"); | |||
} | |||
} | |||
[Category("事件-内部触发"), Description("UnCheckedExec"), Browsable(true), PropertyOrder(5)] | |||
public string 取消勾选事件 | |||
{ | |||
get | |||
{ | |||
return _取消勾选事件; | |||
} | |||
set | |||
{ | |||
if (_取消勾选事件 == value) | |||
return; | |||
_取消勾选事件 = value; | |||
OnPropertyChanged("取消勾选事件"); | |||
} | |||
} | |||
[Category("外部-内部接收消息集"), Description("EventReceiveNameList"), Browsable(true), PropertyOrder(2)] | |||
public ObservableCollection<EventReceiveMessage> 接收消息集 | |||
{ | |||
get | |||
{ | |||
return _接收消息集; | |||
} | |||
set | |||
{ | |||
if (_接收消息集 == value) | |||
return; | |||
_接收消息集 = value; | |||
OnPropertyChanged("接收消息集"); | |||
} | |||
} | |||
//private DataTypeEnum _数据来源类型; | |||
//[Category("*数据绑定模块*"), Description("DataSouceType"), Browsable(true), PropertyOrder(1)] | |||
//public DataTypeEnum 数据来源类型 | |||
//{ | |||
// get | |||
// { | |||
// return _数据来源类型; | |||
// } | |||
// set | |||
// { | |||
// if (_数据来源类型 == value) | |||
// return; | |||
// _数据来源类型 = value; | |||
// OnPropertyChanged("数据来源类型"); | |||
// } | |||
//} | |||
private string _设备名称; | |||
[Category("*数据绑定模块*"), Description("DeviceName"), Browsable(true), PropertyOrder(2)] | |||
public string 设备名称 | |||
{ | |||
get | |||
{ | |||
return _设备名称; | |||
} | |||
set | |||
{ | |||
if (_设备名称 == value) | |||
return; | |||
_设备名称 = value; | |||
OnPropertyChanged("设备名称"); | |||
} | |||
} | |||
private string _设备解析变量; | |||
[Category("*数据绑定模块*"), Description("DeviceValuleName"), Browsable(true), PropertyOrder(3)] | |||
public string 设备解析变量 | |||
{ | |||
get | |||
{ | |||
return _设备解析变量; | |||
} | |||
set | |||
{ | |||
if (_设备解析变量 == value) | |||
return; | |||
_设备解析变量 = value; | |||
OnPropertyChanged("设备解析变量"); | |||
} | |||
} | |||
private InterfaceModeEnum _接口类型; | |||
[Category("*数据绑定模块*"), Description("InterfaceMode"), Browsable(true), PropertyOrder(4)] | |||
public InterfaceModeEnum 接口类型 | |||
{ | |||
get | |||
{ | |||
return _接口类型; | |||
} | |||
set | |||
{ | |||
if (_接口类型 == value) | |||
return; | |||
_接口类型 = value; | |||
OnPropertyChanged("接口类型"); | |||
} | |||
} | |||
private string _接口参数; | |||
[Category("*数据绑定模块*"), Description("InterfaceParameters"), Browsable(true), PropertyOrder(5)] | |||
public string 接口参数 | |||
{ | |||
get | |||
{ | |||
return _接口参数; | |||
} | |||
set | |||
{ | |||
if (_接口参数 == value) | |||
return; | |||
_接口参数 = value; | |||
OnPropertyChanged("接口参数"); | |||
} | |||
} | |||
private string _数据来源变量; | |||
[Category("*数据绑定模块*"), Description("DataSouceInformation"), Browsable(true), PropertyOrder(4)] | |||
public string 连接信息 | |||
{ | |||
get | |||
{ | |||
return _数据来源变量; | |||
} | |||
set | |||
{ | |||
if (_数据来源变量 == value) | |||
return; | |||
_数据来源变量 = value; | |||
OnPropertyChanged("连接信息"); | |||
} | |||
} | |||
private string _数据源; | |||
[Category("*数据绑定模块*"), Description("FDataSouce"), Browsable(true), PropertyOrder(5)] | |||
public string 数据源 | |||
{ | |||
get | |||
{ | |||
return _数据源; | |||
} | |||
set | |||
{ | |||
if (_数据源 == value) | |||
return; | |||
_数据源 = value; | |||
OnPropertyChanged("数据源"); | |||
} | |||
} | |||
private string _代码过滤脚本; | |||
[Category("*数据绑定模块*"), Description("Code"), Browsable(true), PropertyOrder(6)] | |||
public string 代码过滤脚本 | |||
{ | |||
get | |||
{ | |||
return _代码过滤脚本; | |||
} | |||
set | |||
{ | |||
if (_代码过滤脚本 == value) | |||
return; | |||
_代码过滤脚本 = value; | |||
OnPropertyChanged("代码过滤脚本"); | |||
} | |||
} | |||
private string _数据结果; | |||
[Category("*数据绑定模块*"), Description("GenerateData"), Browsable(true), PropertyOrder(7)] | |||
public string 数据结果 | |||
{ | |||
get | |||
{ | |||
return _数据结果; | |||
} | |||
set | |||
{ | |||
if (_数据结果 == value) | |||
return; | |||
_数据结果 = value; | |||
OnPropertyChanged("数据结果"); | |||
} | |||
} | |||
private int _定时调用; | |||
[Category("*数据绑定模块*"), Description("TimeCount"), Browsable(true), PropertyOrder(100)] | |||
public int 定时间隔 | |||
{ | |||
get | |||
{ | |||
return _定时调用; | |||
} | |||
set | |||
{ | |||
if (_定时调用 == value) | |||
return; | |||
_定时调用 = value; | |||
OnPropertyChanged("定时间隔"); | |||
} | |||
} | |||
} | |||
} |
@@ -170,7 +170,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComputerTestDemo", "Compute | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.加载UI程序", "5.加载UI程序", "{1DA0F827-5F3D-4B87-9B51-6C0BF5365A3F}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MinimalistUI", "BPASmartClient.MinimalistUI\BPASmartClient.MinimalistUI.csproj", "{AE49009F-B7D9-482E-AD1F-4514435272E1}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MinimalistUI", "BPASmartClient.MinimalistUI\BPASmartClient.MinimalistUI.csproj", "{AE49009F-B7D9-482E-AD1F-4514435272E1}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.配置工具", "6.配置工具", "{06F0B369-0483-46DD-82D2-70431FB505C1}" | |||
EndProject | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BeDesignerSCADA", "BeDesignerSCADA\BeDesignerSCADA.csproj", "{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
@@ -1566,6 +1570,26 @@ Global | |||
{AE49009F-B7D9-482E-AD1F-4514435272E1}.Release|x64.Build.0 = Release|Any CPU | |||
{AE49009F-B7D9-482E-AD1F-4514435272E1}.Release|x86.ActiveCfg = Release|Any CPU | |||
{AE49009F-B7D9-482E-AD1F-4514435272E1}.Release|x86.Build.0 = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|ARM64.ActiveCfg = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|ARM64.Build.0 = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|x64.Build.0 = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Debug|x86.Build.0 = Debug|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|ARM.Build.0 = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|ARM64.ActiveCfg = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|ARM64.Build.0 = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|x64.ActiveCfg = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|x64.Build.0 = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|x86.ActiveCfg = Release|Any CPU | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47}.Release|x86.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -1645,6 +1669,8 @@ Global | |||
{8940F1E2-693D-407E-AD03-722718860609} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | |||
{1DA0F827-5F3D-4B87-9B51-6C0BF5365A3F} = {7B0175AD-BB74-4A98-B9A7-1E289032485E} | |||
{AE49009F-B7D9-482E-AD1F-4514435272E1} = {1DA0F827-5F3D-4B87-9B51-6C0BF5365A3F} | |||
{06F0B369-0483-46DD-82D2-70431FB505C1} = {7B0175AD-BB74-4A98-B9A7-1E289032485E} | |||
{DF8B4C38-39DE-4220-AB60-885CAE6D1E47} = {06F0B369-0483-46DD-82D2-70431FB505C1} | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | |||