Skip to content

Commit bd94046

Browse files
committed
Refactor pointer event handling for selection logic
Refactored TableView, TableViewCell, and TableViewRow to override OnPointerPressed/OnPointerReleased instead of using AddHandler. Updated selection and drag logic to use internal TableView.OnAnyPointerPressed, improving event distinction and consistency. Removed OnAnyPointerReleased and centralized drag selection ending. Enhanced handling for pointer events over scrollbars, headers, and invalid areas.
1 parent baf4409 commit bd94046

3 files changed

Lines changed: 52 additions & 22 deletions

File tree

‎src/TableView.cs‎

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ public TableView()
7777
Unloaded += OnUnloaded;
7878
SelectionChanged += TableView_SelectionChanged;
7979
_collectionView.ItemPropertyChanged += OnItemPropertyChanged;
80-
81-
AddHandler(PointerPressedEvent, new PointerEventHandler(OnAnyPointerPressed), handledEventsToo: true);
82-
AddHandler(PointerReleasedEvent, new PointerEventHandler(OnAnyPointerReleased), handledEventsToo: true);
8380
}
8481

8582
/// <summary>
@@ -425,29 +422,49 @@ protected override void OnKeyDown(KeyRoutedEventArgs e)
425422
HandleNavigations(e, shiftKey, ctrlKey);
426423
}
427424

425+
/// <inheritdoc/>
426+
protected override void OnPointerPressed(PointerRoutedEventArgs e)
427+
{
428+
base.OnPointerPressed(e);
429+
430+
var originalSource = e.OriginalSource as FrameworkElement;
431+
432+
if (originalSource?.FindAscendant<ScrollBar>() is not null // Skip if the pointer is over a ScrollBar.
433+
|| originalSource?.FindAscendant<TableViewCell>() is not null // Skip if the pointer is over a TableViewCell.
434+
|| originalSource?.FindAscendant<TableViewRow>() is not null) // Skip if the pointer is over a TableViewRow.
435+
{
436+
return;
437+
}
438+
439+
OnAnyPointerPressed(this, e);
440+
}
441+
442+
/// <inheritdoc/>
443+
protected override void OnPointerReleased(PointerRoutedEventArgs e)
444+
{
445+
base.OnPointerReleased(e);
446+
447+
EndDragSelection();
448+
}
449+
428450
/// <summary>
429451
/// Handles pointer-pressed for all cases, including when elements sets <c>e.Handled = true</c>.
430452
/// </summary>
431-
private void OnAnyPointerPressed(object sender, PointerRoutedEventArgs e)
453+
internal void OnAnyPointerPressed(UIElement pressedElement, PointerRoutedEventArgs e)
432454
{
433455
var pointerPoint = e.GetCurrentPoint(this);
434456
var position = pointerPoint.Position;
435457
var canvasPoint = GetCanvasPoint(position);
436458
var ctrlKey = KeyboardHelper.IsCtrlKeyDown();
437459
var isShiftKey = KeyboardHelper.IsShiftKeyDown();
438-
var orignalSoruce = e.OriginalSource as FrameworkElement;
439-
UIElement? pressedElement = orignalSoruce?.FindAscendant<TableViewCell>(); // Check if the pointer is over a cell
440-
pressedElement ??= orignalSoruce?.FindAscendant<TableViewRow>(); // If not, check if the pointer is over a row
441460

442461
if (SelectionMode is ListViewSelectionMode.None // Skip selection when SelectionMode is None
443462
|| IsDragSelecting // Skip selection when a drag is already in progress
444-
|| orignalSoruce is ScrollBar // Skip selection when the pointer is over the ScrollBar
445-
|| orignalSoruce?.FindAscendant<ScrollBar>() is { } // Skip selection when the pointer is within a ScrollBar
446-
|| (pressedElement == null && !ShowDragRectangle) // Skip selection when the pointer is not over a Cell or Row, and ShowDragRectangle is false.
447-
|| !pointerPoint.Properties.IsLeftButtonPressed // Skip selection when the left mouse button is not pressed
448463
|| canvasPoint is null // Skip selection when canvasPoint is null (e.g., pointer is outside the scroll canvas)
449-
|| canvasPoint.Value.Y < 0 // Skip selection when the pointer is in the column header area (above the scroll canvas)
450-
|| (pressedElement == null && canvasPoint.Value.X < CellsHorizontalOffset) // Skip selection when the pointer is in the row header area (and not on a row/cell)
464+
|| canvasPoint.Value.Y < 0 // Skip selection when the pointer is in the column header area (above the scroll canvas)
465+
|| !pointerPoint.Properties.IsLeftButtonPressed // Skip selection when the left mouse button is not pressed
466+
|| (pressedElement == this && !ShowDragRectangle) // Skip selection when the pointer is not over a Cell or Row, and ShowDragRectangle is false.
467+
|| (pressedElement != this && canvasPoint.Value.X < CellsHorizontalOffset) // Skip selection when the pointer is in the row header area (and not on the TableView)
451468
|| isShiftKey) // Skip selection when the Shift key is held
452469
{
453470
return;
@@ -462,7 +479,7 @@ private void OnAnyPointerPressed(object sender, PointerRoutedEventArgs e)
462479
LastSelectionUnit = TableViewSelectionUnit.Row;
463480
#if !WINDOWS
464481
_dragStartCell = pressedElement as TableViewCell;
465-
_dragStartRow = (pressedElement as TableViewRow) ?? orignalSoruce?.FindAscendant<TableViewRow>();
482+
_dragStartRow = (pressedElement as TableViewRow) ?? pressedElement?.FindAscendant<TableViewRow>();
466483
#endif
467484
pressedElement ??= this; // If not, default to the TableView itself
468485

@@ -805,14 +822,6 @@ private void SelectCellsInDragRect(TableViewCellSlotRange cells)
805822
});
806823
}
807824

