ComponentOne的仪表提供了一个有趣的方式来显示数据。Silverlight,WPF,Windows Phone和WinRT C1Gauge的使用接口都是相同的,所以我称它们全能deep仪表盘。仪表盘不具备内置的动画功能,不支持标准的XAML动画技术。本博客文章描述了一个常见的场景,并展示了如何应用动画的仪表盘的指针,使其值发生变化。
绑定集合内的一个值到仪表盘是很常用的使用场景。通过标准的数据绑定方式,你可以很轻松的将数据绑定到仪表盘中,并且给当前指针设置一个 double 值。
<c1:C1RadialGaugex:Name= “gauge” Value= “{Binding MyValue}” />
当底层数据的值发生变时,C1RadialGauge会即时更新,但是没有任何动画。在某些平台上,尤其是像WinRT和Windows Phone,一个小动画可以为应用程序增加亮点。
定制C1AnimatedGauge
自定义C1AnimatedGauge类继承自C1RadialGauge(你可以继承任何类型的仪表盘),它使Storyboard当前值变化后会产生动画效果。这减少了你填写更新代码的工作,并开始故事板每次值的变化。所以,更重要的是针对MVVM的兼容性。 C1AnimatedGauge类还增加了Duration和EasingFunction属性的控制,这样你就可以很容易地进行修改的动画。
public class C1AnimatedGauge : C1.Silverlight.Gauge.C1RadialGauge
{
/// <summary>
/// Gets or sets the target for the control's Value property.
/// </summary>
public double AnimatedValue
{
get { return (double)GetValue(AnimatedValueProperty); }
set { SetValue(AnimatedValueProperty, value); }
}
/// <summary>
/// Identifies the <see cref="AnimatedValue"/> dependency property.
/// </summary>
public static readonly DependencyProperty AnimatedValueProperty =
DependencyProperty.Register(
"AnimatedValue", typeof(double), typeof(C1AnimatedGauge),
new PropertyMetadata(OnTargetValuePropertyChanged));
static void OnTargetValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// get animated gauge
var ag = (C1AnimatedGauge)d;
// create animation
var da = new DoubleAnimation();
da.To = (double)e.NewValue;
da.Duration = new Duration(TimeSpan.FromMilliseconds(ag.Duration));
Storyboard.SetTargetProperty(da, new PropertyPath("Value"));
Storyboard.SetTarget(da, d);
// apply easing function
var ef = ag.EasingFunction;
if (ef == null)
{
var ee = new ElasticEase();
ee.Oscillations = 1;
ee.Springiness = 3;
ef = ee;
}
da.EasingFunction = ef;
// play animation
var sb = new Storyboard();
sb.Children.Add(da);
sb.Begin();
}
/// <summary>
/// Gets or sets the easing function that animates the gauge pointer.
/// </summary>
public IEasingFunction EasingFunction
{
get { return (IEasingFunction)GetValue(EasingFunctionProperty); }
set { SetValue(EasingFunctionProperty, value); }
}
/// <summary>
/// Identifies the <see cref="EasingFunction"/> dependency property.
/// </summary>
public static readonly DependencyProperty EasingFunctionProperty =
DependencyProperty.Register(
"EasingFunction", typeof(IEasingFunction), typeof(C1AnimatedGauge),
new PropertyMetadata(null));
/// <summary>
/// Gets or sets the duration of the animation, in milliseconds.
/// </summary>
public double Duration
{
get { return (double)GetValue(DurationProperty); }
set { SetValue(DurationProperty, value); }
}
/// <summary>
/// Identifies the <see cref="Duration"/> dependency property.
/// </summary>
public static readonly DependencyProperty DurationProperty =
DependencyProperty.Register(
"Duration", typeof(double), typeof(C1AnimatedGauge),
new PropertyMetadata(250.0));
}
添加该类添加到项目中,建立的C1AnimatedGauge类替换C1RadialGauge类。然后绑定或设置AnimatedValue属性查看动画效果。
Example:
<local:C1AnimatedGauge x:Name="gauge" Duration="800">
<local:C1AnimatedGauge.EasingFunction>
<ElasticEase Oscillations="3" Springiness="3"/>
</local:C1AnimatedGauge.EasingFunction>
<c1:C1GaugeMark Interval="10" />
</local:C1AnimatedGauge>
private void btnQ1_Click(object sender, RoutedEventArgs e)
{
// animate a changed value
gauge.AnimatedValue = 20;
}
注意,这里设置了Duration 属性为800 毫秒来定制指针的缓动效果。
以上代码同样适用于WPF, Silverlight, Windows Phone 甚至是WinRT XAML.。在WinRT 中使用时,需要添加以下引用:
WinRT Differences: // add or change these lines of code for C1AnimatedGauge in WinRT da.EnableDependentAnimation = true; Storyboard.SetTargetProperty(da, "Value");
下载 Demo: