/// <summary>
        /// Occurs when detaching the behavior
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();

            this.manipulationProcessor.Started   -= OnManipulationStarted;
            this.manipulationProcessor.Delta     -= OnManipulationDelta;
            this.manipulationProcessor.Completed -= OnManipulationCompleted;
            this.inertiaProcessor.Delta          -= OnManipulationDelta;
            this.inertiaProcessor.Completed      -= OnInertiaCompleted;
            this.inertiaTimer.Tick -= OnTimerTick;
            this.AssociatedObject.MouseLeftButtonUp   -= OnMouseUp;
            this.AssociatedObject.MouseLeftButtonDown -= OnMouseDown;
            this.AssociatedObject.MouseMove           -= OnMouseMove;
            this.AssociatedObject.LostMouseCapture    -= OnLostMouseCapture;
            TouchHelper.EnableInput(false);
            this.AssociatedObject.Loaded -= (s1, e1) => { };
        }
        /// <summary>
        /// Initialize the behavior
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();

            this.manipulationProcessor            = new ManipulationProcessor2D(SupportedManipulations);
            this.manipulationProcessor.Started   += OnManipulationStarted;
            this.manipulationProcessor.Delta     += OnManipulationDelta;
            this.manipulationProcessor.Completed += OnManipulationCompleted;

            this.inertiaProcessor = new InertiaProcessor2D();
            this.inertiaProcessor.TranslationBehavior.DesiredDeceleration = Deceleration;
            this.inertiaProcessor.RotationBehavior.DesiredDeceleration    = AngularDeceleration;
            this.inertiaProcessor.ExpansionBehavior.DesiredDeceleration   = ExpansionDeceleration;
            this.inertiaProcessor.Delta     += OnManipulationDelta;
            this.inertiaProcessor.Completed += OnInertiaCompleted;

            this.inertiaTimer          = new DispatcherTimer();
            this.inertiaTimer.Interval = TimeSpan.FromMilliseconds(30);
            this.inertiaTimer.Tick    += OnTimerTick;

            this.AssociatedObject.RenderTransformOrigin = new Point(0.5, 0.5);

            Move(new Point(0, 0), 0, 100);
            IsPivotActive = true;

            this.AssociatedObject.MouseLeftButtonUp   += OnMouseUp;
            this.AssociatedObject.MouseLeftButtonDown += OnMouseDown;
            this.AssociatedObject.MouseMove           += OnMouseMove;
            this.AssociatedObject.LostMouseCapture    += OnLostMouseCapture;

            TouchHelper.AddHandlers(this.AssociatedObject, new TouchHandlers
            {
                TouchDown             = OnTouchDown,
                CapturedTouchReported = OnCapturedTouchReported,
            });

            TouchHelper.EnableInput(true);

            this.AssociatedObject.Loaded += (s1, e1) =>
            {
                TouchHelper.SetRootElement(TouchHelper.GetRootElement(this.AssociatedObject));
            };
        }
        /// <summary>
        /// Initialize Touch handlers for the AssociatedObject
        /// </summary>
        private void InitializeAssociatedObject(FrameworkElement associatedObject)
        {
            if (associatedObject == null)
            {
                return;
            }
            associatedObject.MouseLeftButtonUp   += OnMouseUp;
            associatedObject.MouseLeftButtonDown += OnMouseDown;
            associatedObject.MouseMove           += OnMouseMove;
            associatedObject.LostMouseCapture    += OnLostMouseCapture;

            TouchHelper.AddHandlers(associatedObject,
                                    new TouchHandlers
            {
                TouchDown             = OnTouchDown,
                CapturedTouchReported = OnCapturedTouchReported,
                CapturedTouchUp       = OnTouchUp
            });

            TouchHelper.EnableInput(true);
            associatedObject.Loaded += AssociatedObjectLoaded;
        }
 protected virtual void Dispose(bool dispose)
 {
     // if Dispose is not called, the TouchHelper cleans it up on the next touch frame
     TouchHelper.EnableInput(false /*enable*/);
 }