为什么不能使用 XAML?这是我制作的一个量规,它非常具有可扩展性,可以绑定到您想要的任何数据。
XAML:
<UserControl x:Class="clock.ctlGauge"
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:clock"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Viewbox>
<Grid Height="300" Width="300">
<Ellipse Fill="Yellow" Stroke="Black" StrokeThickness="3" />
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="55"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="125"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="154"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="183"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="212"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="241"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="270"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="299"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="328"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="357"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="26"/>
<TranslateTransform/>
</TransformGroup>
</Line.RenderTransform>
</Line>
<TextBlock x:Name="textBlock" Height="38.436" Margin="134.688,23.438,140,0" TextWrapping="Wrap" Text="8" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold"/>
<TextBlock x:Name="textBlock_Copy" Height="38.436" Margin="0,30.221,89.375,0" TextWrapping="Wrap" Text="9" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy1" Height="38.436" Margin="0,69.376,50.938,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="34.687"><Run Text="10"/><LineBreak/><Run/></TextBlock>
<TextBlock x:Name="textBlock_Copy2" Height="38.436" Margin="0,0,42.5,72.188" TextWrapping="Wrap" Text="0" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy3" Height="38.435" Margin="0,0,89.375,38.439" TextWrapping="Wrap" Text="1" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy4" Height="38.436" Margin="134.688,0,140,31.656" TextWrapping="Wrap" Text="2" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold"/>
<TextBlock x:Name="textBlock_Copy5" Height="38.436" Margin="85.001,0,0,46.876" TextWrapping="Wrap" Text="3" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy6" Height="38.436" Margin="47.5,0,0,87.188" TextWrapping="Wrap" Text="4" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy7" Margin="35.313,128.347,0,133.217" TextWrapping="Wrap" Text="5" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy8" Height="38.436" Margin="47.5,76.159,0,0" TextWrapping="Wrap" Text="6" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
<TextBlock x:Name="textBlock_Copy9" Height="38.436" Margin="85.001,44.506,0,0" TextWrapping="Wrap" Text="7" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
<Polygon x:Name="MainPointer" Fill="Red" RenderTransformOrigin="0.5,0.5">
<Polygon.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="{Binding MainPointerAngle}"/>
<TranslateTransform/>
</TransformGroup>
</Polygon.RenderTransform>
<Polygon.Points>
<Point X="145" Y="150" />
<Point X="155" Y="150" />
<Point X="150" Y ="0" />
</Polygon.Points>
</Polygon>
<Polygon x:Name="MaxPoint" RenderTransformOrigin="0.5,0.5" Stroke="Black" StrokeThickness="1">
<Polygon.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="{Binding MaxPointAngle}"/>
<TranslateTransform/>
</TransformGroup>
</Polygon.RenderTransform>
<Polygon.Points>
<Point X="145" Y="3" />
<Point X="155" Y="3" />
<Point X="155" Y ="35" />
<Point X="150" Y="40" />
<Point X="145" Y="35" />
</Polygon.Points>
<Polygon.Fill>
<LinearGradientBrush EndPoint="1.0,0" StartPoint="0,0">
<GradientStop Color="#FFD60000" Offset="0"/>
<GradientStop Color="#FFD60000" Offset="1"/>
<GradientStop Color="#FF720000" Offset="0.5"/>
<GradientStop Color="#FFA00000" Offset="0.4"/>
<GradientStop Color="#FFA00000" Offset="0.6"/>
</LinearGradientBrush>
</Polygon.Fill>
</Polygon>
<Ellipse HorizontalAlignment="Center" VerticalAlignment="Center" Width="20" Height="20" >
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.981,0.547" StartPoint="0.008,0.547">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFB9B9B9" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</Viewbox>
</UserControl>
代码背后:
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 clock
{
/// <summary>
/// Interaction logic for ctlClock.xaml
/// </summary>
public partial class ctlGauge : UserControl
{
public static DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(MaxValue_Changed)));
public double MaxValue
{
get { return (double)GetValue(MaxValueProperty); }
set { SetValue(MaxValueProperty, value); }
}
private static void MaxValue_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
{
ctlGauge thisClass = (ctlGauge)o;
thisClass.SetMaxValue();
}
private void SetMaxValue()
{
MaxPointAngle = GetValueAngle(MaxValue);
}
public static DependencyProperty CurrentValueProperty = DependencyProperty.Register("CurrentValue", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(CurrentValue_Changed)));
public double CurrentValue
{
get { return (double)GetValue(CurrentValueProperty); }
set { SetValue(CurrentValueProperty, value); }
}
private static void CurrentValue_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
{
ctlGauge thisClass = (ctlGauge)o;
thisClass.SetCurrentValue();
}
private void SetCurrentValue()
{
MainPointerAngle = GetValueAngle(CurrentValue);
}
public static DependencyProperty MainPointerAngleProperty = DependencyProperty.Register("MainPointerAngle", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(MainPointerAngle_Changed)));
public static DependencyProperty MaxPointAngleProperty = DependencyProperty.Register("MaxPointAngle", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(MaxPointAngle_Changed)));
public double MaxPointAngle
{
get { return (double)GetValue(MaxPointAngleProperty); }
set { SetValue(MaxPointAngleProperty, value); }
}
private static void MaxPointAngle_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
{
ctlGauge thisClass = (ctlGauge)o;
thisClass.SetMaxPointAngle();
}
private void SetMaxPointAngle()
{
//Put Instance MaxPointAngle Property Changed code here
}
public double MainPointerAngle
{
get { return (double)GetValue(MainPointerAngleProperty); }
set { SetValue(MainPointerAngleProperty, value); }
}
private static void MainPointerAngle_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
{
ctlGauge thisClass = (ctlGauge)o;
thisClass.SetMainPointerAngle();
}
private void SetMainPointerAngle()
{
//Put Instance MainPointerAngle Property Changed code here
}
public ctlGauge()
{
InitializeComponent();
SetCurrentValue();
SetMaxValue();
}
private double GetValueAngle(double value)
{
double dAngle = 125 + (value * 29);
if (dAngle > 360)
{
dAngle -= 360;
if (dAngle > 56)
dAngle = 56;
}
else if (dAngle < 124)
dAngle = 124;
return dAngle;
}
}
}
测试窗口:
<Window x:Class="clock.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:clock"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<local:ctlGauge CurrentValue="{Binding ElementName=sldPointerAngle, Path=Value}" MaxValue="{Binding ElementName=sldMaxAngle, Path=Value}" Grid.ColumnSpan="3" />
<TextBlock Text="Pointer Value:" HorizontalAlignment="Right" Grid.Row="1" />
<Slider Name="sldPointerAngle" Grid.Row="1" Grid.Column="1" Minimum="-1" Maximum="11" Value="0" />
<TextBlock Grid.Column="2" Grid.Row="1" Width="100" Text="{Binding ElementName=sldPointerAngle, Path=Value}" />
<TextBlock Text="Max Value:" HorizontalAlignment="Right" Grid.Row="2" />
<Slider Name="sldMaxAngle" Grid.Row="2" Minimum="0" Grid.Column="1" Maximum="10" Value="9" />
<TextBlock Grid.Column="2" Grid.Row="2" Width="100" Text="{Binding ElementName=sldMaxAngle, Path=Value}" />
</Grid>
</Window>
你当然可以稍微修饰一下仪表。
编辑:使用图像而不是多边形:
<UserControl x:Class="clock.ctlGauge"
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:clock"
mc:Ignorable="d"
d:DesignHeight="256" d:DesignWidth="256" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Viewbox>
<Grid Height="256" Width="256">
<Image Name="imgBack" Source="images/Yellowback.png" />
<Image Name="imgBigPointer" Source="images/Pointer1.png" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="{Binding MainPointerAngle}"/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Image Name="imgSmallPointer" Source="images/Pointer2.png" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="{Binding MaxPointAngle}"/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Image Name="imgBorder" Source="images/CircleBorder.png" />
<Image Name="imgCenterCover" Source="images/CenterCover.png" />
</Grid>
</Viewbox>
</UserControl>
在后面的代码中:imgBack.Source = new BitmapImage(new Uri(@"c:\yourfilelocation"));