从 ListView 到其父级的冒泡滚动事件
在我的 WPF 应用程序中,我有一个 ListView
,其 ScrollViewer.VerticalScrollBarVisibility
设置为 Disabled
。它包含在 ScrollViewer
中。当我尝试在 ListView
上使用鼠标滚轮时,外部 ScrollViewer
不会滚动,因为 ListView
正在捕获滚动事件。
如何强制 ListView
允许滚动事件冒泡到 ScrollViewer
?
In my WPF application I have a ListView
whose ScrollViewer.VerticalScrollBarVisibility
is set to Disabled
. It is contained within a ScrollViewer
. When I attempt to use the mouse wheel over the ListView
, the outer ScrollViewer
does not scroll because the ListView
is capturing the scroll events.
How can I force the ListView
to allow the scroll events to bubble up to the ScrollViewer
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
根据您的具体情况,有不同的方法,但我发现这种方法效果很好。假设您的基本情况是这样的:
在 PreviewMouseWheel 期间自己提高 MouseWheelEvent 似乎会强制 ScrollViewer 工作。我希望我知道为什么,这似乎非常违反直觉。
There are different approaches depending on your exact situation, but I found this to work nicely. Assuming your basic situation is this:
Raising MouseWheelEvent yourself during PreviewMouseWheel seems to force the ScrollViewer to work. I wish I knew why, it seems very counterintuitive.
您还可以使用附加行为来实现相同的目标。这样做的优点是不需要 System.Windows.Interactivity 库。逻辑取自其他答案,只是实现不同。
然后在 XAML 中:
You can also achieve the same thing using an attached behaviour. This has the advantage of not needing the System.Windows.Interactivity library. The logic has been taken from the other answers, only the implementation is different.
And then in the XAML:
谢谢 Keyle,
我将您的答案改编为 RX 扩展方法
用法:
Thanks Keyle
I adapted your answer as an RX extension method
Usage:
我的用例略有不同。我有一个非常大的滚动查看器,底部有另一个滚动查看器,其最大高度为 600。我想将整个页面滚动到底部,直到将滚动事件传递到内部滚动查看器。
这可确保您在开始滚动之前首先看到整个滚动查看器。
My use case was slightly different. I have a very big scrollviewer and at the bottom another scrollviewer which has a maxheight of 600. I want to scroll the whole page to the bottom until I pass scrollevents to the inner scrollviewer.
This ensures you see the whole scrollviewer first, before you start scrolling.
好吧,自从我上 SO 以来已经有一段时间了,但我不得不对此发表评论。任何预览事件隧道,那么我们为什么要冒泡呢?停止父级中的隧道并完成它。在父级中添加一个 PreviewMouseWheel 事件。
Ok been a while since I have been on SO but I had to comment on this. Any Preview event tunnels, so why are we bubbling it up? Stop the tunnel in the parent and be done with it. in the parent add a PreviewMouseWheel event.
您需要在内部列表视图
或 XAML 中
捕获预览鼠标滚轮事件,然后停止该事件滚动列表视图并在父列表视图中引发该事件。
感谢@robert-wagner,他在几个月前为我解决了这个问题。
You need to capture the preview mouse wheel event in the inner listview
Or in the XAML
then stop the event from scrolling the listview and raise the event in the parent listview.
Creds go to @robert-wagner who solved this for me a few months ago.
使用附加行为的另一个不错的解决方案。
我喜欢它,因为它将解决方案从控制中分离出来。
创建一个无滚动行为,它将捕获 PreviewMouseWheel(Tunneling) 事件并引发新的 MouseWheelEvent(Bubbling)
然后将该行为附加到任何具有嵌套 ScrollViewers 的 UIElement 案例
所有功劳 乔什·爱因斯坦博客
Another nice solution using attached behavior.
I like it because it decoples the solution from the Control.
Create a no scroling behavior which will catch the PreviewMouseWheel(Tunneling) event and raise a new MouseWheelEvent(Bubbling)
Then attach the behavior to any UIElement with nested ScrollViewers case
all credit to Josh Einstein Blog
如果您来这里寻找仅当子项位于顶部并向上滚动或底部并向下滚动时才使事件冒泡的解决方案,这里有一个解决方案。我只使用 DataGrid 对此进行了测试,但它也应该适用于其他控件。
要附加此行为,请将以下 XMLNS 和 XAML 添加到您的元素:
If you're coming here looking for a solution to bubble the event ONLY if the child is at the top and scrolling up or the bottom and scrolling down, here's a solution. I only tested this with DataGrid, but it should work with other controls as well.
To attach this behavior, add the following XMLNS and XAML to your element: