让Viewbox和ScrollViewer一起工作

时间:2013-11-29 14:21:36

标签: c# visual-studio windows-phone-8 zoom scrollviewer

我已经在播放地图,我使用ScrollViewer在地图上移动,我希望将ViewBoxPinchManipulations一起放大和缩小地图。到目前为止,我已经通过将ScrollViewer的{​​{1}}模式设置为Manipulation来完成此操作,但这会让我在缩放时出现延迟。有没有办法让controlViewBox更好地协同工作,从而避免滞后?我到目前为止的代码是:

的ScrollViewer:

ScrollViewer

PinchZoom:

<ScrollViewer Grid.Column ="0"  Width="768" Height="380" HorizontalScrollBarVisibility="Hidden">
    <Viewbox Stretch="None">
        <View:Map/>
    </Viewbox>
</ScrollViewer>

我使用捏缩放的代码:

<Grid x:Name="Map" Width="1271" Height="1381.5">

    <Grid.RenderTransform>
        <ScaleTransform ScaleX="{Binding Path=deltaZoom}" ScaleY="{Binding Path=deltaZoom}"/>
    </Grid.RenderTransform>

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="ManipulationStarted">
            <cmd:EventToCommand Command="{Binding Path=ZoomStartedCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>

        <i:EventTrigger EventName="ManipulationDelta">
            <cmd:EventToCommand Command="{Binding Path=ZoomDeltaCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>

        <i:EventTrigger EventName="ManipulationCompleted">
            <cmd:EventToCommand Command="{Binding Path=ZoomCompletedCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

</Grid>

2 个答案:

答案 0 :(得分:2)

当我尝试在单个容器中处理大量数据时,我也遇到了这个问题。 您不能简单地在视图框中加载整个地图并使用滚动查看器,并期望一切都能正常工作。

使应用程序在大数据集上表现良好的第一个解决方案是尝试 UI虚拟化。接受虚拟化的控件仅创建显示当前视图所需的元素,或者更确切地说,仅创建显示器上可见的元素。为了更好地理解这个概念,我将给你一个真实世界的例子。看看Facebook如何呈现其新闻Feed。它在X html元素中加载X个帖子,然后当用户向下滚动时,它会卸载不可见的帖子并加载新的帖子。

1.UI虚拟化

它只是重用元素。这是UI虚拟化的概念。我必须提到一个重要的功能:延迟滚动(用户可以滚动但结果仅在点击发布后显示,如果用户喜欢使用滚动条上下播放,这是性能提升)

回到你的问题。如果地图是完全加载的,则滚动或放大是一个性能问题,因为不可见部分也会缩放和滚动。想象一下,如果谷歌地图不支持UI虚拟化会发生什么。当用户尝试放大时,所有地球都会放大(吨数GB)。

2.Data Virtualization

但是,您的地图应该在内存中的某处完全加载。如果它很大,这是一个问题,它来自数据虚拟化。 它不是将所有地图完全加载,而是仅加载显示所需的部分。如果您希望获得更好的响应能力,则可以使用Google地图使用的概念。将更多数据加载到内存中,而不是在渲染时将其加载到显示器上,因此当您尝试滚动时,UI不会冻结(直到数据被带入内存)。

您可以阅读更多内容:

  1. Implementing virtualized panel
  2. Item container generator
  3. Measure core
  4. Results
  5. 我使用Virtualized Canvas解决了我的问题。使用虚拟化画布的应用示例:http://pavzav.blogspot.ro/2010/11/virtualized-canvas.html

    您可能想看一下Wpf Bing Maps Control

答案 1 :(得分:1)

我认为您应该改为查看视口控制器并查看基本镜头示例,他们已经实现了这一点。 viewportcontroller,里面有一个scrollviewer和viewport。

基础是:

  1. 虽然您拥有的图像是“unzoomed”,但是滚动查看器具有完全控制权并且ViewportControl不执行任何操作。
  2. 当您开始捏合时,通过禁用verticalscrollbar并设置viewport.height = scrollviewer.height来锁定滚动查看器。这中和了scollviewer。
  3. 您可以使用Image ScaleTransform进行临时缩放。
  4. 在捏合完成后,调整实际图像的大小,使其占用ViewportControl内的真实空间。现在你的viewportControl将让你在整个缩放的图像上平移,并有很好的反弹。
  5. 再次缩小时,请重新启用滚动查看器。 (将高度设置为屏幕高度并打开滚动条。)
  6. 仅供参考,我完全忘记为什么那里有帆布,但我觉得这很重要。见下文:

    虽然下面的示例不能执行您想要执行的操作,但我将此代码基于此示例中的MediaViewer并对其进行了修改: Basic Lens Sample

    然而,应该注意它是用于图片缩放。