【问题标题】:WP7 Pivot control and a WebBrowser controlWP7 Pivot 控件和 WebBrowser 控件
【发布时间】:2014-06-18 20:29:21
【问题描述】:

我有一个 Pivot,其中包含一个 WebBrowser 控件,该控件实际上占据了整个页面(当然来自 Pivot 标题)。

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

这个可以吗?

谢谢

【问题讨论】:

    标签: c# silverlight windows-phone-7


    【解决方案1】:

    虽然我无法准确告诉您如何将滑动传递给枢轴,但我可以告诉您如何完成部分工作:如何在 WebBrowser 上捕捉/分析/禁用自定义手势。

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

    • WebBrowser 组件几乎只包含一个内部 TileHost,该 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 的边框,它是占据控件 99% 空间的“渲染器”。请注意,有一个 ContentPresenter,因此您可能必须等到控件模板被实例化(即 Loaded/LayoutUpdated)。

    一旦您将手放在该边界上,请将所有 Mani-Event 处理程序附加到它:开始、增量和完成。 PanZoom 是一个普通的 xaml/silverlight/.net/etc 控件,所以它实际上服从 e.Handled = true :) 现在,如果你想禁用 ie。垂直滚动,过滤 Translation.Y0 的 Delta 和 Completed 事件。如果您想禁用点击但保留滚动/平移 - 过滤 X==0&Y==0。

    这是最简单的部分。

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

    虽然它可能看起来非常漂亮和诱人,但这不会轻易为您带来任何真实/漂亮的结果。例如,我写了“如果你想禁用垂直滚动,那么设置一个过滤器'if y==0 then e.handled=true'”。伟大的?简单的?没有!

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

    这是一个带有灵敏触摸屏的小型矩形设备。请在屏幕上进行垂直滑动/平移/拖动,以使生成的 X-compound 为零。如果你设置这样的过滤器,它几乎是不可能正确的。你的用户会想杀了你,因为你强迫他们重试垂直滚动五次或更多次,直到他们做出完美的垂直滑动。

    当然你可以让它不 ==0,但要留一些小余量。好的。但是如果你把边距设置得太大,控件会捕捉到中间的离轴运动,也会产生一个很小的水平平移。在几次不幸的垂直滑动之后,总的水平平移可能会从那些小的剩余物累积起来,位移可能会引人注目。

    但还有一些其他恶毒的副作用:

    简单地说,您已经提交了 e.Handled=true。活动结束了。死的。死亡。如果您只是想让 WebBrowser 跳过例如水平滑动,以便外部(枢轴)控件注意到它们并处理......哎呀。活动结束了。早些时候,TileHost/PanZoomC 已经熄灭了事件,现在您自己完成了。听起来像个糟糕的笑话,嗯?

    幸运的是:

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

    .. 所以乐趣就这样开始了,甚至可能更进一步。

    【讨论】:

    【解决方案2】:

    这类似于将地图放入 Pivot - 此处讨论 - http://mine.tuxfamily.org/?p=111 - 已经在很多问题中提到 - https://stackoverflow.com/search?q=mine.tuxfamily.org

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

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

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

    【讨论】:

    • 是的,我想到了,但它是一个需要链接和滚动的活动网络浏览器控件。
    【解决方案3】:

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

    【讨论】:

    • silverlight 中没有预览事件
    【解决方案4】:

    调用以下方法并将您的参数作为 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
                            }
                        }
                    }
                });
            }
    

    它对我有用。干杯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多