Skip to content

Commit 2b141d2

Browse files
authored
Merge pull request #2519 from cwensley/curtis/wpf-scroll-grid-on-dragover
Wpf: Auto scroll Tree/GridView when cursor nears edge during drag/drop
2 parents 4a3cdbc + ced4704 commit 2b141d2

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

src/Eto.Wpf/Forms/Controls/GridHandler.cs

+64
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ public abstract class GridHandler<TWidget, TCallback> : WpfControl<EtoDataGrid,
114114
where TWidget : Grid
115115
where TCallback : Grid.ICallback
116116
{
117+
DateTime? startDragOverTime;
118+
const int DragScrollSize = 12;
119+
const int DragScrollFastSize = 6;
120+
const double DragScrollDelay = 0.1;
121+
const double DragScrollFastDelay = 0.01;
122+
117123
ContextMenu contextMenu;
118124
bool hasFocus;
119125
protected bool SkipSelectionChanged { get; set; }
@@ -993,5 +999,63 @@ public void OnColumnWidthChanged(GridColumnHandler gridColumnHandler)
993999
var cellType = cellInfo.IsHeader ? GridCellType.ColumnHeader : rowIndex != -1 && columnIndex != -1 ? GridCellType.Data : GridCellType.None;
9941000
return (column, columnIndex, rowIndex, cellType, item);
9951001
}
1002+
1003+
swc.ScrollViewer ScrollViewer => Control.FindChild<swc.ScrollViewer>();
1004+
1005+
protected override void HandleDragOver(sw.DragEventArgs e, Eto.Forms.DragEventArgs args)
1006+
{
1007+
base.HandleDragOver(e, args);
1008+
1009+
var scrollViewer = ScrollViewer;
1010+
if (scrollViewer == null)
1011+
return;
1012+
1013+
void ScrollWithIncrement(bool fast, double increment)
1014+
{
1015+
var now = DateTime.Now;
1016+
if (startDragOverTime == null)
1017+
{
1018+
startDragOverTime = now;
1019+
return;
1020+
}
1021+
1022+
var diff = now - startDragOverTime;
1023+
if (diff > TimeSpan.FromSeconds(fast ? DragScrollFastDelay : DragScrollDelay))
1024+
{
1025+
startDragOverTime = now;
1026+
var oldOffset = scrollViewer.VerticalOffset;
1027+
var maxHeight = scrollViewer.ScrollableHeight;
1028+
var newOffset = Math.Min(maxHeight, Math.Max(0, oldOffset + increment));
1029+
if (newOffset != oldOffset)
1030+
scrollViewer.ScrollToVerticalOffset(newOffset);
1031+
}
1032+
}
1033+
1034+
var headerPart = ShowHeader ? Control.FindChild<swcp.DataGridColumnHeadersPresenter>("PART_ColumnHeadersPresenter") : null;
1035+
var headerHeight = headerPart?.ActualHeight ?? 0;
1036+
1037+
// scroll up or down when the user drags close to the edge
1038+
if (args.Location.Y < headerHeight + DragScrollSize)
1039+
{
1040+
ScrollWithIncrement(args.Location.Y < headerHeight + DragScrollFastSize, -1);
1041+
return;
1042+
}
1043+
1044+
var height = Control.ActualHeight;
1045+
if (scrollViewer.ComputedHorizontalScrollBarVisibility == Visibility.Visible)
1046+
{
1047+
var child = scrollViewer.FindChild<swcp.ScrollBar>("PART_HorizontalScrollBar");
1048+
height -= child.ActualHeight;
1049+
}
1050+
1051+
if (args.Location.Y > height - DragScrollSize)
1052+
{
1053+
ScrollWithIncrement(args.Location.Y > height - DragScrollFastSize, 1);
1054+
return;
1055+
}
1056+
1057+
// not in a drag scroll area, reset
1058+
startDragOverTime = null;
1059+
}
9961060
}
9971061
}

0 commit comments

Comments
 (0)