<UserControl x:Class="DashboardDome.MeterPlate"
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:DashboardDome"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Viewbox>
<Border CornerRadius="200" ClipToBounds="True"
BorderBrush="{Binding PlateBorderBrush ,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}"
BorderThickness="{Binding PlateBorderThickness,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}"
Background="{Binding PlateBackground,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}">
<Grid>
<Canvas Name="canvasPlate" Width="400" Height="400">
<Canvas.RenderTransform>
<RotateTransform Angle="-45" CenterX="200" CenterY="200"/>
</Canvas.RenderTransform>
</Canvas>
<Path Data="M100 200 A100 100 0 1 1 200 300" Stroke="#B2FFFFFF" StrokeThickness="10" StrokeStartLineCap="Round" StrokeEndLineCap="Round">
<Path.RenderTransform>
<RotateTransform Angle="-45" CenterX="200" CenterY="200"/>
</Path.RenderTransform>
</Path>
<Path Name="GreenPointer" Data="M200 205,40 200,200 195,200 205" RenderTransformOrigin="0.5,0.5" Fill="Green">
<Path.RenderTransform>
<RotateTransform x:Name="GreenRtPointer" Angle="-45"/>
</Path.RenderTransform>
</Path>
<Path Name="RedPointer" Data="M200 205,40 200,200 195,200 205" RenderTransformOrigin="0.5,0.5" Fill="Red">
<Path.RenderTransform>
<RotateTransform x:Name="RedRtPointer" Angle="-45"/>
</Path.RenderTransform>
</Path>
<Path Name="BluePointer" Data="M200 205,40 200,200 195,200 205" RenderTransformOrigin="0.5,0.5" Fill="Blue">
<Path.RenderTransform>
<RotateTransform x:Name="BlueRtPointer" Angle="-45"/>
</Path.RenderTransform>
</Path>
<Path Name="YellowPointer" Data="M200 205,40 200,200 195,200 205" RenderTransformOrigin="0.5,0.5" Fill="Yellow">
<Path.RenderTransform>
<RotateTransform x:Name="YellowRtPointer" Angle="-45"/>
</Path.RenderTransform>
</Path>
<TextBlock Margin="0,200,0,0" x:Name="SetDial"
HorizontalAlignment="Center" VerticalAlignment="Center">
</TextBlock>
<TextBlock Margin="0,300,0,0" x:Name="Dial"
HorizontalAlignment="Center" VerticalAlignment="Center">
</TextBlock>
<Border Width="30" Height="30" CornerRadius="15">
<Border.Background>
<RadialGradientBrush>
<GradientStop Color="White" Offset="0.583"/>
<GradientStop Color="#FF97B5BD" Offset="1"/>
</RadialGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</Viewbox>
</Grid>
</UserControl>
<Path Name="pointer1" Data="M200 205,40 200,200 195,200 205" RenderTransformOrigin="0.5,0.5" Fill="Black">
<Path.RenderTransform>
<RotateTransform x:Name="rtPointer1" Angle="-45"/>
</Path.RenderTransform>
</Path>
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 DashboardDome
{
/// <summary>
/// MeterPlate.xaml 的交互逻辑
/// </summary>
public partial class MeterPlate : UserControl
{
/// <summary>
/// 页面显示指针数量
/// </summary>
public int PointerNum { get; set; } = 1;
/// <summary>
/// 表盘名称
/// </summary>
public string DialTextName { get; set; }
/// <summary>
/// 表盘字体颜色
/// </summary>
public Brush DialTextColor { get; set; }
/// <summary>
/// 表盘字体大小
/// </summary>
public double DialTextFontSize { get; set; }
/// <summary>
/// 是否显示当前角度
/// </summary>
public bool IsSetDialNum { get; set; } = false;
/// <summary>
/// 当前角度
/// </summary>
public string SetDialNum
{
get { return (string)GetValue(SetDialNumProperty); }
set { SetValue(SetDialNumProperty, value); }
}
public static readonly DependencyProperty SetDialNumProperty =
DependencyProperty.Register("SetDialNum", typeof(string), typeof(MeterPlate),
new PropertyMetadata(default(string), new PropertyChangedCallback(OnValuePropertyChanged)));
/// <summary>
/// 绿色指针
/// </summary>
public int GreenValue
{
get { return (int)GetValue(GreenValueProperty); }
set { SetValue(GreenValueProperty, value); }
}
public static readonly DependencyProperty GreenValueProperty =
DependencyProperty.Register("GreenValue", typeof(int), typeof(MeterPlate),
new PropertyMetadata(default(int), new PropertyChangedCallback(OnValuePropertyChanged)));
/// <summary>
/// 红色指针
/// </summary>
public int RedValue
{
get { return (int)GetValue(RedValueProperty); }
set { SetValue(RedValueProperty, value); }
}
public static readonly DependencyProperty RedValueProperty =
DependencyProperty.Register("RedValue", typeof(int), typeof(MeterPlate),
new PropertyMetadata(default(int), new PropertyChangedCallback(OnValuePropertyChanged)));
/// <summary>
/// 蓝色指针
/// </summary>
public int BlueValue
{
get { return (int)GetValue(BlueValueProperty); }
set { SetValue(BlueValueProperty, value); }
}
public static readonly DependencyProperty BlueValueProperty =
DependencyProperty.Register("BlueValue", typeof(int), typeof(MeterPlate),
new PropertyMetadata(default(int), new PropertyChangedCallback(OnValuePropertyChanged)));
/// <summary>
/// 黄色指针
/// </summary>
public int YellowValue
{
get { return (int)GetValue(YellowValueProperty); }
set { SetValue(YellowValueProperty, value); }
}
public static readonly DependencyProperty YellowValueProperty =
DependencyProperty.Register("YellowValue", typeof(int), typeof(MeterPlate),
new PropertyMetadata(default(int), new PropertyChangedCallback(OnValuePropertyChanged)));
public double Minimum
{
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(MeterPlate),
new PropertyMetadata(double.NaN, new PropertyChangedCallback(OnPropertyChanged)));
public double Maximum
{
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(MeterPlate),
new PropertyMetadata(double.NaN, new PropertyChangedCallback(OnPropertyChanged)));
public Brush PlateBackground
{
get { return (Brush)GetValue(PlateBackgroundProperty); }
set { SetValue(PlateBackgroundProperty, value); }
}
public static readonly DependencyProperty PlateBackgroundProperty =
DependencyProperty.Register("PlateBackground", typeof(Brush), typeof(MeterPlate), null);
public Brush PlateBorderBrush
{
get { return (Brush)GetValue(PlateBorderBrushProperty); }
set { SetValue(PlateBorderBrushProperty, value); }
}
public static readonly DependencyProperty PlateBorderBrushProperty =
DependencyProperty.Register("PlateBorderBrush", typeof(Brush), typeof(MeterPlate), null);
public Thickness PlateBorderThickness
{
get { return (Thickness)GetValue(PlateBorderThicknessProperty); }
set { SetValue(PlateBorderThicknessProperty, value); }
}
public static readonly DependencyProperty PlateBorderThicknessProperty =
DependencyProperty.Register("PlateBorderThickness", typeof(Thickness), typeof(MeterPlate), null);
public static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MeterPlate).DrawScale();
}
public static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MeterPlate).DrawAngle();
}
public MeterPlate()
{
InitializeComponent();
Loaded += MeterPlate_Loaded;
}
private void MeterPlate_Loaded(object sender, RoutedEventArgs e)
{
if (PointerNum == 1)
{
RedPointer.Visibility = Visibility.Hidden;
BluePointer.Visibility = Visibility.Hidden;
YellowPointer.Visibility = Visibility.Hidden;
}
if (PointerNum == 2)
{
BluePointer.Visibility = Visibility.Hidden;
YellowPointer.Visibility = Visibility.Hidden;
}
if (PointerNum == 3)
{
YellowPointer.Visibility = Visibility.Hidden;
}
this.Dial.Text = DialTextName;
this.Dial.Foreground = DialTextColor;
this.Dial.FontSize = DialTextFontSize;
if (!IsSetDialNum)
{
this.SetDial.Visibility = Visibility.Hidden;
}
this.DrawScale();
}
/// <summary>
/// 画表盘的刻度
/// </summary>
private void DrawScale()
{
this.canvasPlate.Children.Clear();
for (double i = 0; i <= this.Maximum - this.Minimum; i++)
{
//添加刻度线
Line lineScale = new Line();
if (i % 30 == 0)
{
//注意Math.Cos和Math.Sin的参数是弧度,记得将角度转为弧度制
lineScale.X1 = 200 - 170 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
lineScale.Y1 = 200 - 170 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
lineScale.Stroke = new SolidColorBrush(Colors.White);
lineScale.StrokeThickness = 3;
//添加刻度值
TextBlock txtScale = new TextBlock();
txtScale.Text = (i + this.Minimum).ToString();
txtScale.Width = 34;
txtScale.TextAlignment = TextAlignment.Center;
txtScale.Foreground = new SolidColorBrush(Colors.White);
txtScale.RenderTransform = new RotateTransform() { Angle = 45, CenterX = 17, CenterY = 8 };
txtScale.FontSize = 16;
Canvas.SetLeft(txtScale, 200 - 155 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180) - 17);
Canvas.SetTop(txtScale, 200 - 155 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180) - 10);
this.canvasPlate.Children.Add(txtScale);
}
else
{
lineScale.X1 = 200 - 180 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
lineScale.Y1 = 200 - 180 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
lineScale.Stroke = new SolidColorBrush(Colors.White);
lineScale.StrokeThickness = 1;
}
lineScale.X2 = 200 - 190 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
lineScale.Y2 = 200 - 190 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
this.canvasPlate.Children.Add(lineScale);
}
}
private void DrawAngle()
{
double step = 270.0 / (this.Maximum - this.Minimum);
if (PointerNum == 1)
{
DoubleAnimation Greenda = new DoubleAnimation(this.GreenValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.GreenRtPointer.BeginAnimation(RotateTransform.AngleProperty, Greenda);
}
if (PointerNum == 2)
{
DoubleAnimation Greenda = new DoubleAnimation(this.GreenValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.GreenRtPointer.BeginAnimation(RotateTransform.AngleProperty, Greenda);
DoubleAnimation Redda = new DoubleAnimation(this.RedValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.RedRtPointer.BeginAnimation(RotateTransform.AngleProperty, Redda);
}
if (PointerNum == 3)
{
DoubleAnimation Greenda = new DoubleAnimation(this.GreenValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.GreenRtPointer.BeginAnimation(RotateTransform.AngleProperty, Greenda);
DoubleAnimation Redda = new DoubleAnimation(this.RedValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.RedRtPointer.BeginAnimation(RotateTransform.AngleProperty, Redda);
DoubleAnimation Blueda = new DoubleAnimation(this.BlueValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.BlueRtPointer.BeginAnimation(RotateTransform.AngleProperty, Blueda);
}
if (PointerNum == 4)
{
DoubleAnimation Greenda = new DoubleAnimation(this.GreenValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.GreenRtPointer.BeginAnimation(RotateTransform.AngleProperty, Greenda);
DoubleAnimation Redda = new DoubleAnimation(this.RedValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.RedRtPointer.BeginAnimation(RotateTransform.AngleProperty, Redda);
DoubleAnimation Blueda = new DoubleAnimation(this.BlueValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.BlueRtPointer.BeginAnimation(RotateTransform.AngleProperty, Blueda);
DoubleAnimation Yellowda = new DoubleAnimation(this.YellowValue * step + 90, new Duration(TimeSpan.FromMilliseconds(200)));
this.YellowRtPointer.BeginAnimation(RotateTransform.AngleProperty, Yellowda);
}
if (IsSetDialNum)
{
this.SetDial.Text = SetDialNum + " °";
this.SetDial.Foreground = DialTextColor;
this.SetDial.FontSize = DialTextFontSize;
}
}
}
}
WPF指针
最新推荐文章于 2024-05-20 20:22:32 发布