Windows Phone:无法使ViewportControl对齐

时间:2014-07-06 15:36:40

标签: c# silverlight xaml windows-phone-8 pinchzoom

我一直在尝试使用Windows Phone 8 Silverlight应用程序中的ViewportControl类实现捏拉缩放很长一段时间没有任何成功。有一些很棒的样本,例如this one,但我无法将我找到的示例映射到我的场景中。

捏合和缩放工作正常,我遇到的问题是在操作完成后视口与内容的对齐。

我面临的主要问题是,在我的操作完成后,我无法将缩放的内容(一个XAML画布和子树,它是ViewportControl的子节点)与视口对齐。这导致视口(可滚动区域)的有效边界偏离我的内容,导致我的部分内容无法访问/不可滚动。

这是我的操作算法:

  1. 开始捏合操作。
  2. 在捏合期间将渲染变换应用于画布'子树。
  3. 操作完成。
  4. 将主画布缩放到有效大小 渲染变换后的子树(按预期工作,画布与渲染变换后的子树对齐)。
  5. 在ViewportControl内的画布和视口控件本身之间获取转换。
  6. 使用转换来获取一个边界矩形(我希望)应该代表一个矩形,它覆盖我要在ViewportControl中滚动的内容, 但是在托管ViewportControl的坐标空间中。
  7. 将此rect应用为ViewportControl的视口边界。
  8. 将视口的原点设置为平移的画布左上角坐标
  9. 这是我在操作完成后计算并应用新边界的地方:

     // Obtain transform between canvas and ViewportControl            
     GeneralTransform gt = m_MainCanvas.TransformToVisual(m_ViewportControl);
     Rect newBounds = gt.TransformBounds(new Rect(0, 0, m_MainCanvas.Width, m_MainCanvas.Height));
     m_ViewportControl.Bounds = newBounds;
    
     // set the origin of the viewport again
     m_ViewportControl.SetViewportOrigin(gt.Transform(new Point(0, 0)));
    

    这导致我的内容与视口错位。

    尝试,尽我所能,我无法弄清楚我在这里做错了什么......甚至在查看了如何解决这个问题的教程后......:|

    我认为发生的事情是我正在设置边界的矩形是正确的,但它的X和Y坐标是关闭的。我希望通过使用canvas和ViewportControl本身之间的转换来解决这个问题,但显然不是。

    问题:如何正确设置ViewportControl的原点(如何计算传递给SetViewportOrigin方法的点?有人可以解释人们在缩放内容和视口之间使用的比例吗?在其他例子中看到如何破解这个?

    2014年7月8日更新

    我在这里取得了一些进展。我在ViewportControl中的内容与控件本身之间进行转换的方法,然后使用它来获取控件空间中的rect以用作视口的边界是不起作用的。我的解决方法是简单地将渲染转换的内容包装在画布中,我调整了有效(渲染转换)大小的大小。然后我将界限设置为那个大小,我终于有了很好的反弹效果。

    我现在面临的问题是,当我调整画布大小并重置视口的边界时,内容会捕捉到视口的左上角,并且不再以用户的收缩区域为中心提供。

    有谁能帮我理解SetViewportOrigin方法如何在ViewportControl上运行?在捏合操作后,我看到Viewport与画布有一些非常奇怪的数据:

    Canvas Size = 1025.69, 1641.11
    Bounds = 0,0,1025.69,1641.11
    viewport = -56,41.00,480,698
    

    当我甚至不调用SetViewportOrigin(Point)时,为什么视口偏移为非零值(x,y = -56,41)?

    以下是我认为SetViewportOrigin(Point)方法有效的方法:假设我的Viewport控件本身大小为400 x 400像素,我的内容为800 x 800像素。如果我将视口的原点设置为100,100将滚动内容,使得前100个垂直像素和100个水平像素将被剪裁/屏蔽/屏幕外。这不是ViewportControl的工作方式吗?

1 个答案:

答案 0 :(得分:0)

我想到了这一点,现在我是一个快乐的露营者。事实证明,我使用错误的坐标空间将视口原点设置为一个点。我想如果我想将内容移动到某个地方,我会在视口的坐标空间中提供该点,内容将滚动(设置内容的左上角)。我想到的是SetViewportOrigin方法采用的Point数据是在内容的坐标空间中。例如:如果您的内容宽度为500 x 500像素,则视口宽度为400 x 400像素,并且您希望视口遮住前100个垂直像素和100个水平像素(显示右下角)的内容),您将原点设置为100,100,而不是-100,100。

我在坐标空间之间做了一堆无用的转换,试图将视口传递到坐标系中的一个点。