Provides attached properties to make FrameworkElements inside PivotItems responsive to SelectionChanged events by Pivots. The result is a 'slide in' effect added to the selected elements.
Inheritance: System.Windows.DependencyObject
        /// <summary>
        /// Attach the translate transform that is used
        /// for the slide in effect to a framework element.
        /// </summary>
        /// <param name="element">The framework element.</param>
        private static void AttachTransform(FrameworkElement element)
        {
            Transform          originalTransform  = element.RenderTransform;
            TranslateTransform translateTransform = SlideInEffect.GetAttachedTransform(element);

            if (translateTransform == null)
            {
                translateTransform = new TranslateTransform()
                {
                    X = 0
                };

                if (originalTransform == null)
                {
                    element.RenderTransform = translateTransform;
                }
                else
                {
                    TransformGroup transformGroup = new TransformGroup();
                    transformGroup.Children.Add(originalTransform);
                    transformGroup.Children.Add(translateTransform);
                    element.RenderTransform = transformGroup;
                }

                SlideInEffect.SetAttachedTransform(element, translateTransform);
            }
        }
 /// <summary>
 /// Unsubscribes an element from the private managers.
 /// </summary>
 /// <param name="target">The framework element.</param>
 private static void UnsubscribeFrameworkElement(FrameworkElement target)
 {
     // If element is subscribed, unsubscribe.
     if (SlideInEffect.GetIsSubscribed(target))
     {
         SlideInEffect.SetParentPivot(target, null);
         SlideInEffect.SetParentPivotItem(target, null);
         SlideInEffect.SetIsSubscribed(target, false);
     }
 }
        /// <summary>
        /// Subscribes an element to the private managers.
        /// </summary>
        /// <param name="target">The framework element.</param>
        private static void SubscribeFrameworkElement(FrameworkElement target)
        {
            if (!SlideInEffect.GetIsSubscribed(target))
            {
                // Find the parent Pivot and PivotItem.
                Pivot            pivot, pTemp;
                PivotItem        pivotItem, iTemp;
                DependencyObject parent = VisualTreeHelper.GetParent(target);

                pTemp     = null;
                pivotItem = iTemp = null;

                while ((pTemp == null) && (parent != null))
                {
                    pTemp = parent as Pivot;
                    iTemp = parent as PivotItem;

                    if (iTemp != null)
                    {
                        pivotItem = iTemp;
                    }

                    parent = VisualTreeHelper.GetParent(parent as DependencyObject);
                }

                if (parent == null || pivotItem == null)
                {
                    return;
                }
                else
                {
                    pivot = pTemp;
                }

                AttachTransform(target);
                SlideInEffect.SetParentPivot(target, pivot);
                SlideInEffect.SetParentPivotItem(target, pivotItem);
                SlideInEffect.SetIsSubscribed(target, true);
            }
        }
        /// <summary>
        /// Adds an animation corresponding to an specific framework element.
        /// Thus, the storyboard can be composed piece by piece.
        /// </summary>
        /// <param name="element">The framework element.</param>
        /// <param name="leftToRight">
        /// Indicates whether the animation should go
        /// from left to right or viceversa.
        /// </param>
        /// <param name="storyboard">A reference to the storyboard.</param>
        private static void ComposeStoryboard(FrameworkElement element, bool leftToRight, ref Storyboard storyboard)
        {
            double                        xPosition          = SlideInEffect.GetLineIndex(element) * ProportionalOffset;
            double                        from               = leftToRight ? xPosition : -xPosition;
            TranslateTransform            translateTransform = SlideInEffect.GetAttachedTransform(element);
            DoubleAnimationUsingKeyFrames animation          = new DoubleAnimationUsingKeyFrames();

            LinearDoubleKeyFrame keyFrame1 = new LinearDoubleKeyFrame();

            keyFrame1.KeyTime = TimeSpan.Zero;
            keyFrame1.Value   = from;
            animation.KeyFrames.Add(keyFrame1);

            LinearDoubleKeyFrame keyFrame2 = new LinearDoubleKeyFrame();

            keyFrame2.KeyTime = TimeSpan.FromMilliseconds(BeginTime);
            keyFrame2.Value   = from;
            animation.KeyFrames.Add(keyFrame2);

            LinearDoubleKeyFrame keyFrame3 = new LinearDoubleKeyFrame();

            keyFrame3.KeyTime = TimeSpan.FromMilliseconds(BreakTime);
            keyFrame3.Value   = from * ExponentialInterpolationWeight;
            animation.KeyFrames.Add(keyFrame3);

            EasingDoubleKeyFrame keyFrame4 = new EasingDoubleKeyFrame();

            keyFrame4.KeyTime = TimeSpan.FromMilliseconds(EndTime);
            keyFrame4.Value   = 0.0;

            keyFrame4.EasingFunction = SlideInExponentialEase;
            animation.KeyFrames.Add(keyFrame4);

            Storyboard.SetTarget(animation, translateTransform);
            Storyboard.SetTargetProperty(animation, XPropertyPath);
            storyboard.Children.Add(animation);
        }
        /// <summary>
        /// Modify the subscription of the dependency object
        /// to the private managers based on the line index value.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="e">The event arguments.</param>
        private static void OnLineIndexPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement target = obj as FrameworkElement;

            if (target == null)
            {
                throw new InvalidOperationException("The dependency object must be a framework element.");
            }

            int index = (int)e.NewValue;

            if (index < 0)
            {
                // Dettach event handlers.
                if (SlideInEffect.GetHasEventsAttached(target))
                {
                    target.Loaded   -= Target_Loaded;
                    target.Unloaded -= Target_Unloaded;
                    SlideInEffect.SetHasEventsAttached(target, false);
                }

                UnsubscribeFrameworkElement(target);
            }
            else
            {
                // Attach event handlers.
                if (!SlideInEffect.GetHasEventsAttached(target))
                {
                    target.Loaded   += Target_Loaded;
                    target.Unloaded += Target_Unloaded;
                    SlideInEffect.SetHasEventsAttached(target, true);
                }

                SubscribeFrameworkElement(target);
            }
        }