private void ConfigureInteractionTracker()
        {
            _tracker = InteractionTracker.Create(_compositor);

            _interactionSource = VisualInteractionSource.Create(_root);

            _interactionSource.PositionYSourceMode   = InteractionSourceMode.EnabledWithInertia;
            _interactionSource.PositionYChainingMode = InteractionChainingMode.Always;

            _tracker.InteractionSources.Add(_interactionSource);
            float refreshPanelHeight = (float)RefreshPanel.ActualHeight;

            _tracker.MaxPosition = new Vector3((float)Root.ActualWidth, 0, 0);
            _tracker.MinPosition = new Vector3(-(float)Root.ActualWidth, -refreshPanelHeight, 0);

            //The PointerPressed handler needs to be added using AddHandler method with the handledEventsToo boolean set to "true"
            //instead of the XAML element's "PointerPressed=Window_PointerPressed",
            //because the list view needs to chain PointerPressed handled events as well.
            ContentPanel.AddHandler(PointerPressedEvent, new PointerEventHandler(Window_PointerPressed), true);

            SetupPullToRefreshBehavior(refreshPanelHeight);

            //Apply spring force to pull the content back to Zero
            ConfigureRestingPoint(refreshPanelHeight);

            //
            // Use the Tracker's Position (negated) to apply to the Offset of the Image. The -{refreshPanelHeight} is to hide the refresh panel
            //
            _contentPanelVisual.StartAnimation("Offset.Y", -_tracker.GetReference().Position.Y - refreshPanelHeight);
        }
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            ThumbnailList.ItemsSource = new List <Item>
            {
                new Item {
                    Name = "Daren"
                },
                new Item {
                    Name = "Kendra"
                },
                new Item {
                    Name = "Gavin"
                },
                new Item {
                    Name = "Naia"
                },
                new Item {
                    Name = "Frodo"
                },
                new Item {
                    Name = "Stella"
                },
                new Item {
                    Name = "DJ"
                },
                new Item {
                    Name = "Stasch"
                }
            };

            // InteractionTracker and VisualInteractionSource setup.
            _root = ElementCompositionPreview.GetElementVisual(Root);
            _contentPanelVisual = ElementCompositionPreview.GetElementVisual(ContentPanel);
            _compositor         = _root.Compositor;
            _tracker            = InteractionTracker.Create(_compositor);
            _interactionSource  = VisualInteractionSource.Create(_root);
            _interactionSource.PositionYSourceMode   = InteractionSourceMode.EnabledWithInertia;
            _interactionSource.PositionYChainingMode = InteractionChainingMode.Always;
            _tracker.InteractionSources.Add(_interactionSource);
            var refreshPanelHeight = (float)RefreshPanel.ActualHeight;

            _tracker.MaxPosition = new Vector3((float)Root.ActualWidth, 0, 0);
            _tracker.MinPosition = new Vector3(-(float)Root.ActualWidth, -refreshPanelHeight, 0);

            // Use the Tacker's Position (negated) to apply to the Offset of the Image.
            // The -{refreshPanelHeight} is to hide the refresh panel
            m_positionExpression =
                _compositor.CreateExpressionAnimation($"-tracker.Position.Y - {refreshPanelHeight} ");
            m_positionExpression.SetReferenceParameter("tracker", _tracker);
            _contentPanelVisual.StartAnimation("Offset.Y", m_positionExpression);

            var resistanceModifier  = CompositionConditionalValue.Create(_compositor);
            var resistanceCondition = _compositor.CreateExpressionAnimation(
                $"-tracker.Position.Y < {pullToRefreshDistance}");

            resistanceCondition.SetReferenceParameter("tracker", _tracker);
            var resistanceAlternateValue = _compositor.CreateExpressionAnimation(
                "source.DeltaPosition.Y / 3");

            resistanceAlternateValue.SetReferenceParameter("source", _interactionSource);
            resistanceModifier.Condition = resistanceCondition;
            resistanceModifier.Value     = resistanceAlternateValue;

            var stoppingModifier  = CompositionConditionalValue.Create(_compositor);
            var stoppingCondition = _compositor.CreateExpressionAnimation(
                $"-tracker.Position.Y >= {pullToRefreshDistance}");

            stoppingCondition.SetReferenceParameter("tracker", _tracker);
            var stoppingAlternateValue = _compositor.CreateExpressionAnimation("0");

            stoppingModifier.Condition = stoppingCondition;
            stoppingModifier.Value     = stoppingAlternateValue;
            //Now add the 2 source modifiers to the InteractionTracker.
            var modifierList = new List <CompositionConditionalValue> {
                resistanceModifier, stoppingModifier
            };

            _interactionSource.ConfigureDeltaPositionYModifiers(modifierList);

            //The PointerPressed handler needs to be added using AddHandler method with the //handledEventsToo boolean set to "true"
            //instead of the XAML element's "PointerPressed=Window_PointerPressed",
            //because the list view needs to chain PointerPressed handled events as well.
            ContentPanel.AddHandler(PointerPressedEvent, new PointerEventHandler(Window_PointerPressed), true);
        }