UWP Grid Splitter 拖动时始终贴合鼠标位置的问题咨询
GridSplitter 拖动时光标位置未固定绑定的问题解决
我明白你遇到的这个问题——当GridSplitter拖到边界停下后,再往回拖动时,控件会跟着移动但光标并没有始终停在Splitter上,这是因为默认的拖动逻辑是基于鼠标的相对移动量,而不是跟踪绝对位置导致的。
要实现拖动过程中光标始终位于GridSplitter上的效果,我们可以自定义一个继承自GridSplitter的控件,修改其拖动逻辑为基于鼠标绝对位置计算目标列宽,同时处理边界限制后的基准值更新:
using Microsoft.Toolkit.Uwp.UI.Controls; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; namespace YourNamespace { public class FixedPositionGridSplitter : GridSplitter { private double _initialMouseX; private double _initialTargetColumnWidth; private ColumnDefinition _targetColumn; protected override void OnPointerPressed(PointerRoutedEventArgs e) { base.OnPointerPressed(e); var pointerPoint = e.GetCurrentPoint(this); _initialMouseX = pointerPoint.Position.X; // 根据你的布局,获取要调整的左侧列 if (Parent is Grid parentGrid && Grid.Column == 1) { _targetColumn = parentGrid.ColumnDefinitions[0]; _initialTargetColumnWidth = _targetColumn.ActualWidth; } CapturePointer(e.Pointer); } protected override void OnPointerMoved(PointerRoutedEventArgs e) { if (_targetColumn == null) { base.OnPointerMoved(e); return; } var pointerPoint = e.GetCurrentPoint(this); var mouseDeltaX = pointerPoint.Position.X - _initialMouseX; var newColumnWidth = _initialTargetColumnWidth + mouseDeltaX; // 应用最小宽度限制,同时更新基准值避免反向拖动偏移 if (newColumnWidth >= _targetColumn.MinWidth) { _targetColumn.Width = new GridLength(newColumnWidth); } else { _targetColumn.Width = new GridLength(_targetColumn.MinWidth); _initialMouseX = pointerPoint.Position.X; _initialTargetColumnWidth = _targetColumn.MinWidth; } } protected override void OnPointerReleased(PointerRoutedEventArgs e) { base.OnPointerReleased(e); ReleasePointerCapture(e.Pointer); _targetColumn = null; } } }
之后在XAML中引用这个自定义控件(记得替换YourNamespace为你的实际命名空间):
<Grid> <Grid.RowDefinitions> <RowDefinition Height="39"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="100"></ColumnDefinition> <ColumnDefinition Width="2"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <local:FixedPositionGridSplitter Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Width="2" ResizeBehavior="BasedOnAlignment" ResizeDirection="Auto" /> </Grid>
这个方案的核心是:在指针按下时记录初始的鼠标位置和目标列宽度,拖动过程中根据鼠标的绝对位置变化计算新列宽;当到达最小宽度边界时,更新初始基准值,这样反向拖动时光标就能重新和GridSplitter绑定,始终保持在控件上。
内容的提问来源于stack exchange,提问作者tscpp
相关产品推荐
相关产品推荐

