private void ScrollViewer_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Debug.WriteLine("scrollViewer_MouseLeftButtonUp");

            if (!IsActive)
                return;

            // hide the pull down item by locating it off screen
            _pullDownItem.VerticalOffset = -ToDoItemHeight;

            // if the list was pulled down far enough, add a new item
            if (_distance > ToDoItemHeight)
            {
                var newItem = new ToDoItemViewModel("");
                var todoModel = newItem.ToModel();
                _todoManager.Save(todoModel);
                newItem.Update(todoModel);
                _todoItems.Insert(0, newItem);

                // when the new item has been rendered, use the edit interaction to place the UI
                // into edit mode
                _todoList.InvokeOnNextLayoutUpdated(() => _editInteraction.EditItem(newItem));
            }

            IsActive = false;
            _effectPlayed = false;
        }
        private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            if (!IsEnabled)
                return;

            if (IsActive)
            {
                var touchPoints = e.GetTouchPoints(_todoList);

                // if we still have two touch points continue the pinch gesture
                if (touchPoints.Count == 2)
                {
                    double currentDelta = GetDelta(touchPoints[0], touchPoints[1]);

                    double itemsOffset = 0;

                    // is the delta bigger than the initial?
                    if (currentDelta > _initialDelta)
                    {
                        double delta = currentDelta - _initialDelta;
                        itemsOffset = delta / 2;

                        // play a sound effect if the users has pinched far enough to add a new item
                        if (delta > ToDoItemHeight && !_effectPlayed)
                        {
                            _effectPlayed = true;
                            _popSound.Play();
                        }

                        _addNewThresholdReached = delta > ToDoItemHeight;

                        // stretch and fade in the new item
                        var cappedDelta = Math.Min(ToDoItemHeight, delta);
                        ((ScaleTransform)_pullDownItem.RenderTransform).ScaleY = cappedDelta / ToDoItemHeight;
                        _pullDownItem.Opacity = cappedDelta / ToDoItemHeight;

                        // set the text
                        _pullDownItem.Text = cappedDelta < ToDoItemHeight ? "Pull to create new item" : "Release to add new item";
                    }

                    // offset all the items in the list so that they 'part'
                    for (int i = 0; i < _todoItems.Count; i++)
                    {
                        var container = _todoList.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
                        var translateTransform = (TranslateTransform)container.RenderTransform;
                        translateTransform.Y = i <= _itemOneIndex ? -itemsOffset : itemsOffset;
                    }
                }
                else
                {
                    // if we no longer have two touch points, end the interactions
                    IsActive = false;

                    RefreshView();

                    // hide the pull-down item
                    _pullDownItem.VerticalOffset = -ToDoItemHeight;

                    if (_addNewThresholdReached)
                    {
                        var newItem = new ToDoItemViewModel("");
                        var todoModel = newItem.ToModel();
                        _todoManager.Save(todoModel);
                        newItem.Update(todoModel);

                        _todoItems.Insert(_itemOneIndex, newItem);

                        // when the new item has been rendered, use the edit interaction to place the UI
                        // into edit mode
                        _todoList.InvokeOnNextLayoutUpdated(() => _editInteraction.EditItem(newItem));
                    }
                }
            }
            else
            {
                var touchPoints = e.GetTouchPoints(_todoList);
                if (touchPoints.Count == 2)
                {
                    _addNewThresholdReached = false;
                    _effectPlayed = false;

                    // find the items that were touched ...
                    var itemOne = GetToDoItemAtLocation(touchPoints[0].Position);
                    var itemTwo = GetToDoItemAtLocation(touchPoints[1].Position);

                    if (itemOne != null && itemTwo != null)
                    {
                        // find their indices
                        _itemOneIndex = _todoItems.IndexOf(itemOne);
                        _itemTwoIndex = _todoItems.IndexOf(itemTwo);

                        // are the two items next to each other?
                        if (Math.Abs(_itemOneIndex - _itemTwoIndex) == 1)
                        {
                            if (_itemOneIndex > _itemTwoIndex)
                            {
                                // We need to swap the two
                                int tempIndex = _itemOneIndex;
                                _itemOneIndex = _itemTwoIndex;
                                _itemTwoIndex = tempIndex;

                                var tempItem = itemOne;
                                itemOne = itemTwo;
                                itemTwo = tempItem;
                            }
                            IsActive = true;

                            // determine where to locate the new item placeholder
                            var itemOneContainer = _todoList.ItemContainerGenerator.ContainerFromItem(itemOne) as FrameworkElement;
                            var itemOneContainerPos = itemOneContainer.GetRelativePosition(_todoList);
                            _newItemLocation = itemOneContainerPos.Y + ToDoItemHeight - (ToDoItemHeight / 2);

                            // position the placeholder and add a scale transform
                            _pullDownItem.VerticalOffset = _newItemLocation;
                            _pullDownItem.Opacity = 0;
                            _pullDownItem.RenderTransform = new ScaleTransform()
                            {
                                ScaleY = 1,
                                CenterY = ToDoItemHeight / 2
                            };

                            // record the initial distance between touch point
                            _initialDelta = GetDelta(touchPoints[0], touchPoints[1]);

                            AddTranslateTransfromToElements();

                            _pullDownItem.Opacity = 1;
                        }
                    }
                }
            }
        }