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 FurnaceUI.Controls
{
///
/// FoupList.xaml 的交互逻辑
///
public partial class FoupList : UserControl
{
public FoupList()
{
InitializeComponent();
}
///
/// 使用动画的方式来更新值
///
/// 当前的数据值信息
/// 动画的时间,单位,毫秒
public void SetValue(float value, double time = 300)
{
SingleAnimation animation = new SingleAnimation(value, TimeSpan.FromMilliseconds(time));
BeginAnimation(ValueProperty, animation);
}
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(float), typeof(FoupList),
new PropertyMetadata(0f, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置数值的当前值,应该处于最小值和最大值之间
///
public float Value
{
get { return (float)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
///
/// 获取或设置数值的起始值,默认为0
///
public float ValueStart
{
get { return (float)GetValue(ValueStartProperty); }
set { SetValue(ValueStartProperty, value); }
}
// Using a DependencyProperty as the backing store for ValueStart. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueStartProperty =
DependencyProperty.Register("ValueStart", typeof(float), typeof(FoupList),
new PropertyMetadata(0f, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置Wafer的分割段数,最小为2,最大1000,默认为10
///
public int SegmentCount
{
get { return (int)GetValue(SegmentCountProperty); }
set { SetValue(SegmentCountProperty, value); }
}
// Using a DependencyProperty as the backing store for SegmentCount. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SegmentCountProperty =
DependencyProperty.Register("SegmentCount", typeof(int), typeof(FoupList),
new PropertyMetadata(25, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置WaferList的颜色
///
public Color FoupListColor
{
get { return (Color)GetValue(FoupListProperty); }
set { SetValue(FoupListProperty, value); }
}
// Using a DependencyProperty as the backing store for TemperatureColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FoupListProperty =
DependencyProperty.Register("FoupListColor", typeof(Color), typeof(FoupList),
new PropertyMetadata(Colors.Tomato, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置WaferList的颜色
///
public Color FoupListBackColor
{
get { return (Color)GetValue(FoupListBackColorProperty); }
set { SetValue(FoupListBackColorProperty, value); }
}
// Using a DependencyProperty as the backing store for TemperatureBackColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FoupListBackColorProperty =
DependencyProperty.Register("FoupListBackColor", typeof(Color), typeof(FoupList),
new PropertyMetadata(Colors.Silver, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置是否显示WaferList的数值
///
public bool IsRenderText
{
get { return (bool)GetValue(IsRenderTextProperty); }
set { SetValue(IsRenderTextProperty, value); }
}
// Using a DependencyProperty as the backing store for IsRenderText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsRenderTextProperty =
DependencyProperty.Register("IsRenderText", typeof(bool), typeof(FoupList),
new PropertyMetadata(false, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置左侧的单位显示文本,默认是空
///
public string LeftUnitText
{
get { return (string)GetValue(LeftUnitTextProperty); }
set { SetValue(LeftUnitTextProperty, value); }
}
// Using a DependencyProperty as the backing store for LeftUnitText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LeftUnitTextProperty =
DependencyProperty.Register("LeftUnitText", typeof(string), typeof(FoupList),
new PropertyMetadata(" ", new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置右侧的单位显示文本,默认是空
///
public string RightUnitText
{
get { return (string)GetValue(RightUnitTextProperty); }
set { SetValue(RightUnitTextProperty, value); }
}
// Using a DependencyProperty as the backing store for RightUnitText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RightUnitTextProperty =
DependencyProperty.Register("RightUnitText", typeof(string), typeof(FoupList),
new PropertyMetadata(" ", new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 获取或设置右侧轴的数值和左边的关系
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Func RightDataTransfer { get; set; }
///
/// 获取或设置数值的最大值,默认为100
///
public float ValueMax
{
get { return (float)GetValue(ValueMaxProperty); }
set { SetValue(ValueMaxProperty, value); }
}
// Using a DependencyProperty as the backing store for ValueMax. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueMaxProperty =
DependencyProperty.Register("ValueMax", typeof(float), typeof(FoupList),
new PropertyMetadata(100f, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
///
/// 当属性刷新的时候,进行强制更新绘图
///
///
///
public static void RenderUpdateByPropertyChanged(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
{
if (dependency is FoupList hslThermometer)
{
hslThermometer.FoupListUpdate();
}
}
///
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
FoupListUpdate();
}
private Color colorCenter = Colors.WhiteSmoke;
private Color colorBorder = Colors.Silver;
private SolidColorBrush SolidColorBrush = new SolidColorBrush();
///
/// 刷新界面信息
///
public void FoupListUpdate()
{
canvas1.Children.Clear();
int Width = (int)ActualWidth;
int Height = (int)ActualHeight;
if (Width < 20) return;
if (Height < 50) return;
float radius_mini = Height * 0.1f;
float radius_large = Height * 0.2f;
float top = radius_mini + 10;
float height_mid = Height - top - 10;
LinearGradientBrush linear = new LinearGradientBrush(
new GradientStopCollection(new List()
{
new GradientStop(colorCenter, 0.0f),
new GradientStop(colorBorder, 0.3f),
new GradientStop(colorCenter, 0.8f),
new GradientStop(colorBorder, 1.0f)
}),
new Point(0, 0),
new Point(1, 0));
//WpfUtils.FillRectangle(canvas1, Width / 2.0f - radius_mini, top, radius_mini * 2, height_mid-10, FoupListBackColor);
//WpfUtils.DrawRectangle(canvas1, Width / 2.0f - radius_mini, top, radius_mini * 2, height_mid - 10, FoupListBackColor, 2);
double x = Width / 2.0f - radius_mini;
double y = top-4;
double width = radius_mini * 2;
double height = height_mid;
WpfUtils.DrawLine(canvas1, x, y,x+width,y, linear, 4);
WpfUtils.DrawLine(canvas1, x, y+height,x+width,y+height, linear, 4);
WpfUtils.DrawLine(canvas1, x+width/2.0f, y, x + width / 2.0f, y+height, linear, 8);
WpfUtils.DrawLine(canvas1, x+width-15, y, x + width-15, y+height, linear, 8);
// 绘制刻度线,以及刻度文本
for (int i = 0; i <= SegmentCount; i++)
{
float valueTmp = i * (ValueMax - ValueStart) / SegmentCount + ValueStart;
float paintTmp = height_mid - 10 - (valueTmp - ValueStart) / (ValueMax - ValueStart) * (height_mid - 10) + top;
double lineLength = width / 2.0f;
double startX = x + width / 4.0f;
if (i > 0)
{
for (int j = 1; j < 10; j++)
{
// 绘制细小的刻度
float segment_min = (height_mid - 10) / SegmentCount / 10 * j;
if (j == 5)
{
WpfUtils.DrawLine(canvas1, startX - lineLength * 0.12f, paintTmp + segment_min, startX+lineLength, paintTmp + segment_min, Foreground, 1);
}
else
{
WpfUtils.DrawLine(canvas1, startX, paintTmp + segment_min, startX+lineLength, paintTmp + segment_min, Foreground, 1);
}
}
}
//WpfUtils.DrawLine(canvas1, Width / 2.0f - radius_mini - Width * 0.14f, paintTmp, Width / 2.0f - radius_mini - 4, paintTmp, Foreground, 1);
// 左坐标轴
//WpfUtils.DrawLine(canvas1, Width / 2.0f - radius_mini - Width * 0.1f, paintTmp, Width / 2.0f - radius_mini - 4, paintTmp, Foreground, 1);
WpfUtils.DrawLine(canvas1, startX - lineLength * 0.2f, paintTmp, startX + lineLength, paintTmp, Foreground, 1);
WpfUtils.DrawString(canvas1, RightUnitText, Foreground, new System.Drawing.RectangleF(5, 0, Width - 10, top - radius_mini), HorizontalAlignment.Right, VerticalAlignment.Center);
//WpfUtils.DrawString(canvas1, valueTmp.ToString(), Foreground, new System.Drawing.RectangleF(-5f, paintTmp - 90, Width / 2.0f - radius_mini - Width * 0.13f, 100f), HorizontalAlignment.Right, VerticalAlignment.Bottom);
float stringX = (float)(x-40);
float stringY = paintTmp-20;
float stringWidth = 40;
float stringHeight = 40;
WpfUtils.DrawString(canvas1, valueTmp.ToString(), Foreground, new System.Drawing.RectangleF(stringX, stringY, stringWidth, stringHeight), HorizontalAlignment.Left, VerticalAlignment.Center);
WpfUtils.FillTriangle(canvas1,new Point(stringX+stringWidth*0.8, stringY+stringHeight*0.5),Colors.LightGreen,8,GraphDirection.Rightward);
WpfUtils.DrawString(canvas1, LeftUnitText, Foreground, new System.Drawing.RectangleF(5, 0, Width - 10, top - radius_mini), HorizontalAlignment.Left, VerticalAlignment.Center);
}
// 绘制温度计的背景
//WpfUtils.FillRectangle(canvas1, Width / 2.0f - radius_mini * 0.7f, top, radius_mini * 1.4f, height_mid - 10, linear);
if (IsRenderText)
{
WpfUtils.DrawString(canvas1, (170-Value+1).ToString(), Foreground, Width / 2.0f - radius_large, top + height_mid+20, radius_large * 2, radius_large * 2, HorizontalAlignment.Center, VerticalAlignment.Center);
}
}
}
}