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: