private void CancelPointer(PointerRoutedEventArgs e)
        {
            // When the user stops interacting with the column headers, the drag mode needs to be reset and any open popups closed.
            if (this.OwningGrid != null)
            {
                this.IsPressed     = false;
                this.IsPointerOver = false;

                DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;
                bool setResizeCursor = false;

                if (this.OwningGrid.ColumnHeaders != null)
                {
                    Point pointerPositionHeaders = e.GetCurrentPoint(this.OwningGrid.ColumnHeaders).Position;
                    setResizeCursor = interactionInfo.DragMode == DragMode.Resize && pointerPositionHeaders.X > 0 && pointerPositionHeaders.X < this.OwningGrid.ActualWidth;
                }

                if (!setResizeCursor)
                {
                    SetOriginalCursor();
                }

                if (interactionInfo.DragPointerId == e.Pointer.PointerId)
                {
                    this.OwningGrid.ResetColumnHeaderInteractionInfo();
                }

                if (setResizeCursor)
                {
                    SetResizeCursor(e.Pointer, e.GetCurrentPoint(this).Position);
                }

                ApplyState(false /*useTransitions*/);
            }
        }
        private void DataGridColumnHeader_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            if (this.OwningColumn == null || this.OwningGrid == null || this.OwningGrid.ColumnHeaders == null || !this.IsEnabled)
            {
                return;
            }

            PointerPoint pointerPoint    = e.GetCurrentPoint(this);
            Point        pointerPosition = pointerPoint.Position;
            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (pointerPoint.IsInContact && (interactionInfo.DragPointerId == 0 || interactionInfo.DragPointerId == e.Pointer.PointerId))
            {
                Point pointerPositionHeaders = e.GetCurrentPoint(this.OwningGrid.ColumnHeaders).Position;
                bool  handled = false;

                Debug.Assert(this.OwningGrid.Parent is UIElement, "Expected owning DataGrid's parent to be a UIElement.");

                double distanceFromLeft  = pointerPosition.X;
                double distanceFromRight = this.ActualWidth - distanceFromLeft;

                OnPointerMove_Resize(ref handled, pointerPositionHeaders);
                OnPointerMove_Reorder(ref handled, e.Pointer, pointerPosition, pointerPositionHeaders, distanceFromLeft, distanceFromRight);

                // If nothing was done about moving the pointer while the pointer is down, remember the dragging, but do not
                // claim the event was actually handled.
                if (interactionInfo.DragMode == DragMode.PointerPressed &&
                    interactionInfo.PressedPointerPositionHeaders.HasValue &&
                    Math.Abs(interactionInfo.PressedPointerPositionHeaders.Value.X - pointerPositionHeaders.X) + Math.Abs(interactionInfo.PressedPointerPositionHeaders.Value.Y - pointerPositionHeaders.Y) > DATAGRIDCOLUMNHEADER_dragThreshold)
                {
                    interactionInfo.DragMode      = DragMode.Drag;
                    interactionInfo.DragPointerId = e.Pointer.PointerId;
                }

                if (interactionInfo.DragMode == DragMode.Drag)
                {
                    DragDeltaEventArgs dragDeltaEventArgs = new DragDeltaEventArgs(pointerPositionHeaders.X - interactionInfo.LastPointerPositionHeaders.Value.X, pointerPositionHeaders.Y - interactionInfo.LastPointerPositionHeaders.Value.Y);
                    this.OwningGrid.OnColumnHeaderDragDelta(dragDeltaEventArgs);
                }

                interactionInfo.LastPointerPositionHeaders = pointerPositionHeaders;
            }

            SetResizeCursor(e.Pointer, pointerPosition);

            if (!this.IsPointerOver)
            {
                this.IsPointerOver = true;
                ApplyState(true /*useTransitions*/);
            }
        }
        private void SetOriginalCursor()
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (interactionInfo.ResizePointerId != 0)
            {
                Debug.Assert(interactionInfo.OriginalCursor != null, "Expected non-null interactionInfo.OriginalCursor.");

                Window.Current.CoreWindow.PointerCursor = interactionInfo.OriginalCursor;
                interactionInfo.ResizePointerId         = 0;
            }
        }
        private void DataGridColumnHeader_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (this.OwningGrid != null && !(bool)e.NewValue)
            {
                this.IsPressed     = false;
                this.IsPointerOver = false;

                DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

                if (interactionInfo.CapturedPointer != null)
                {
                    ReleasePointerCapture(interactionInfo.CapturedPointer);
                }

                ApplyState(false /*useTransitions*/);
            }
        }
        private void DataGridColumnHeader_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            if (!this.IsEnabled || this.OwningGrid == null)
            {
                return;
            }

            this.IsPointerOver = false;

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (interactionInfo.DragMode == DragMode.None && interactionInfo.ResizePointerId == e.Pointer.PointerId)
            {
                SetOriginalCursor();
            }

            ApplyState(true /*useTransitions*/);
        }
        private bool TrySetResizeColumn(uint pointerId, DataGridColumn column)
        {
            // If Datagrid.CanUserResizeColumns == false, then the column can still override it
            if (this.OwningGrid != null && CanResizeColumn(column))
            {
                DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

                Debug.Assert(interactionInfo.DragMode != DragMode.None, "Expected _dragMode other than None.");

                interactionInfo.DragColumn    = column;
                interactionInfo.DragMode      = DragMode.Resize;
                interactionInfo.DragPointerId = pointerId;

                return(true);
            }

            return(false);
        }
        private void SetResizeCursor(Pointer pointer, Point pointerPosition)
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (interactionInfo.DragMode != DragMode.None || this.OwningGrid == null || this.OwningColumn == null)
            {
                return;
            }

            // Set mouse cursor if the column can be resized.
            double         distanceFromLeft  = pointerPosition.X;
            double         distanceFromTop   = pointerPosition.Y;
            double         distanceFromRight = this.ActualWidth - distanceFromLeft;
            DataGridColumn currentColumn     = this.OwningColumn;
            DataGridColumn previousColumn    = null;

            if (!(this.OwningColumn is DataGridFillerColumn))
            {
                previousColumn = this.OwningGrid.ColumnsInternal.GetPreviousVisibleNonFillerColumn(currentColumn);
            }

            int  resizeRegionWidth = pointer.PointerDeviceType == PointerDeviceType.Touch ? DATAGRIDCOLUMNHEADER_resizeRegionWidthLoose : DATAGRIDCOLUMNHEADER_resizeRegionWidthStrict;
            bool nearCurrentResizableColumnRightEdge = distanceFromRight <= resizeRegionWidth && currentColumn != null && CanResizeColumn(currentColumn) && distanceFromTop < this.ActualHeight;
            bool nearPreviousResizableColumnLeftEdge = distanceFromLeft <= resizeRegionWidth && previousColumn != null && CanResizeColumn(previousColumn) && distanceFromTop < this.ActualHeight;

            if (this.OwningGrid.IsEnabled && (nearCurrentResizableColumnRightEdge || nearPreviousResizableColumnLeftEdge))
            {
                CoreCursor currentCursor = CoreWindow.GetForCurrentThread().PointerCursor;
                if (currentCursor != null && currentCursor.Type != CoreCursorType.SizeWestEast)
                {
                    interactionInfo.OriginalCursor  = currentCursor;
                    interactionInfo.ResizePointerId = pointer.PointerId;
                    CoreWindow.GetForCurrentThread().PointerCursor = new CoreCursor(CoreCursorType.SizeWestEast, 0);
                }
            }
            else if (interactionInfo.ResizePointerId == pointer.PointerId)
            {
                SetOriginalCursor();
            }
        }
        private void OnPointerMove_Resize(ref bool handled, Point pointerPositionHeaders)
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (!handled && interactionInfo.DragMode == DragMode.Resize && interactionInfo.DragColumn != null && interactionInfo.DragStart.HasValue)
            {
                Debug.Assert(interactionInfo.ResizePointerId != 0, "Expected interactionInfo.ResizePointerId other than 0.");

                // Resize column
                double pointerDelta = pointerPositionHeaders.X - interactionInfo.DragStart.Value.X;
                double desiredWidth = interactionInfo.OriginalWidth + pointerDelta;

                desiredWidth = Math.Max(interactionInfo.DragColumn.ActualMinWidth, Math.Min(interactionInfo.DragColumn.ActualMaxWidth, desiredWidth));
                interactionInfo.DragColumn.Resize(interactionInfo.DragColumn.Width.Value, interactionInfo.DragColumn.Width.UnitType, interactionInfo.DragColumn.Width.DesiredValue, desiredWidth, true);

                this.OwningGrid.UpdateHorizontalOffset(interactionInfo.OriginalHorizontalOffset);

                handled = true;
            }
        }
        private void OnPointerMove_Reorder(ref bool handled, Pointer pointer, Point pointerPosition, Point pointerPositionHeaders, double distanceFromLeft, double distanceFromRight)
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            if (handled)
            {
                return;
            }

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;
            int resizeRegionWidth = pointer.PointerDeviceType == PointerDeviceType.Touch ? DATAGRIDCOLUMNHEADER_resizeRegionWidthLoose : DATAGRIDCOLUMNHEADER_resizeRegionWidthStrict;

            // Handle entry into reorder mode
            if (interactionInfo.DragMode == DragMode.PointerPressed &&
                interactionInfo.DragColumn == null &&
                distanceFromRight > resizeRegionWidth &&
                distanceFromLeft > resizeRegionWidth &&
                interactionInfo.PressedPointerPositionHeaders.HasValue &&
                Math.Abs(interactionInfo.PressedPointerPositionHeaders.Value.X - pointerPositionHeaders.X) + Math.Abs(interactionInfo.PressedPointerPositionHeaders.Value.Y - pointerPositionHeaders.Y) > DATAGRIDCOLUMNHEADER_dragThreshold)
            {
                DragStartedEventArgs dragStartedEventArgs =
                    new DragStartedEventArgs(pointerPositionHeaders.X - interactionInfo.LastPointerPositionHeaders.Value.X, pointerPositionHeaders.Y - interactionInfo.LastPointerPositionHeaders.Value.Y);
                this.OwningGrid.OnColumnHeaderDragStarted(dragStartedEventArgs);

                handled = CanReorderColumn(this.OwningColumn);

                if (handled)
                {
                    OnPointerMove_BeginReorder(pointer.PointerId, pointerPosition);
                }
            }

            // Handle reorder mode (eg, positioning of the popup)
            if (interactionInfo.DragMode == DragMode.Reorder && this.OwningGrid.ColumnHeaders.DragIndicator != null)
            {
                DragDeltaEventArgs dragDeltaEventArgs = new DragDeltaEventArgs(pointerPositionHeaders.X - interactionInfo.LastPointerPositionHeaders.Value.X, pointerPositionHeaders.Y - interactionInfo.LastPointerPositionHeaders.Value.Y);
                this.OwningGrid.OnColumnHeaderDragDelta(dragDeltaEventArgs);

                // Find header we're hovering over
                DataGridColumn targetColumn = GetReorderingTargetColumn(pointerPositionHeaders, !this.OwningColumn.IsFrozen /*scroll*/, out var scrollAmount);

                this.OwningGrid.ColumnHeaders.DragIndicatorOffset = pointerPosition.X - interactionInfo.DragStart.Value.X + scrollAmount;
                this.OwningGrid.ColumnHeaders.InvalidateArrange();

                if (this.OwningGrid.ColumnHeaders.DropLocationIndicator != null)
                {
                    Point targetPosition = new Point(0, 0);
                    if (targetColumn == null || targetColumn == this.OwningGrid.ColumnsInternal.FillerColumn || targetColumn.IsFrozen != this.OwningColumn.IsFrozen)
                    {
                        targetColumn      = this.OwningGrid.ColumnsInternal.GetLastColumn(true /*isVisible*/, this.OwningColumn.IsFrozen /*isFrozen*/, null /*isReadOnly*/);
                        targetPosition    = targetColumn.HeaderCell.Translate(this.OwningGrid.ColumnHeaders, targetPosition);
                        targetPosition.X += targetColumn.ActualWidth;
                    }
                    else
                    {
                        targetPosition = targetColumn.HeaderCell.Translate(this.OwningGrid.ColumnHeaders, targetPosition);
                    }

                    this.OwningGrid.ColumnHeaders.DropLocationIndicatorOffset = targetPosition.X - scrollAmount;
                }

                handled = true;
            }
        }
        private void OnPointerMove_BeginReorder(uint pointerId, Point pointerPosition)
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            DataGridColumnHeader dragIndicator = new DataGridColumnHeader();

            dragIndicator.OwningColumn    = this.OwningColumn;
            dragIndicator.IsEnabled       = false;
            dragIndicator.Content         = this.Content;
            dragIndicator.ContentTemplate = this.ContentTemplate;

            Control dropLocationIndicator = new ContentControl();

            dropLocationIndicator.SetStyleWithType(this.OwningGrid.DropLocationIndicatorStyle);

            if (this.OwningColumn.DragIndicatorStyle != null)
            {
                dragIndicator.SetStyleWithType(this.OwningColumn.DragIndicatorStyle);
            }
            else if (this.OwningGrid.DragIndicatorStyle != null)
            {
                dragIndicator.SetStyleWithType(this.OwningGrid.DragIndicatorStyle);
            }

            // If the user didn't style the dragIndicator's Width, default it to the column header's width.
            if (double.IsNaN(dragIndicator.Width))
            {
                dragIndicator.Width = this.ActualWidth;
            }

            // If the user didn't style the dropLocationIndicator's Height, default to the column header's height.
            if (double.IsNaN(dropLocationIndicator.Height))
            {
                dropLocationIndicator.Height = this.ActualHeight;
            }

            // pass the caret's data template to the user for modification.
            DataGridColumnReorderingEventArgs columnReorderingEventArgs = new DataGridColumnReorderingEventArgs(this.OwningColumn)
            {
                DropLocationIndicator = dropLocationIndicator,
                DragIndicator         = dragIndicator
            };

            this.OwningGrid.OnColumnReordering(columnReorderingEventArgs);
            if (columnReorderingEventArgs.Cancel)
            {
                return;
            }

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            // The app didn't cancel, so prepare for the reorder.
            interactionInfo.DragColumn = this.OwningColumn;
            Debug.Assert(interactionInfo.DragMode != DragMode.None, "Expected _dragMode other than None.");
            interactionInfo.DragMode      = DragMode.Reorder;
            interactionInfo.DragPointerId = pointerId;
            interactionInfo.DragStart     = pointerPosition;

            // Display the reordering thumb.
            this.OwningGrid.ColumnHeaders.DragColumn            = this.OwningColumn;
            this.OwningGrid.ColumnHeaders.DragIndicator         = columnReorderingEventArgs.DragIndicator;
            this.OwningGrid.ColumnHeaders.DropLocationIndicator = columnReorderingEventArgs.DropLocationIndicator;
        }
        /// <summary>
        /// Returns the column against whose top-left the reordering caret should be positioned
        /// </summary>
        /// <param name="pointerPositionHeaders">Pointer position within the ColumnHeadersPresenter</param>
        /// <param name="scroll">Whether or not to scroll horizontally when a column is dragged out of bounds</param>
        /// <param name="scrollAmount">If scroll is true, returns the horizontal amount that was scrolled</param>
        /// <returns>The column against whose top-left the reordering caret should be positioned.</returns>
        private DataGridColumn GetReorderingTargetColumn(Point pointerPositionHeaders, bool scroll, out double scrollAmount)
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            scrollAmount = 0;
            double leftEdge = 0;

            if (this.OwningGrid.ColumnsInternal.RowGroupSpacerColumn.IsRepresented)
            {
                leftEdge = this.OwningGrid.ColumnsInternal.RowGroupSpacerColumn.ActualWidth;
            }

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;
            double rightEdge = this.OwningGrid.CellsWidth;

            if (this.OwningColumn.IsFrozen)
            {
                rightEdge = Math.Min(rightEdge, interactionInfo.FrozenColumnsWidth);
            }
            else if (this.OwningGrid.FrozenColumnCount > 0)
            {
                leftEdge = interactionInfo.FrozenColumnsWidth;
            }

            if (pointerPositionHeaders.X < leftEdge)
            {
                if (scroll &&
                    this.OwningGrid.HorizontalScrollBar != null &&
                    this.OwningGrid.HorizontalScrollBar.Visibility == Visibility.Visible &&
                    this.OwningGrid.HorizontalScrollBar.Value > 0)
                {
                    double newVal = pointerPositionHeaders.X - leftEdge;
                    scrollAmount = Math.Min(newVal, this.OwningGrid.HorizontalScrollBar.Value);
                    this.OwningGrid.UpdateHorizontalOffset(scrollAmount + this.OwningGrid.HorizontalScrollBar.Value);
                }

                pointerPositionHeaders.X = leftEdge;
            }
            else if (pointerPositionHeaders.X >= rightEdge)
            {
                if (scroll &&
                    this.OwningGrid.HorizontalScrollBar != null &&
                    this.OwningGrid.HorizontalScrollBar.Visibility == Visibility.Visible &&
                    this.OwningGrid.HorizontalScrollBar.Value < this.OwningGrid.HorizontalScrollBar.Maximum)
                {
                    double newVal = pointerPositionHeaders.X - rightEdge;
                    scrollAmount = Math.Min(newVal, this.OwningGrid.HorizontalScrollBar.Maximum - this.OwningGrid.HorizontalScrollBar.Value);
                    this.OwningGrid.UpdateHorizontalOffset(scrollAmount + this.OwningGrid.HorizontalScrollBar.Value);
                }

                pointerPositionHeaders.X = rightEdge - 1;
            }

            foreach (DataGridColumn column in this.OwningGrid.ColumnsInternal.GetDisplayedColumns())
            {
                Point  pointerPosition = this.OwningGrid.ColumnHeaders.Translate(column.HeaderCell, pointerPositionHeaders);
                double columnMiddle    = column.HeaderCell.ActualWidth / 2;
                if (pointerPosition.X >= 0 && pointerPosition.X <= columnMiddle)
                {
                    return(column);
                }
                else if (pointerPosition.X > columnMiddle && pointerPosition.X < column.HeaderCell.ActualWidth)
                {
                    return(this.OwningGrid.ColumnsInternal.GetNextVisibleColumn(column));
                }
            }

            return(null);
        }
        private void DataGridColumnHeader_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            if (this.OwningGrid == null || this.OwningColumn == null || e.Handled || !this.IsEnabled)
            {
                return;
            }

            PointerPoint pointerPoint = e.GetCurrentPoint(this);

            if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse && pointerPoint.Properties.IsLeftButtonPressed)
            {
                return;
            }

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (interactionInfo.DragPointerId != 0 && interactionInfo.DragPointerId != e.Pointer.PointerId)
            {
                return;
            }

            Point pointerPosition        = pointerPoint.Position;
            Point pointerPositionHeaders = e.GetCurrentPoint(this.OwningGrid.ColumnHeaders).Position;
            bool  handled = e.Handled;

            this.IsPressed = false;

            if (this.OwningGrid.ColumnHeaders != null)
            {
                switch (interactionInfo.DragMode)
                {
                case DragMode.PointerPressed:
                {
                    // Completed a click or tap without dragging, so raise the DataGrid.Sorting event.
                    InvokeProcessSort();
                    break;
                }

                case DragMode.Reorder:
                {
                    // Find header hovered over
                    int targetIndex = this.GetReorderingTargetDisplayIndex(pointerPositionHeaders);

                    if ((!this.OwningColumn.IsFrozen && targetIndex >= this.OwningGrid.FrozenColumnCount) ||
                        (this.OwningColumn.IsFrozen && targetIndex < this.OwningGrid.FrozenColumnCount))
                    {
                        this.OwningColumn.DisplayIndex = targetIndex;

                        DataGridColumnEventArgs ea = new DataGridColumnEventArgs(this.OwningColumn);
                        this.OwningGrid.OnColumnReordered(ea);
                    }

                    DragCompletedEventArgs dragCompletedEventArgs = new DragCompletedEventArgs(pointerPosition.X - interactionInfo.DragStart.Value.X, pointerPosition.Y - interactionInfo.DragStart.Value.Y, false);
                    this.OwningGrid.OnColumnHeaderDragCompleted(dragCompletedEventArgs);
                    break;
                }

                case DragMode.Drag:
                {
                    DragCompletedEventArgs dragCompletedEventArgs = new DragCompletedEventArgs(0, 0, false);
                    this.OwningGrid.OnColumnHeaderDragCompleted(dragCompletedEventArgs);
                    break;
                }
                }

                SetResizeCursor(e.Pointer, pointerPosition);

                // Variables that track drag mode states get reset in DataGridColumnHeader_LostPointerCapture
                if (interactionInfo.CapturedPointer != null)
                {
                    ReleasePointerCapture(interactionInfo.CapturedPointer);
                }

                this.OwningGrid.ResetColumnHeaderInteractionInfo();
                handled = true;
            }

            e.Handled = handled;

            ApplyState(true /*useTransitions*/);
        }
        private void DataGridColumnHeader_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            if (this.OwningGrid == null || this.OwningColumn == null || e.Handled || !this.IsEnabled || this.OwningGrid.ColumnHeaderInteractionInfo.DragMode != DragMode.None)
            {
                return;
            }

            PointerPoint pointerPoint = e.GetCurrentPoint(this);
            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse && !pointerPoint.Properties.IsLeftButtonPressed)
            {
                return;
            }

            Debug.Assert(interactionInfo.DragPointerId == 0, "Expected _dragPointerId is 0.");

            bool handled = e.Handled;

            this.IsPressed = true;

            if (this.OwningGrid.ColumnHeaders != null)
            {
                Point pointerPosition = pointerPoint.Position;

                if (this.CapturePointer(e.Pointer))
                {
                    interactionInfo.CapturedPointer = e.Pointer;
                }
                else
                {
                    interactionInfo.CapturedPointer = null;
                }

                Debug.Assert(interactionInfo.DragMode == DragMode.None, "Expected _dragMode equals None.");
                Debug.Assert(interactionInfo.DragColumn == null, "Expected _dragColumn is null.");
                interactionInfo.DragMode                      = DragMode.PointerPressed;
                interactionInfo.DragPointerId                 = e.Pointer.PointerId;
                interactionInfo.FrozenColumnsWidth            = this.OwningGrid.ColumnsInternal.GetVisibleFrozenEdgedColumnsWidth();
                interactionInfo.PressedPointerPositionHeaders = interactionInfo.LastPointerPositionHeaders = this.Translate(this.OwningGrid.ColumnHeaders, pointerPosition);

                double         distanceFromLeft  = pointerPosition.X;
                double         distanceFromRight = this.ActualWidth - distanceFromLeft;
                DataGridColumn currentColumn     = this.OwningColumn;
                DataGridColumn previousColumn    = null;
                if (!(this.OwningColumn is DataGridFillerColumn))
                {
                    previousColumn = this.OwningGrid.ColumnsInternal.GetPreviousVisibleNonFillerColumn(currentColumn);
                }

                int resizeRegionWidth = e.Pointer.PointerDeviceType == PointerDeviceType.Touch ? DATAGRIDCOLUMNHEADER_resizeRegionWidthLoose : DATAGRIDCOLUMNHEADER_resizeRegionWidthStrict;

                if (distanceFromRight <= resizeRegionWidth)
                {
                    handled = TrySetResizeColumn(e.Pointer.PointerId, currentColumn);
                }
                else if (distanceFromLeft <= resizeRegionWidth && previousColumn != null)
                {
                    handled = TrySetResizeColumn(e.Pointer.PointerId, previousColumn);
                }

                if (interactionInfo.DragMode == DragMode.Resize && interactionInfo.DragColumn != null)
                {
                    interactionInfo.DragStart                = interactionInfo.LastPointerPositionHeaders;
                    interactionInfo.OriginalWidth            = interactionInfo.DragColumn.ActualWidth;
                    interactionInfo.OriginalHorizontalOffset = this.OwningGrid.HorizontalOffset;

                    handled = true;
                }
            }

            e.Handled = handled;

            ApplyState(true /*useTransitions*/);
        }