← 返回所有博客文章

ComponentOne的仪表提供了一个有趣的方式来显示数据。SilverlightWPFWindows PhoneWinRT C1Gauge的使用接口都是相同的,所以我称它们全能deep仪表盘。仪表盘不具备内置的动画功能,不支持标准的XAML动画技术。本博客文章描述了一个常见的场景,并展示了如何应用动画的仪表盘的指针,使其值发生变化。

绑定集合内的一个值到仪表盘是很常用的使用场景。通过标准的数据绑定方式,你可以很轻松的将数据绑定到仪表盘中,并且给当前指针设置一个 double 值。

<c1:C1RadialGaugex:Name= “gauge”  Value= “{Binding MyValue}” />

当底层数据的值发生变时,C1RadialGauge会即时更新,但是没有任何动画。在某些平台上,尤其是像WinRTWindows Phone,一个小动画可以为应用程序增加亮点。

定制C1AnimatedGauge

自定义C1AnimatedGauge类继承自C1RadialGauge(你可以继承任何类型的仪表盘),它使Storyboard当前值变化后会产生动画效果。这减少了你填写更新代码的工作,并开始故事板每次值的变化。所以,更重要的是针对MVVM的兼容性。 C1AnimatedGauge类还增加了DurationEasingFunction属性的控制,这样你就可以很容易地进行修改的动画。

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:

Silverlight 4 – VS2010/C#

WPF 4 – VS2010/VB 

Windows Phone – VS2010/C# 

WinRT XAML – VS2012/C#