locked
Animating custom attached dependency property RRS feed

  • Question

  • Hi,

     I have this helper class to allow animating ScrollViewer::VerticalOffset

    namespace X
    {
        public class ScrollViewerAnimator 
        {
            public static readonly DependencyProperty OffsetProperty = DependencyProperty.RegisterAttached("Offset", typeof(double),
                                                                       typeof(ScrollViewerAnimator), new PropertyMetadata(0d, OnOffsetChangedCallback));
    
          
            public static double GetOffset(DependencyObject obj)
            {
                return (double)obj.GetValue(OffsetProperty);
            }
    
            public static void SetOffset(DependencyObject obj, double value)
            {
                obj.SetValue(OffsetProperty, value);
            }
    
            private static void OnOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ScrollViewer sv = d as ScrollViewer;
                if (sv != null)
                {
                    sv.ScrollToVerticalOffset((double)e.NewValue);
                }
            }
        }
    }
    

    and here is a helper method for creating the storyboard:

      public static class DependencyObjectExtension
        {
            public static void Animate(this DependencyObject target, double from, double to, string property, int duration, int starttime,
                                       EasingFunctionBase easing = null, Action completedCallback = null)
            {
                var animation = new DoubleAnimation();
                animation.From = from;
                animation.To = to;
                animation.EasingFunction = easing ?? new SineEase();
                animation.Duration = TimeSpan.FromMilliseconds(duration);
                           
    
                if (completedCallback != null)
                    animation.Completed += (s, e) => completedCallback();
    
                Storyboard.SetTarget(animation, target);
                Storyboard.SetTargetProperty(animation, property);
    
                var storyBoard = new Storyboard();
                Storyboard.AllowDependentAnimations = true;
                storyBoard.BeginTime = TimeSpan.FromMilliseconds(starttime);
                storyBoard.Duration = TimeSpan.FromMilliseconds(duration);
                storyBoard.Children.Add(animation);
                storyBoard.Begin();
            }
        }

    now if i call ScrollViewer.Animate(ScrollViewer.VerticalOffset,ScrollViewer.VerticalOffset + delta,"(ScrollViewerAnimator.Offset)", 400, 0) i will get "WinRT information: Cannot resolve TargetProperty (ScrollViewerAnimator.Offset) on specified object.". How can I qualify the ScrollViewerAnimator in the path expression such that the runtime will be able to recognize the attached property.

    Thanks,

     Stefan

    Friday, August 17, 2012 8:27 PM

Answers

  • This is a tricky problem and a known limitation dating as far back as Silverlight.

    Basically, you cannot animate a custom attached DependencyProperty because as you've noted, property path resolution simply does not work.  I can't find explicit documentation of this but you can see it in old Silverlight forum posts like this one:  http://forums.silverlight.net/t/182227.aspx

    You also cannot derive from ScrollViewer to make a custom ScrollViewer that has an Offset property, as the class is sealed.

    The next best workaround that I can think of is to create a custom UserControl that wraps a ScrollViewer, and exposes Offset values as non-attached DPs.  It's slightly hacky, but the underlying problem involves major changes to fix and will likely not be addressed until a later version of the product.

    Hope this helps,

    Matt

    


    XAML SDET Lead : Input / DirectManipulation / Accessibility

    Tuesday, August 21, 2012 6:33 PM