我目前正在页面上捕获PointerMoved
事件以用于水平菜单。因此,用户可以向左/向右滑动,页面将相应地设置动画。
这在用户触摸静态元素(TextBlock等)时有效,但如果他们触摸ListView则会捕获触摸事件。
如何实现ListView,以便当用户垂直滚动时,它正常工作,但当用户水平滚动时,它会将事件传递给我的代码?
答案 0 :(得分:5)
有可能,但你需要一个小技巧。作为参考,我在这里Rob Caplan's article。
让我们开始吧:
首先 - 您的活动在哪里? - 答案很简单 - 当你启用ScrollViewer
时,所有事件都被它拦截并被处理。您ListView
只会获得PointerEntered
个事件,而PointerExited
之后,所有进一步的处理都会被ScrollViewer
所取代。那就是问题所在。但正如我所说,有一种方法可以做你想做的事。
为此,我们假设您仅使用VerticalScroll定义了ListView
:
<ListView Name="myList" ScrollViewer.HorizontalScrollMode="Disabled">
当然可以为两个方向做,但这只是一个简单的例子。
现在让我们看一下Page
的构造函数:
PointerPoint firstPoint = null;
ScrollViewer listScrollviewer = null;
public MainPage()
{
this.InitializeComponent();
myList.ItemsSource = yourItemSource;
myList.PointerEntered += myList_PointerEntered;
myList.PointerMoved += myList_PointerMoved;
}
这里没什么奇怪的 - 我只是订阅了事件,并声明了两个变量firstPoint
和listScrollviewer
,我以后需要这些变量。
我们还需要获取ScrollViewer
的{{1}} - 以下方法可以完成此任务:
ListView
现在 - 要启用我们的活动,我们需要停用public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}
:
ScrollViewer
我们将在private ScrollViewer DisableScrolling(DependencyObject depObj)
{
ScrollViewer foundOne = GetScrollViewer(depObj);
if (foundOne != null) foundOne.VerticalScrollMode = ScrollMode.Disabled;
return foundOne;
}
被触发的事件中停用ScrollViewer
。在此步骤中,我们还会记住按下的PointerEntered
- 因为我们已禁用PointerPoint
,我们必须手动滚动它 - 这就是我们需要Scrollviewer
。
PointerPoint
最后我们的private void myList_PointerEntered(object sender, PointerRoutedEventArgs e)
{
firstPoint = e.GetCurrentPoint(myList);
if (listScrollviewer == null) listScrollviewer = DisableScrolling(myList);
}
事件,现在因为我们已停用PointerMoved
而被解雇 - 移动ScrollViewer
+您需要放置的其他代码:
ScrollViewer
几点评论:
private void myList_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (listScrollviewer != null)
{
PointerPoint secondPoint = e.GetCurrentPoint(myList);
double verticalDifference = secondPoint.Position.Y - firstPoint.Position.Y;
listScrollviewer.ChangeView(null, listScrollviewer.VerticalOffset - verticalDifference, null);
}
// some other code you need
}
或其他控件具有水平滚动,那么您还需要禁用并处理它,ListView
那样顺畅地工作。我还提出了一个简单的工作示例here at OneDrive。