@@ -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 BPASmartClient.SCADAControl.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; | |||||
} | |||||
} | |||||
} |
@@ -16,7 +16,9 @@ namespace BPASmartClient.SCADAControl | |||||
/// 运行程序 注册事件 | /// 运行程序 注册事件 | ||||
/// </summary> | /// </summary> | ||||
void Register(); | void Register(); | ||||
/// <summary> | |||||
/// 控件类型 | |||||
/// </summary> | |||||
string ControlType { get; } | string ControlType { get; } | ||||
} | } | ||||
} | } |
@@ -0,0 +1,30 @@ | |||||
<UserControl x:Class="BPASmartClient.SCADAControl.NewConveyorBelt" | |||||
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:BPASmartClient.SCADAControl" | |||||
mc:Ignorable="d" | |||||
x:Name="gr" | |||||
Margin="0,0,0,0" | |||||
d:DesignHeight="400" d:DesignWidth="1200"> | |||||
<Grid > | |||||
<Viewbox Width="auto" Height="auto"> | |||||
<Canvas Width="{Binding ElementName=gr, Path=ActualWidth}" Height="{Binding ElementName=gr, Path=ActualHeight}"> | |||||
<Path | |||||
Tag="mp" | |||||
Margin="0" | |||||
Stroke="{Binding StrokeFillBrush, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" | |||||
StrokeDashArray="{Binding StrokeDashArray, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" | |||||
StrokeThickness="{Binding ConveyorBeltWidth, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" /> | |||||
<Path | |||||
Tag="cb" | |||||
Fill="Transparent" | |||||
Stroke="{Binding StrokeBrush, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" | |||||
StrokeThickness="{Binding StrokeThickness, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" /> | |||||
</Canvas> | |||||
</Viewbox> | |||||
</Grid> | |||||
</UserControl> |
@@ -0,0 +1,277 @@ | |||||
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 BPASmartClient.SCADAControl | |||||
{ | |||||
/// <summary> | |||||
/// NewConveyorBelt.xaml 的交互逻辑 | |||||
/// </summary> | |||||
public partial class NewConveyorBelt : UserControl, IExecutable | |||||
{ | |||||
Path Path_mp = null; | |||||
Path Path_cb = null; | |||||
Storyboard storyboard = new Storyboard(); | |||||
Storyboard storyboard1 = new Storyboard(); | |||||
public NewConveyorBelt() | |||||
{ | |||||
InitializeComponent(); | |||||
Width = 1200; | |||||
Height = 400; | |||||
this.SizeChanged += ConveyorBelt_SizeChanged; | |||||
ConveyorBeltWidth = 70; | |||||
Direction = 0; | |||||
StrokeBrush = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#00BEFA")); | |||||
StrokeDashArray = new DoubleCollection { 1.5, 1.5 }; | |||||
StrokeFillBrush = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#00BEFA")); | |||||
StrokeThickness = 2; | |||||
} | |||||
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() | |||||
{ | |||||
} | |||||
public void VisualStateManagerData() | |||||
{ | |||||
storyboard.RepeatBehavior = RepeatBehavior.Forever; | |||||
DoubleAnimation dbAscending = new DoubleAnimation | |||||
{ | |||||
From = 0, | |||||
To = 100, | |||||
Duration = new Duration(new TimeSpan(0, 0, 20)), | |||||
}; | |||||
storyboard.Children.Add(dbAscending); | |||||
Storyboard.SetTarget(dbAscending, Path_mp); | |||||
Storyboard.SetTargetProperty(dbAscending, new PropertyPath("StrokeDashOffset")); | |||||
storyboard1.RepeatBehavior = RepeatBehavior.Forever; | |||||
DoubleAnimation dbAscending1 = new DoubleAnimation | |||||
{ | |||||
From = 0, | |||||
To = -100, | |||||
Duration = new Duration(new TimeSpan(0, 0, 20)), | |||||
}; | |||||
storyboard1.Children.Add(dbAscending1); | |||||
Storyboard.SetTarget(dbAscending1, Path_mp); | |||||
Storyboard.SetTargetProperty(dbAscending1, new PropertyPath("StrokeDashOffset")); | |||||
Refursh(); | |||||
} | |||||
private void ConveyorBelt_SizeChanged(object sender, SizeChangedEventArgs e) | |||||
{ | |||||
//查找 | |||||
if (!(Path_cb != null && Path_mp != null)) | |||||
{ | |||||
foreach (Path tb in FindVisualChildren<Path>(this)) | |||||
{ | |||||
// do something with tb here | |||||
if (tb.Tag != null) | |||||
{ | |||||
if (tb.Tag.ToString() == "cb") | |||||
{ | |||||
Path_cb = tb; | |||||
} | |||||
else if (tb.Tag.ToString() == "mp") | |||||
{ | |||||
Path_mp = tb; | |||||
} | |||||
} | |||||
} | |||||
VisualStateManagerData(); | |||||
} | |||||
//传送带外边框绘制 | |||||
PathGeometry geometry = new PathGeometry(); | |||||
PathFigure pathFigure = new PathFigure(); | |||||
pathFigure.StartPoint = new Point(this.Height / 2, 0); | |||||
pathFigure.Segments.Add(new ArcSegment(new Point(this.Height / 2, this.Height), new Size(this.Height / 2, this.Height / 2), 0, false, SweepDirection.Counterclockwise, true)); | |||||
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, this.Height), true)); | |||||
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, this.Height - ConveyorBeltWidth), true)); | |||||
double innerCircle = (this.Height - (ConveyorBeltWidth * 2)) / 2;//内圆半径 | |||||
pathFigure.Segments.Add(new LineSegment(new Point(ConveyorBeltWidth + innerCircle, this.Height - ConveyorBeltWidth), true)); | |||||
pathFigure.Segments.Add(new ArcSegment(new Point(ConveyorBeltWidth + innerCircle, ConveyorBeltWidth), new Size(innerCircle, innerCircle), 0, false, SweepDirection.Clockwise, true)); | |||||
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, ConveyorBeltWidth), true)); | |||||
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, 0), true)); | |||||
pathFigure.Segments.Add(new LineSegment(new Point(this.Height / 2, 0), true)); | |||||
geometry.Figures.Add(pathFigure); | |||||
Path_cb.Data = geometry; | |||||
//传送带内部皮带绘制 | |||||
PathGeometry geometry1 = new PathGeometry(); | |||||
PathFigure pathFigure1 = new PathFigure(); | |||||
pathFigure1.StartPoint = new Point(this.Width, ConveyorBeltWidth / 2); | |||||
double innerCircle1 = (this.Height - ConveyorBeltWidth) / 2;//内圆半径 | |||||
pathFigure1.Segments.Add(new LineSegment(new Point(innerCircle1 + ConveyorBeltWidth / 2, ConveyorBeltWidth / 2), true)); | |||||
pathFigure1.Segments.Add(new ArcSegment(new Point(innerCircle1 + ConveyorBeltWidth / 2, this.Height - ConveyorBeltWidth / 2), new Size(innerCircle1, innerCircle1), 0, false, SweepDirection.Counterclockwise, true)); | |||||
pathFigure1.Segments.Add(new LineSegment(new Point(this.Width, this.Height - ConveyorBeltWidth / 2), true)); | |||||
geometry1.Figures.Add(pathFigure1); | |||||
Path_mp.Data = geometry1; | |||||
} | |||||
/// <summary> | |||||
/// 搜索指定名称的子元素 | |||||
/// </summary> | |||||
/// <typeparam name="T"></typeparam> | |||||
/// <param name="obj"></param> | |||||
/// <param name="name"></param> | |||||
/// <returns></returns> | |||||
public static T FindChild<T>(DependencyObject obj, string name) where T : FrameworkElement | |||||
{ | |||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) | |||||
{ | |||||
DependencyObject child = VisualTreeHelper.GetChild(obj, i); | |||||
if (child != null && child is T && (child as T).Name.Equals(name)) | |||||
return (T)child; | |||||
else | |||||
{ | |||||
T childOfChild = FindChild<T>(child, name); | |||||
if (childOfChild != null) | |||||
return childOfChild; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject | |||||
{ | |||||
if (depObj != null) | |||||
{ | |||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) | |||||
{ | |||||
DependencyObject child = VisualTreeHelper.GetChild(depObj, i); | |||||
if (child != null && child is T) | |||||
{ | |||||
yield return (T)child; | |||||
} | |||||
foreach (T childOfChild in FindVisualChildren<T>(child)) | |||||
{ | |||||
yield return childOfChild; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |||||
{ | |||||
(d as NewConveyorBelt)?.Refursh(); | |||||
} | |||||
private void Refursh() | |||||
{ | |||||
if (Direction == 1) | |||||
{ | |||||
storyboard.Begin(); | |||||
storyboard1.Stop(); | |||||
// VisualStateManager.GoToState(this, "Left", false); | |||||
} | |||||
else if (Direction == 2) | |||||
{ | |||||
storyboard.Stop(); | |||||
storyboard1.Begin(); | |||||
//VisualStateManager.GoToState(this, "Right", false); | |||||
} | |||||
else | |||||
{ | |||||
storyboard.Stop(); | |||||
storyboard1.Stop(); | |||||
//VisualStateManager.GoToState(this, "Stop", false); | |||||
} | |||||
} | |||||
public DoubleCollection StrokeDashArray | |||||
{ | |||||
get { return (DoubleCollection)GetValue(StrokeDashArrayProperty); } | |||||
set { SetValue(StrokeDashArrayProperty, value); } | |||||
} | |||||
public static readonly DependencyProperty StrokeDashArrayProperty = | |||||
DependencyProperty.Register("StrokeDashArray", typeof(DoubleCollection), typeof(NewConveyorBelt), | |||||
new PropertyMetadata(default, new PropertyChangedCallback(OnPropertyChanged))); | |||||
public double ConveyorBeltWidth | |||||
{ | |||||
get { return (double)GetValue(ConveyorBeltWidthProperty); } | |||||
set { SetValue(ConveyorBeltWidthProperty, value); } | |||||
} | |||||
public static readonly DependencyProperty ConveyorBeltWidthProperty = | |||||
DependencyProperty.Register("ConveyorBeltWidth", typeof(double), typeof(NewConveyorBelt), | |||||
new PropertyMetadata(50.0, new PropertyChangedCallback(OnPropertyChanged))); | |||||
public Brush StrokeFillBrush | |||||
{ | |||||
get { return (Brush)GetValue(StrokeFillBrushProperty); } | |||||
set { SetValue(StrokeFillBrushProperty, value); } | |||||
} | |||||
public static readonly DependencyProperty StrokeFillBrushProperty = | |||||
DependencyProperty.Register("StrokeFillBrush", typeof(Brush), typeof(NewConveyorBelt), | |||||
new PropertyMetadata(Brushes.LightBlue, new PropertyChangedCallback(OnPropertyChanged))); | |||||
public Brush StrokeBrush | |||||
{ | |||||
get { return (Brush)GetValue(StrokeBrushProperty); } | |||||
set { SetValue(StrokeBrushProperty, value); } | |||||
} | |||||
public static readonly DependencyProperty StrokeBrushProperty = | |||||
DependencyProperty.Register("StrokeBrush", typeof(Brush), typeof(NewConveyorBelt), | |||||
new PropertyMetadata(Brushes.LightBlue, new PropertyChangedCallback(OnPropertyChanged))); | |||||
public double StrokeThickness | |||||
{ | |||||
get { return (double)GetValue(StrokeThicknessProperty); } | |||||
set { SetValue(StrokeThicknessProperty, value); } | |||||
} | |||||
public static readonly DependencyProperty StrokeThicknessProperty = | |||||
DependencyProperty.Register("StrokeThickness", typeof(double), typeof(NewConveyorBelt), | |||||
new PropertyMetadata(1.0, new PropertyChangedCallback(OnPropertyChanged))); | |||||
[Category("值设定")] | |||||
public int Direction | |||||
{ | |||||
get { return (int)GetValue(DirectionProperty); } | |||||
set { SetValue(DirectionProperty, value); } | |||||
} | |||||
public static readonly DependencyProperty DirectionProperty = | |||||
DependencyProperty.Register("Direction", typeof(int), typeof(NewConveyorBelt), | |||||
new PropertyMetadata(0, new PropertyChangedCallback(OnPropertyChanged))); | |||||
} | |||||
} |
@@ -0,0 +1,144 @@ | |||||
using BPASmartClient.SCADAControl.Hepler; | |||||
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 BPASmartClient.SCADAControl | |||||
{ | |||||
[TemplatePart(Name = ELLIPSE, Type = typeof(FrameworkElement))] | |||||
[TemplatePart(Name = TranslateX, Type = typeof(TranslateTransform))] | |||||
public class SwitchButton : ToggleButton, IExecutable | |||||
{ | |||||
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.RunJsScipt(UnCheckedExec); | |||||
} | |||||
private void TheCheckBox_Checked(object sender, RoutedEventArgs e) | |||||
{ | |||||
Config.RunJsScipt(CheckedExec); | |||||
} | |||||
public string ControlType => "控件"; | |||||
} | |||||
} |
@@ -2,7 +2,8 @@ | |||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||
xmlns:local="clr-namespace:BPASmartClient.SCADAControl" | xmlns:local="clr-namespace:BPASmartClient.SCADAControl" | ||||
xmlns:ctrl="clr-namespace:BPASmartClient.SCADAControl"> | |||||
xmlns:ctrl="clr-namespace:BPASmartClient.SCADAControl" | |||||
xmlns:con="clr-namespace:BPASmartClient.SCADAControl.Converters"> | |||||
<!--<Style TargetType="{x:Type local:CustomControl1}"> | <!--<Style TargetType="{x:Type local:CustomControl1}"> | ||||
<Setter Property="Template"> | <Setter Property="Template"> | ||||
<Setter.Value> | <Setter.Value> | ||||
@@ -93,4 +94,42 @@ | |||||
</Setter.Value> | </Setter.Value> | ||||
</Setter> | </Setter> | ||||
</Style> | </Style> | ||||
<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"/> | |||||
<con:HalfNumberConverter x:Key="HalfNumber"/> | |||||
<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> | |||||
</ResourceDictionary> | </ResourceDictionary> |