在开发应用程序时,经常需要展示一些数据的可视化形式,比如速度、温度、压力等。Silverlight3 SDK 和工具包提供了超过一百个控件,但缺少一个圆形仪表盘控件。因此,决定创建一个,目标是制作一个易于使用且外观专业的仪表盘。可以在这里看到实时演示。
在本节中,将解释如何在应用程序中使用仪表盘控件。最简单的开始方式是复制下面的模板代码片段到项目中,前提是已经引用了CircularGauge.dll和CircularGauge命名空间。
<gauge:CircularGaugeControl x:Name="myGauge1" Grid.Column="0" Grid.Row="0" Radius="150" ScaleRadius="110" ScaleStartAngle="120" ScaleSweepAngle="300" PointerLength="85" PointerCapRadius="35" MinValue="0" MaxValue="1000" MajorDivisionsCount="10" MinorDivisionsCount="5" CurrentValue="{Binding Score}" ImageSource="silverlightlogo.png" ImageSize="60,50" RangeIndicatorThickness="8" RangeIndicatorRadius="120" RangeIndicatorLightRadius="10" RangeIndicatorLightOffset="80" ScaleLabelRadius="90" ScaleLabelSize="40,20" ScaleLabelFontSize="10" ScaleLabelForeground="LightGray" MajorTickSize="10,3" MinorTickSize="3,1" MajorTickColor="LightGray" MinorTickColor="LightGray" ImageOffset="-50" GaugeBackgroundColor="Black" PointerThickness="16" OptimalRangeStartValue="300" OptimalRangeEndValue="700" DialTextOffset="40" DialText="Black" DialTextColor="Black">
</gauge:CircularGaugeControl>
CircularGauge 控件提供了多种选项来完全自定义其所有元素。大多数属性设置都很直观,所以只会在这里讨论一些。
属性的设置可以改变控件的外观。例如:
这是一个无样式控件,所以所有外观细节都在 generic.xaml 中指定的默认样式中描述。如果想创建一个新的控件模板,仪表盘控件在其控件模板中期望包含以下元素:
可以在源代码中包含的 generic.xaml 文件中找到默认样式的完整标记。
本节概述了创建此控件的主要步骤。仪表盘控件的大部分视觉表示都是使用 Expression Blend 绘制的。包含仪表盘所有元素的容器是一个 Grid。仪表盘/边缘、指针帽、指针、范围指示器光和玻璃效果(另一个带有降低透明度的椭圆)都是使用 Expression Blend 3 绘制的。绘制了形状,然后模板绑定了高度、宽度和其他属性。以下是指针的标记:
<Path x:Name="Pointer" Stroke="#FFE91C1C" StrokeThickness="2" Width="{TemplateBinding PointerLength}" Height="{TemplateBinding PointerThickness}" HorizontalAlignment="Center" Data="M1,1 L1,10 L156,6 z" Stretch="Fill" RenderTransformOrigin="0,0.5" RenderTransform="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PointerLength, Converter={StaticResource pointerCenterConverter}}">
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF890A0A" Offset="0.197"/>
<GradientStop Color="#FFC40808" Offset="1"/>
<GradientStop Color="#FFE32323" Offset="0.61"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
所有想要在代码中访问的模板项都需要适当命名。这是在用户界面和控件之间建立绑定的方式。然后重写 OnApplyTemplate 方法以获取 UI 中的命名元素。
不能在 generic.xaml 文件中定义的元素是刻度和范围指示器,它们需要在代码中绘制。主要和次要刻度标记只是已经旋转和移动的矩形,使用渲染转换。类似于刻度标记,刻度标签是已经旋转和移动的文本块。为了绘制刻度,需要计算刻度圆周上的点的位置。这可以使用以下公式计算:
给定角度和半径找到圆周上的点的公式:
x = a + r * cos(θ)
y = b + r * sin(θ)
其中:
类似于绘制刻度,使用相同的公式计算组成范围段的四个点。
最后,动画指针只涉及创建一个双精度动画,并将目标设置为指针的旋转变换角度。
void AnimatePointer(double oldcurrentvalueAngle, double newcurrentvalueAngle)
{
if (pointer != null)
{
DoubleAnimation da = new DoubleAnimation();
da.From = oldcurrentvalueAngle;
da.To = newcurrentvalueAngle;
double animDuration = Math.Abs(oldcurrentvalueAngle - newcurrentvalueAngle) * animatingSpeedFactor;
da.Duration = new Duration(TimeSpan.FromMilliseconds(animDuration));
Storyboard sb = new Storyboard();
sb.Completed += new EventHandler(sb_Completed);
sb.Children.Add(da);
Storyboard.SetTarget(da, pointer);
Storyboard.SetTargetProperty(da, new PropertyPath("(Path.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)"));
if (newcurrentvalueAngle != oldcurrentvalueAngle)
{
sb.Begin();
}
}
}