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*/); }