// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Collections;
using Avalonia.Media;
using System.ComponentModel;
using System.Diagnostics;
using Avalonia.Utilities;
using System;
using Avalonia.Controls.Utils;
namespace Avalonia.Controls
{
///
/// Represents an individual column header.
///
public class DataGridColumnHeader : ContentControl
{
private enum DragMode
{
None = 0,
MouseDown = 1,
Drag = 2,
Resize = 3,
Reorder = 4
}
private const int DATAGRIDCOLUMNHEADER_resizeRegionWidth = 5;
private const double DATAGRIDCOLUMNHEADER_separatorThickness = 1;
private bool _areHandlersSuspended;
private static DragMode _dragMode;
private static Point? _lastMousePositionHeaders;
private static Cursor _originalCursor;
private static double _originalHorizontalOffset;
private static double _originalWidth;
private bool _desiredSeparatorVisibility;
private static Point? _dragStart;
private static DataGridColumn _dragColumn;
private static double _frozenColumnsWidth;
private static Lazy _resizeCursor = new Lazy(() => new Cursor(StandardCursorType.SizeWestEast));
public static readonly StyledProperty SeparatorBrushProperty =
AvaloniaProperty.Register(nameof(SeparatorBrush));
public IBrush SeparatorBrush
{
get { return GetValue(SeparatorBrushProperty); }
set { SetValue(SeparatorBrushProperty, value); }
}
public static readonly StyledProperty AreSeparatorsVisibleProperty =
AvaloniaProperty.Register(
nameof(AreSeparatorsVisible),
defaultValue: true);
public bool AreSeparatorsVisible
{
get { return GetValue(AreSeparatorsVisibleProperty); }
set { SetValue(AreSeparatorsVisibleProperty, value); }
}
static DataGridColumnHeader()
{
AreSeparatorsVisibleProperty.Changed.AddClassHandler((x,e) => x.OnAreSeparatorsVisibleChanged(e));
}
///
/// Initializes a new instance of the class.
///
//TODO Implement
public DataGridColumnHeader()
{
PointerPressed += DataGridColumnHeader_PointerPressed;
PointerReleased += DataGridColumnHeader_PointerReleased;
PointerMoved += DataGridColumnHeader_PointerMove;
PointerEnter += DataGridColumnHeader_PointerEnter;
PointerLeave += DataGridColumnHeader_PointerLeave;
}
private void OnAreSeparatorsVisibleChanged(AvaloniaPropertyChangedEventArgs e)
{
if (!_areHandlersSuspended)
{
_desiredSeparatorVisibility = (bool)e.NewValue;
if (OwningGrid != null)
{
UpdateSeparatorVisibility(OwningGrid.ColumnsInternal.LastVisibleColumn);
}
else
{
UpdateSeparatorVisibility(null);
}
}
}
internal DataGridColumn OwningColumn
{
get;
set;
}
internal DataGrid OwningGrid => OwningColumn?.OwningGrid;
internal int ColumnIndex
{
get
{
if (OwningColumn == null)
{
return -1;
}
return OwningColumn.Index;
}
}
internal ListSortDirection? CurrentSortingState
{
get;
private set;
}
private bool IsMouseOver
{
get;
set;
}
private bool IsPressed
{
get;
set;
}
private void SetValueNoCallback(AvaloniaProperty property, T value, BindingPriority priority = BindingPriority.LocalValue)
{
_areHandlersSuspended = true;
try
{
SetValue(property, value, priority);
}
finally
{
_areHandlersSuspended = false;
}
}
//TODO Implement
internal void ApplyState()
{
CurrentSortingState = null;
if (OwningGrid != null
&& OwningGrid.DataConnection != null
&& OwningGrid.DataConnection.AllowSort)
{
var sort = OwningColumn.GetSortDescription();
if(sort != null)
{
CurrentSortingState = sort.Descending ? ListSortDirection.Descending : ListSortDirection.Ascending;
}
}
PseudoClasses.Set(":sortascending",
CurrentSortingState.HasValue && CurrentSortingState.Value == ListSortDirection.Ascending);
PseudoClasses.Set(":sortdescending",
CurrentSortingState.HasValue && CurrentSortingState.Value == ListSortDirection.Descending);
}
internal void UpdateSeparatorVisibility(DataGridColumn lastVisibleColumn)
{
bool newVisibility = _desiredSeparatorVisibility;
// Collapse separator for the last column if there is no filler column
if (OwningColumn != null &&
OwningGrid != null &&
_desiredSeparatorVisibility &&
OwningColumn == lastVisibleColumn &&
!OwningGrid.ColumnsInternal.FillerColumn.IsActive)
{
newVisibility = false;
}
// Update the public property if it has changed
if (AreSeparatorsVisible != newVisibility)
{
SetValueNoCallback(AreSeparatorsVisibleProperty, newVisibility);
}
}
internal void OnMouseLeftButtonUp_Click(InputModifiers inputModifiers, ref bool handled)
{
// completed a click without dragging, so we're sorting
InvokeProcessSort(inputModifiers);
handled = true;
}
internal void InvokeProcessSort(InputModifiers inputModifiers)
{
Debug.Assert(OwningGrid != null);
if (OwningGrid.WaitForLostFocus(() => InvokeProcessSort(inputModifiers)))
{
return;
}
if (OwningGrid.CommitEdit(DataGridEditingUnit.Row, exitEditingMode: true))
{
Avalonia.Threading.Dispatcher.UIThread.Post(() => ProcessSort(inputModifiers));
}
}
//TODO GroupSorting
internal void ProcessSort(InputModifiers inputModifiers)
{
// if we can sort:
// - DataConnection.AllowSort is true, and
// - AllowUserToSortColumns and CanSort are true, and
// - OwningColumn is bound, and
// - SortDescriptionsCollection exists, and
// - the column's data type is comparable
// then try to sort
if (OwningColumn != null
&& OwningGrid != null
&& OwningGrid.EditingRow == null
&& OwningColumn != OwningGrid.ColumnsInternal.FillerColumn
&& OwningGrid.DataConnection.AllowSort
&& OwningGrid.CanUserSortColumns
&& OwningColumn.CanUserSort
&& OwningGrid.DataConnection.SortDescriptions != null)
{
DataGrid owningGrid = OwningGrid;
DataGridSortDescription newSort;
KeyboardHelper.GetMetaKeyState(inputModifiers, out bool ctrl, out bool shift);
DataGridSortDescription sort = OwningColumn.GetSortDescription();
IDataGridCollectionView collectionView = owningGrid.DataConnection.CollectionView;
Debug.Assert(collectionView != null);
using (collectionView.DeferRefresh())
{
// if shift is held down, we multi-sort, therefore if it isn't, we'll clear the sorts beforehand
if (!shift || owningGrid.DataConnection.SortDescriptions.Count == 0)
{
owningGrid.DataConnection.SortDescriptions.Clear();
}
if (sort != null)
{
newSort = sort.SwitchSortDirection();
// changing direction should not affect sort order, so we replace this column's
// sort description instead of just adding it to the end of the collection
int oldIndex = owningGrid.DataConnection.SortDescriptions.IndexOf(sort);
if (oldIndex >= 0)
{
owningGrid.DataConnection.SortDescriptions.Remove(sort);
owningGrid.DataConnection.SortDescriptions.Insert(oldIndex, newSort);
}
else
{
owningGrid.DataConnection.SortDescriptions.Add(newSort);
}
}
else
{
string propertyName = OwningColumn.GetSortPropertyName();
// no-opt if we couldn't find a property to sort on
if (string.IsNullOrEmpty(propertyName))
{
return;
}
newSort = DataGridSortDescription.FromPath(propertyName, culture: collectionView.Culture);
owningGrid.DataConnection.SortDescriptions.Add(newSort);
}
}
}
}
private bool CanReorderColumn(DataGridColumn column)
{
return OwningGrid.CanUserReorderColumns
&& !(column is DataGridFillerColumn)
&& (column.CanUserReorderInternal.HasValue && column.CanUserReorderInternal.Value || !column.CanUserReorderInternal.HasValue);
}
///
/// Determines whether a column can be resized by dragging the border of its header. If star sizing
/// is being used, there are special conditions that can prevent a column from being resized:
/// 1. The column is the last visible column.
/// 2. All columns are constrained by either their maximum or minimum values.
///
/// Column to check.
/// Whether or not the column can be resized by dragging its header.
private static bool CanResizeColumn(DataGridColumn column)
{
if (column.OwningGrid != null && column.OwningGrid.ColumnsInternal != null && column.OwningGrid.UsesStarSizing &&
(column.OwningGrid.ColumnsInternal.LastVisibleColumn == column || !DoubleUtil.AreClose(column.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, column.OwningGrid.CellsWidth)))
{
return false;
}
return column.ActualCanUserResize;
}
private static bool TrySetResizeColumn(DataGridColumn column)
{
// If datagrid.CanUserResizeColumns == false, then the column can still override it
if (CanResizeColumn(column))
{
_dragColumn = column;
_dragMode = DragMode.Resize;
return true;
}
return false;
}
//TODO DragDrop
internal void OnMouseLeftButtonDown(ref bool handled, PointerEventArgs args, Point mousePosition)
{
IsPressed = true;
if (OwningGrid != null && OwningGrid.ColumnHeaders != null)
{
args.Device.Capture(this);
_dragMode = DragMode.MouseDown;
_frozenColumnsWidth = OwningGrid.ColumnsInternal.GetVisibleFrozenEdgedColumnsWidth();
_lastMousePositionHeaders = this.Translate(OwningGrid.ColumnHeaders, mousePosition);
double distanceFromLeft = mousePosition.X;
double distanceFromRight = Bounds.Width - distanceFromLeft;
DataGridColumn currentColumn = OwningColumn;
DataGridColumn previousColumn = null;
if (!(OwningColumn is DataGridFillerColumn))
{
previousColumn = OwningGrid.ColumnsInternal.GetPreviousVisibleNonFillerColumn(currentColumn);
}
if (_dragMode == DragMode.MouseDown && _dragColumn == null && (distanceFromRight <= DATAGRIDCOLUMNHEADER_resizeRegionWidth))
{
handled = TrySetResizeColumn(currentColumn);
}
else if (_dragMode == DragMode.MouseDown && _dragColumn == null && distanceFromLeft <= DATAGRIDCOLUMNHEADER_resizeRegionWidth && previousColumn != null)
{
handled = TrySetResizeColumn(previousColumn);
}
if (_dragMode == DragMode.Resize && _dragColumn != null)
{
_dragStart = _lastMousePositionHeaders;
_originalWidth = _dragColumn.ActualWidth;
_originalHorizontalOffset = OwningGrid.HorizontalOffset;
handled = true;
}
}
}
//TODO DragEvents
//TODO MouseCapture
internal void OnMouseLeftButtonUp(ref bool handled, PointerEventArgs args, Point mousePosition, Point mousePositionHeaders)
{
IsPressed = false;
if (OwningGrid != null && OwningGrid.ColumnHeaders != null)
{
if (_dragMode == DragMode.MouseDown)
{
OnMouseLeftButtonUp_Click(args.InputModifiers, ref handled);
}
else if (_dragMode == DragMode.Reorder)
{
// Find header we're hovering over
int targetIndex = GetReorderingTargetDisplayIndex(mousePositionHeaders);
if (((!OwningColumn.IsFrozen && targetIndex >= OwningGrid.FrozenColumnCount)
|| (OwningColumn.IsFrozen && targetIndex < OwningGrid.FrozenColumnCount)))
{
OwningColumn.DisplayIndex = targetIndex;
DataGridColumnEventArgs ea = new DataGridColumnEventArgs(OwningColumn);
OwningGrid.OnColumnReordered(ea);
}
}
SetDragCursor(mousePosition);
// Variables that track drag mode states get reset in DataGridColumnHeader_LostMouseCapture
args.Device.Capture(null);
OnLostMouseCapture();
_dragMode = DragMode.None;
handled = true;
}
}
//TODO DragEvents
internal void OnMouseMove(ref bool handled, Point mousePosition, Point mousePositionHeaders)
{
if (handled || OwningGrid == null || OwningGrid.ColumnHeaders == null)
{
return;
}
Debug.Assert(OwningGrid.Parent is InputElement);
double distanceFromLeft = mousePosition.X;
double distanceFromRight = Bounds.Width - distanceFromLeft;
OnMouseMove_Resize(ref handled, mousePositionHeaders);
OnMouseMove_Reorder(ref handled, mousePosition, mousePositionHeaders, distanceFromLeft, distanceFromRight);
// if we still haven't done anything about moving the mouse while
// the button is down, we remember that we're dragging, but we don't
// claim to have actually handled the event
if (_dragMode == DragMode.MouseDown)
{
_dragMode = DragMode.Drag;
}
_lastMousePositionHeaders = mousePositionHeaders;
SetDragCursor(mousePosition);
}
private void DataGridColumnHeader_PointerEnter(object sender, PointerEventArgs e)
{
if (!IsEnabled)
{
return;
}
Point mousePosition = e.GetPosition(this);
OnMouseEnter(mousePosition);
ApplyState();
}
private void DataGridColumnHeader_PointerLeave(object sender, PointerEventArgs e)
{
if (!IsEnabled)
{
return;
}
OnMouseLeave();
ApplyState();
}
private void DataGridColumnHeader_PointerPressed(object sender, PointerPressedEventArgs e)
{
if (OwningColumn == null || e.Handled || !IsEnabled || e.MouseButton != MouseButton.Left)
{
return;
}
Point mousePosition = e.GetPosition(this);
bool handled = e.Handled;
OnMouseLeftButtonDown(ref handled, e, mousePosition);
e.Handled = handled;
ApplyState();
}
private void DataGridColumnHeader_PointerReleased(object sender, PointerReleasedEventArgs e)
{
if (OwningColumn == null || e.Handled || !IsEnabled || e.InitialPressMouseButton != MouseButton.Left)
{
return;
}
Point mousePosition = e.GetPosition(this);
Point mousePositionHeaders = e.GetPosition(OwningGrid.ColumnHeaders);
bool handled = e.Handled;
OnMouseLeftButtonUp(ref handled, e, mousePosition, mousePositionHeaders);
e.Handled = handled;
ApplyState();
}
private void DataGridColumnHeader_PointerMove(object sender, PointerEventArgs e)
{
if (OwningGrid == null || !IsEnabled)
{
return;
}
Point mousePosition = e.GetPosition(this);
Point mousePositionHeaders = e.GetPosition(OwningGrid.ColumnHeaders);
bool handled = false;
OnMouseMove(ref handled, mousePosition, mousePositionHeaders);
}
///
/// Returns the column against whose top-left the reordering caret should be positioned
///
/// Mouse position within the ColumnHeadersPresenter
/// Whether or not to scroll horizontally when a column is dragged out of bounds
/// If scroll is true, returns the horizontal amount that was scrolled
///
private DataGridColumn GetReorderingTargetColumn(Point mousePositionHeaders, bool scroll, out double scrollAmount)
{
scrollAmount = 0;
double leftEdge = OwningGrid.ColumnsInternal.RowGroupSpacerColumn.IsRepresented ? OwningGrid.ColumnsInternal.RowGroupSpacerColumn.ActualWidth : 0;
double rightEdge = OwningGrid.CellsWidth;
if (OwningColumn.IsFrozen)
{
rightEdge = Math.Min(rightEdge, _frozenColumnsWidth);
}
else if (OwningGrid.FrozenColumnCount > 0)
{
leftEdge = _frozenColumnsWidth;
}
if (mousePositionHeaders.X < leftEdge)
{
if (scroll &&
OwningGrid.HorizontalScrollBar != null &&
OwningGrid.HorizontalScrollBar.IsVisible &&
OwningGrid.HorizontalScrollBar.Value > 0)
{
double newVal = mousePositionHeaders.X - leftEdge;
scrollAmount = Math.Min(newVal, OwningGrid.HorizontalScrollBar.Value);
OwningGrid.UpdateHorizontalOffset(scrollAmount + OwningGrid.HorizontalScrollBar.Value);
}
mousePositionHeaders = mousePositionHeaders.WithX(leftEdge);
}
else if (mousePositionHeaders.X >= rightEdge)
{
if (scroll &&
OwningGrid.HorizontalScrollBar != null &&
OwningGrid.HorizontalScrollBar.IsVisible &&
OwningGrid.HorizontalScrollBar.Value < OwningGrid.HorizontalScrollBar.Maximum)
{
double newVal = mousePositionHeaders.X - rightEdge;
scrollAmount = Math.Min(newVal, OwningGrid.HorizontalScrollBar.Maximum - OwningGrid.HorizontalScrollBar.Value);
OwningGrid.UpdateHorizontalOffset(scrollAmount + OwningGrid.HorizontalScrollBar.Value);
}
mousePositionHeaders = mousePositionHeaders.WithX(rightEdge - 1);
}
foreach (DataGridColumn column in OwningGrid.ColumnsInternal.GetDisplayedColumns())
{
Point mousePosition = OwningGrid.ColumnHeaders.Translate(column.HeaderCell, mousePositionHeaders);
double columnMiddle = column.HeaderCell.Bounds.Width / 2;
if (mousePosition.X >= 0 && mousePosition.X <= columnMiddle)
{
return column;
}
else if (mousePosition.X > columnMiddle && mousePosition.X < column.HeaderCell.Bounds.Width)
{
return OwningGrid.ColumnsInternal.GetNextVisibleColumn(column);
}
}
return null;
}
///
/// Returns the display index to set the column to
///
/// Mouse position relative to the column headers presenter
///
private int GetReorderingTargetDisplayIndex(Point mousePositionHeaders)
{
DataGridColumn targetColumn = GetReorderingTargetColumn(mousePositionHeaders, false /*scroll*/, out double scrollAmount);
if (targetColumn != null)
{
return targetColumn.DisplayIndex > OwningColumn.DisplayIndex ? targetColumn.DisplayIndex - 1 : targetColumn.DisplayIndex;
}
else
{
return OwningGrid.Columns.Count - 1;
}
}
///
/// Returns true if the mouse is
/// - to the left of the element, or within the left half of the element
/// and
/// - within the vertical range of the element, or ignoreVertical == true
///
///
///
///
///
private bool IsReorderTargeted(Point mousePosition, Control element, bool ignoreVertical)
{
Point position = this.Translate(element, mousePosition);
return (position.X < 0 || (position.X >= 0 && position.X <= element.Bounds.Width / 2))
&& (ignoreVertical || (position.Y >= 0 && position.Y <= element.Bounds.Height));
}
///
/// Resets the static DataGridColumnHeader properties when a header loses mouse capture
///
private void OnLostMouseCapture()
{
// When we stop interacting with the column headers, we need to reset the drag mode
// and close any popups if they are open.
if (_dragColumn != null && _dragColumn.HeaderCell != null)
{
_dragColumn.HeaderCell.Cursor = _originalCursor;
}
_dragMode = DragMode.None;
_dragColumn = null;
_dragStart = null;
_lastMousePositionHeaders = null;
if (OwningGrid != null && OwningGrid.ColumnHeaders != null)
{
OwningGrid.ColumnHeaders.DragColumn = null;
OwningGrid.ColumnHeaders.DragIndicator = null;
OwningGrid.ColumnHeaders.DropLocationIndicator = null;
}
}
///
/// Sets up the DataGridColumnHeader for the MouseEnter event
///
/// mouse position relative to the DataGridColumnHeader
private void OnMouseEnter(Point mousePosition)
{
IsMouseOver = true;
SetDragCursor(mousePosition);
}
///
/// Sets up the DataGridColumnHeader for the MouseLeave event
///
private void OnMouseLeave()
{
IsMouseOver = false;
}
//TODO Styles DragIndicator
private void OnMouseMove_BeginReorder(Point mousePosition)
{
DataGridColumnHeader dragIndicator = new DataGridColumnHeader
{
OwningColumn = OwningColumn,
IsEnabled = false,
Content = Content,
ContentTemplate = ContentTemplate
};
dragIndicator.PseudoClasses.Add(":dragIndicator");
IControl dropLocationIndicator = OwningGrid.DropLocationIndicatorTemplate?.Build();
// If the user didn't style the dropLocationIndicator's Height, default to the column header's height
if (dropLocationIndicator != null && double.IsNaN(dropLocationIndicator.Height) && dropLocationIndicator is Control element)
{
element.Height = Bounds.Height;
}
// pass the caret's data template to the user for modification
DataGridColumnReorderingEventArgs columnReorderingEventArgs = new DataGridColumnReorderingEventArgs(OwningColumn)
{
DropLocationIndicator = dropLocationIndicator,
DragIndicator = dragIndicator
};
OwningGrid.OnColumnReordering(columnReorderingEventArgs);
if (columnReorderingEventArgs.Cancel)
{
return;
}
// The user didn't cancel, so prepare for the reorder
_dragColumn = OwningColumn;
_dragMode = DragMode.Reorder;
_dragStart = mousePosition;
// Display the reordering thumb
OwningGrid.ColumnHeaders.DragColumn = OwningColumn;
OwningGrid.ColumnHeaders.DragIndicator = columnReorderingEventArgs.DragIndicator;
OwningGrid.ColumnHeaders.DropLocationIndicator = columnReorderingEventArgs.DropLocationIndicator;
// 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 = Bounds.Width;
}
}
//TODO DragEvents
private void OnMouseMove_Reorder(ref bool handled, Point mousePosition, Point mousePositionHeaders, double distanceFromLeft, double distanceFromRight)
{
if (handled)
{
return;
}
//handle entry into reorder mode
if (_dragMode == DragMode.MouseDown && _dragColumn == null && (distanceFromRight > DATAGRIDCOLUMNHEADER_resizeRegionWidth && distanceFromLeft > DATAGRIDCOLUMNHEADER_resizeRegionWidth))
{
handled = CanReorderColumn(OwningColumn);
if (handled)
{
OnMouseMove_BeginReorder(mousePosition);
}
}
//handle reorder mode (eg, positioning of the popup)
if (_dragMode == DragMode.Reorder && OwningGrid.ColumnHeaders.DragIndicator != null)
{
// Find header we're hovering over
DataGridColumn targetColumn = GetReorderingTargetColumn(mousePositionHeaders, !OwningColumn.IsFrozen /*scroll*/, out double scrollAmount);
OwningGrid.ColumnHeaders.DragIndicatorOffset = mousePosition.X - _dragStart.Value.X + scrollAmount;
OwningGrid.ColumnHeaders.InvalidateArrange();
if (OwningGrid.ColumnHeaders.DropLocationIndicator != null)
{
Point targetPosition = new Point(0, 0);
if (targetColumn == null || targetColumn == OwningGrid.ColumnsInternal.FillerColumn || targetColumn.IsFrozen != OwningColumn.IsFrozen)
{
targetColumn =
OwningGrid.ColumnsInternal.GetLastColumn(
isVisible: true,
isFrozen: OwningColumn.IsFrozen,
isReadOnly: null);
targetPosition = targetColumn.HeaderCell.Translate(OwningGrid.ColumnHeaders, targetPosition);
targetPosition = targetPosition.WithX(targetPosition.X + targetColumn.ActualWidth);
}
else
{
targetPosition = targetColumn.HeaderCell.Translate(OwningGrid.ColumnHeaders, targetPosition);
}
OwningGrid.ColumnHeaders.DropLocationIndicatorOffset = targetPosition.X - scrollAmount;
}
handled = true;
}
}
private void OnMouseMove_Resize(ref bool handled, Point mousePositionHeaders)
{
if (handled)
{
return;
}
if (_dragMode == DragMode.Resize && _dragColumn != null && _dragStart.HasValue)
{
// resize column
double mouseDelta = mousePositionHeaders.X - _dragStart.Value.X;
double desiredWidth = _originalWidth + mouseDelta;
desiredWidth = Math.Max(_dragColumn.ActualMinWidth, Math.Min(_dragColumn.ActualMaxWidth, desiredWidth));
_dragColumn.Resize(_dragColumn.Width.Value, _dragColumn.Width.UnitType, _dragColumn.Width.DesiredValue, desiredWidth, true);
OwningGrid.UpdateHorizontalOffset(_originalHorizontalOffset);
handled = true;
}
}
private void SetDragCursor(Point mousePosition)
{
if (_dragMode != DragMode.None || OwningGrid == null || OwningColumn == null)
{
return;
}
// set mouse if we can resize column
double distanceFromLeft = mousePosition.X;
double distanceFromRight = Bounds.Width - distanceFromLeft;
DataGridColumn currentColumn = OwningColumn;
DataGridColumn previousColumn = null;
if (!(OwningColumn is DataGridFillerColumn))
{
previousColumn = OwningGrid.ColumnsInternal.GetPreviousVisibleNonFillerColumn(currentColumn);
}
if ((distanceFromRight <= DATAGRIDCOLUMNHEADER_resizeRegionWidth && currentColumn != null && CanResizeColumn(currentColumn)) ||
(distanceFromLeft <= DATAGRIDCOLUMNHEADER_resizeRegionWidth && previousColumn != null && CanResizeColumn(previousColumn)))
{
var resizeCursor = _resizeCursor.Value;
if (Cursor != resizeCursor)
{
_originalCursor = Cursor;
Cursor = resizeCursor;
}
}
else
{
Cursor = _originalCursor;
}
}
}
}