ScrollViewer中包含可移动项目的可滚动画布
本文关键字:滚动 动画 项目 包含 可移动 ScrollViewer | 更新日期: 2023-09-27 18:29:12
我有一个包含Canvas的ScrollViewer。这个画布上有一些可移动的UI元素。这是我的XAML代码:
<ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Auto" Background="White">
<Canvas x:Name="MapCanvas" Width="4000" Height="4000">
<Button x:Name="TestBtn"
Content="My button"
Canvas.Left="250"
ManipulationStarted="MapItem_ManipulationStarted"
ManipulationDelta="MapItem_ManipulationDelta"
ManipulationCompleted="MapItem_ManipulationCompleted"
/>
</Canvas>
</ScrollViewer>
以下是事件处理程序的代码:
private void MapItem_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
{
FrameworkElement btn = sender as FrameworkElement;
if (null == btn) return;
double left = Canvas.GetLeft(btn) + e.DeltaManipulation.Translation.X;
double top = Canvas.GetTop(btn) + e.DeltaManipulation.Translation.Y;
if (left < 0)
left = 0;
else if (left > MapCanvas.ActualWidth - btn.ActualWidth)
left = MapCanvas.ActualWidth - btn.ActualWidth;
if (top < 0)
top = 0;
else if(top > MapCanvas.ActualHeight - btn.ActualHeight)
top = MapCanvas.ActualHeight - btn.ActualHeight;
Canvas.SetLeft(btn, left);
Canvas.SetTop(btn, top);
e.Handled = true;
}
private void MapItem_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
{
Scroller.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
Scroller.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
e.Handled = true;
}
private void MapItem_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
Scroller.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
Scroller.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
e.Handled = true;
}
一切都很完美。但是,当ScrollViewer滚动到某个HorizontalOffset或VerticalOffset,并且我正在点击或点击可见区域中的任何UIElement时,ScrollViewer似乎会自动滚动到HorisontalOffset==0和VerticalOffset==0。然后,在释放UIElement之后,它会跳回来。如何避免这种行为并使ScrollViewer停留在它的位置,同时将UIElement拖动到它内部的Canvas中?
我还没有测试过这一点,但您可以尝试用禁用/重新启用ScrollViewer
控件本身的调用来替换(或添加到)禁用/重新启动滚动条可见性的调用:
private void MapItem_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
Scroller.IsEnabled = false;
}
private void MapItem_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
Scroller.IsEnabled = true;
}
如果它确实有效,当它被禁用时,它可能会影响Style
,因此当它等于False
时,您可能必须在IsEnabled
属性上使用Trigger
来重新设置它的样式。
我发现我需要在页面构造函数中设置ScrollViewer.ManipulationMode=ManipulationModel.Control,而不设置HorisontalScrollBarVisibility和VerticalScrollVarVisibility(它将偏移重置为0,0坐标)现在它起作用了。
谢谢!