WP7 Pivot控件和WebBrowser控件

我有一个包含WebBrowser控件的Pivot,它实际上占用了整个页面(当然,从Pivot头部开始)。

我想弄清楚如何使WebBrowser控件允许用户向左/向右滑动以激活Pivot控件。 目前它只是向左/向右平移WebBrowser控件

这可以吗?

谢谢

这类似于将一个Map放在一个Pivot中 – 这里讨论 – http://mine.tuxfamily.org/?p=111-已经在很多问题中提到过https://stackoverflow.com/search?q = mine.tuxfamily.org

一般来说,建议似乎是基于可用性:

  • 尽量避免在PivotItem中放置使用Touch的控件

顺便说一句,如果您只是使用Web浏览器控件来获取非常少量的静态html(因此您根本不需要任何滚动),那么您可以从Web浏览器中删除HitTesting。

虽然我无法确切地告诉您如何将滑动传递到枢轴,但我可以告诉您如何完成工作的一部分:如何通过WebBrowser捕获/分析/禁用自定义手势。

如果我没记错的话,在7.0中:

  • WebBrowser组件几乎只包含一些包含在某些网格/边框中的内部TileHost
  • TileHost完成了与处理触摸事件相关的所有工作
  • TileHost完全在内部(在本机层)完成它,没有.Net看到任何操作事件(我认为),或者至少它忽略了处理/覆盖上层操作事件的所有尝试。 在这些问题上,WebBrowserInterop类基本上是空的。

现在,在我拥有的7.5中(也许在7.1上,我也不知道),似乎MS正在努力解决一些WebBrowser操作问题 – 我认为他们正在努力使滚动/滑动完全由.Net层。 他们编写了一个特殊类PanZoomContainer并将它们注入到WebBrowser内部模板的VisualTree中。 WebBrowserInterop极大地丰富了许多用于事件通知的隧道。 WebBrowserInterop挂钩到PanZoomContainer的ManipulationEvents,然后将它们传递给本机层。 此外,它还会侦听来自本机层的事件/命令,例如“ZoomAndScroll”或“ShowSIP” – 并且主要将它们传递回PanZoomContainer。 这个想法很清楚吧? 他们将事件处理从完全内部重新整理到一些意大利面,但已经通过PanZoomC实现了它们。

现在,对我/我们来说是什么?

它是PanZoomContainer,其Mani-Events被检查。 TileHost现在不捕获它们。 在这个版本的WebBrowser控件中,它的VisualTree由一些边框,网格,一个PanZoomContainer和一个TileHost(渲染器)组成。 它类似于:

WebBrowser PanZoom ContentPresenter Border/Name="border" <- you want this one TileHost 

我跳过了一些边框和网格,它们与问题无关。 现在,如果听到PanZoomContainer的Mani-Events,那就让我们阻止他们吧!

使用VisualTreeHelper,只需深入挖掘,直到找到FrameworkElement.Name ==“border”。 这是包装TileHost的边框,TileHost是占据控件99%空间的“渲染器”。 请注意,有一个ContentPresenter,因此您可能需要等到controltemplate被实例化(即Loaded / LayoutUpdated)。

一旦你掌握了边界,就可以将所有Mani-Event处理程序附加到它:启动,增量和完成。 PanZoom是一个普通的xaml / silverlight / .net / etc控件,所以它实际上服从e.Handled = true :)现在,如果要禁用ie。 垂直滚动,过滤翻译的Delta和Completed事件.Y <> 0。 如果要禁用点击但保留滚动/平移 - 过滤器X == 0和Y == 0。

这很容易。

困难的部分是尝试过滤不同的Start / Delta / Stop并根据您的喜好调整行为。

虽然它可能看起来非常漂亮和诱人,但这不会轻易获得任何真实/好的结果。 例如,我写道“如果你想禁用垂直滚动,那么设置一个filter'如果y == 0则e.handled = true'”。 大? 简单? 不!

假设我们想要“禁用弹性水平平移”,同时保留“垂直滚动”。 反之亦然,无论如何,这只是一个例子:

这是一个带有敏感触摸屏的小型矩形设备。 请在屏幕上进行垂直扫描/平移/拖动,生成的X-化合物将为零。 如果设置这样的filter,它几乎不可能正确。 您的用户希望杀死您,强制他们重试 - 垂直滚动五次或更多次,直到他们进行完美的垂直滑动。

当然你可以使它不是== 0,但留下一些小的余量。 好。 但是如果你使边距太大,控制器会抓住中间的轴外运动并制作一个小的水平平底锅。经过一些不幸的垂直扫动后,总的水平平底锅可能会从那些小的剩余物积累而且可能会放弃要引人注目。

但还有一些卑鄙的副作用:

简单地说,你已经提交了e.Handled = true。 活动是GONE。 死。 Deased。 如果你只是想让WebBrowser跳过例如水平滑动,那么外部(Pivot)控件会注意到它们并处理.....哎呀。 活动是GONE。 早些时候,TileHost / PanZoomC已经熄灭了这些事件,现在你已经完成了它。 听起来像个恶作剧,嗯?

Fortunatelly:

  • 由于您已将处理程序附加到最底层的“边框”,因此它们不仅可以阻止事件,还可以实际监听并在其他地方发布它们。 也就是说,如果这些处理程序检测到一个有趣的移动,它们可能e.Handled = true,但同时它们可以通知您的自定义对象有关该发现,即。 开始你的故事板。
  • mani-events即将到来,但还有第二层可以监听操作:Silverlight Toolkit中的GestureListener / GestureService。 它报告由mani事件处理后的事件,但它报告它们时不考虑在它们上设置的任何e.Handled = true。 它是完全独立的手势监听机制,您还可以使用它来检测“已取消”的操作

..所以有趣的是,甚至可能更进一步。

我不知道WP7 Pivot,但Pivot控件上是否有任何Preview *事件允许您处理触摸并将其标记为已处理?

调用以下方法并将您的参数作为PivotControl x:name和WebBrowserControl x:name传递给此方法。

这里WebBrowserControl被放置在第二个枢轴项目中,即数据透视索引为1,我试图向左或向右滑动并分别到达枢轴索引2或1。

 public static void SwipteLeftRight(Microsoft.Phone.Controls.Pivot pivotControl, Microsoft.Phone.Controls.WebBrowser webBrowserControl) { var gesListener = GestureService.GetGestureListener(webBrowserControl); gesListener.Flick += ((sen, args) => { if (args.Direction == System.Windows.Controls.Orientation.Horizontal) { if (args.HorizontalVelocity < 0) { if (((Microsoft.Phone.Controls.PivotItem)(pivotControl.SelectedItem)).Header.ToString().Trim() == "Pivot Item name") { pivotControl.SelectedIndex = 2; //Next Pivot item } } else if (args.HorizontalVelocity > 0) { if ((Microsoft.Phone.Controls.PivotItem)(pivotControl.SelectedItem)).Header.ToString().Trim() == "Pivot Item name") { pivotControl.SelectedIndex = 0; // Previous Pivot Item } } } }); } 

它对我有用。 干杯