808-
/// <summary>
809-
/// Handles pointer-released for all cases, including when elements sets <c>e.Handled = true</c>.
810-
/// </summary>
811-
private void OnAnyPointerReleased(object sender, PointerRoutedEventArgs e)
812-
{
813-
EndDragSelection();
814-
}
815-
816825
/// <summary>
817826
/// Handles navigation keys.
818827
/// </summary>

‎src/TableViewCell.cs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,10 @@ protected override void OnPointerPressed(PointerRoutedEventArgs e)
422422
e.Handled = true;
423423
return;
424424
}
425+
426+
TableView?.OnAnyPointerPressed(this, e);
425427
}
428+
426429
/// <inheritdoc/>
427430
protected override void OnPointerReleased(PointerRoutedEventArgs e)
428431
{
@@ -432,6 +435,8 @@ protected override void OnPointerReleased(PointerRoutedEventArgs e)
432435
{
433436
e.Handled = true;
434437
}
438+
439+
TableView?.EndDragSelection();
435440
}
436441

437442
/// <summary>

‎src/TableViewRow.cs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,22 @@ protected override Size ArrangeOverride(Size finalSize)
195195
return finalSize;
196196
}
197197

198+
/// <inheritdoc/>
199+
protected override void OnPointerPressed(PointerRoutedEventArgs e)
200+
{
201+
base.OnPointerPressed(e);
202+
203+
TableView?.OnAnyPointerPressed(this, e);
204+
}
205+
206+
/// <inheritdoc/>
207+
protected override void OnPointerReleased(PointerRoutedEventArgs e)
208+
{
209+
base.OnPointerReleased(e);
210+
211+
TableView?.EndDragSelection();
212+
}
213+
198214
/// <summary>
199215
/// Updates the position of the row relative to the TableView.
200216
/// </summary>

0 commit comments

Comments
 (0)