views:

240

answers:

2

I am implementing a "marching ants" style animation by applying a StrokeDashOffset animation to a Rectangle control. I would like the animation to play when the rectangle is visible but not take up extra CPU cycles when it's hidden. Is WPF smart enough to automatically pause the animation when the affected control is hidden?

+1  A: 

I think that the animation continues, but the rendering system will realize that the rectangle is invisible and will not waste time redrawing anything.

It is possible to animate the Visibility or Opacity properties, which would not work if the animation system took the visibility into account.

Timores
+1  A: 

No. WPF is smart enough to not doing so :). The reason behind this is that you can't predict what animated property does (it can be any dependency property, not necessary related to control appearance).

You can do the following test.

XAML:

<Window x:Class="WpfApplication1.TestBrowser"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="Animation Test"
        Height="300"
        Width="300">
    <StackPanel>
            <Button Content="Toggle label" 
                            Click="ToggleLableClick"/>
            <local:MyLabel x:Name="lbl" Content="Hello" />
    </StackPanel>
</Window>

C#:

using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace WpfApplication1
{
  public partial class TestBrowser : Window
  {
    public TestBrowser()
    {
      InitializeComponent();
        var da = new DoubleAnimation(0, 10, new Duration(TimeSpan.FromSeconds(10)))
                    {
                        AutoReverse = true,
                        RepeatBehavior = RepeatBehavior.Forever
                    };
        lbl.BeginAnimation(MyLabel.DoublePropertyProperty, da);
    }

    private void ToggleLableClick(object sender, RoutedEventArgs e)
    {
        lbl.Visibility = lbl.IsVisible ? Visibility.Collapsed : Visibility.Visible;
    }
  }

    public class MyLabel : Label
    {
        public double DoubleProperty
        {
            get { return (double)GetValue(DoublePropertyProperty); }
            set { SetValue(DoublePropertyProperty, value); }
        }

        public static readonly DependencyProperty DoublePropertyProperty =
                DependencyProperty.Register("DoubleProperty", typeof(double), typeof(MyLabel), 
                new FrameworkPropertyMetadata(0.0,
                    FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange, OnDoublePropertyChanged));

        private static void OnDoublePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Trace.WriteLine(e.NewValue);
        }

        protected override Size MeasureOverride(Size constraint)
        {
            Trace.WriteLine("Measure");
            return base.MeasureOverride(constraint);
        }

        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            Trace.WriteLine("Arrange");
            return base.ArrangeOverride(arrangeBounds);
        }
    }
}

You'll notice prove of WPF brilliance in debug output: it shows DoubleProperty changes no matter control visible or not, but visibility matters when it comes to Measure/Arrange. Handlers are not called when control is collapsed, although I marked DoubleProperty as property that affects meausre and arrange...

Anvaka