private void OnDragCompleted(SplitterGrip grip, double change)
        {
            // if the change is negative the pop up was dragged to the left(top),
            // otherwise it was dragged to the right(bottom)

            var itemsControl = ItemsControl.ItemsControlFromItemContainer(grip.LeftChild) as SplitterItemsControl;

            if (itemsControl == null)
            {
                return;
            }

            var gripOffset = GetGripOffset(grip);
            var newOffset  = gripOffset + change;

            CoerceOffset(ref newOffset);

            var actualChange = Math.Abs(newOffset - gripOffset);
            var diffUnit     = SplitterItemsControl.GetUnitForSize(itemsControl, actualChange);

            var isLeftAbsolute  = grip.LeftChild.IsFixed;
            var isRightAbsolute = grip.RightChild.IsFixed;

            try
            {
                // we defer updating the panel, until we're done.
                itemsControl.DisallowPanelInvalidation = true;

                if (isLeftAbsolute || isRightAbsolute)
                {
                    if (isLeftAbsolute)
                    {
                        if (change < 0)
                        {
                            grip.LeftChild.Length -= actualChange;
                        }
                        else
                        {
                            grip.LeftChild.Length += actualChange;
                        }
                    }

                    if (isRightAbsolute)
                    {
                        if (change < 0)
                        {
                            grip.RightChild.Length += actualChange;
                        }
                        else
                        {
                            grip.RightChild.Length -= actualChange;
                        }
                    }
                }
                else // both use star based measurement system
                {
                    if (change < 0)
                    {
                        grip.LeftChild.Length  -= diffUnit;
                        grip.RightChild.Length += diffUnit;
                    }
                    else
                    {
                        grip.LeftChild.Length  += diffUnit;
                        grip.RightChild.Length -= diffUnit;
                    }
                }
            }
            finally
            {
                itemsControl.DisallowPanelInvalidation = false;
            }

            // we invalidate manually
            var panel = grip.ParentOfType <SplitterItemsPanel>();

            if (panel != null)
            {
                panel.InvalidateMeasure();
            }
        }
        private void MoveGrip(SplitterGrip grip, SplitterItemsControl itemsControl, double verticalChange, double horizontalChange)
        {
            var isHorizontal = grip.Orientation == Orientation.Horizontal;
            var change       = isHorizontal ? verticalChange : horizontalChange;

            var newLength = (isHorizontal ? grip.LeftChild.ActualHeight : grip.LeftChild.ActualWidth) + change;

            CoerceOffset(ref newLength);

            var coercedChange = newLength - (isHorizontal ? grip.LeftChild.ActualHeight : grip.LeftChild.ActualWidth);

            coercedChange = Math.Abs(coercedChange);

            var diffUnit = SplitterItemsControl.GetUnitForSize(itemsControl, coercedChange);

            var isLeftAbsolute  = grip.LeftChild.IsFixed;
            var isRightAbsolute = grip.RightChild.IsFixed;

            try
            {
                itemsControl.DisallowPanelInvalidation = true;

                if (isLeftAbsolute || isRightAbsolute)
                {
                    if (isLeftAbsolute)
                    {
                        if (change < 0)
                        {
                            grip.LeftChild.Length -= coercedChange;
                        }
                        else
                        {
                            grip.LeftChild.Length += coercedChange;
                        }
                    }

                    if (isRightAbsolute)
                    {
                        if (change < 0)
                        {
                            grip.RightChild.Length += coercedChange;
                        }
                        else
                        {
                            grip.RightChild.Length -= coercedChange;
                        }
                    }
                }
                else // both use star based measurement system
                {
                    if (change < 0)
                    {
                        grip.LeftChild.Length  -= diffUnit;
                        grip.RightChild.Length += diffUnit;
                    }
                    else
                    {
                        grip.LeftChild.Length  += diffUnit;
                        grip.RightChild.Length -= diffUnit;
                    }
                }
            }
            finally
            {
                itemsControl.DisallowPanelInvalidation = false;
            }

            // we invalidate manually
            var panel = grip.ParentOfType <SplitterItemsPanel>();

            if (panel != null)
            {
                panel.InvalidateMeasure();
            }
        }