让Viewbox和ScrollViewer一起工作

Jon*_*N89 19 c# zoom scrollviewer visual-studio windows-phone-8

我已经玩了地图,我用它ScrollViewer在地图上移动,我希望ViewBox一起使用它PinchManipulations来放大和缩小地图.到目前为止,我已经通过设置这样做ScrollViewerManipulation模式control,但是这给了我一个滞后,当我放大.有没有办法让这个ViewBoxScrollViewer更好地一起工作,从而避免滞后?我到目前为止的代码是:

ScrollViewer中:

<ScrollViewer Grid.Column ="0"  Width="768" Height="380" HorizontalScrollBarVisibility="Hidden">
    <Viewbox Stretch="None">
        <View:Map/>
    </Viewbox>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

PinchZoom:

<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>
Run Code Online (Sandbox Code Playgroud)

我使用捏缩放的代码:

public ICommand ZoomStartedCommand { get; set; }
public ICommand ZoomDeltaCommand { get; set; }
public ICommand ZoomCompletedCommand { get; set; }

private double _deltaZoom;
public double deltaZoom
{
    get
    {
        return _deltaZoom;
    }
    set
    {
        _deltaZoom = value;
        RaisePropertyChanged("deltaZoom");
    }
}

public double distance;
public MainViewModel()
{
    ZoomStartedCommand = new RelayCommand<ManipulationStartedEventArgs>(ZoomStart);
    ZoomDeltaCommand = new RelayCommand<ManipulationDeltaEventArgs>(ZoomDelta);
    ZoomCompletedCommand = new RelayCommand<ManipulationCompletedEventArgs>(ZoomCompleted);
}

public void ZoomStart(ManipulationStartedEventArgs e)
{
    FrameworkElement Element = (FrameworkElement)e.OriginalSource;

    var myScrollViewer = FindParentOfType<ScrollViewer>(Element) as ScrollViewer;
    myScrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.Control);

}

public void ZoomDelta(ManipulationDeltaEventArgs e)
{
    if (e.PinchManipulation != null)
    { 
        deltaZoom = deltaZoom * e.PinchManipulation.DeltaScale;
    }
    else
    {
        FrameworkElement Element = (FrameworkElement)e.OriginalSource;

        var myScrollViewer = FindParentOfType<ScrollViewer>(Element) as ScrollViewer;
        myScrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.System);
    }
}

public void ZoomCompleted(ManipulationCompletedEventArgs e)
{
    FrameworkElement Element = (FrameworkElement)e.OriginalSource;

    var myScrollViewer = FindParentOfType<ScrollViewer>(Element) as ScrollViewer;
    myScrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.System);
}
Run Code Online (Sandbox Code Playgroud)

JTI*_*TIM 1

我认为您应该查看视口控制器并查看基本镜头示例,他们在其中实现了此功能。视口控制器内部有一个滚动查看器和视口。

基本原理是这样的:

  1. 虽然您拥有的图像是“未缩放”的,但滚动查看器具有完全控制权,而 ViewportControl 不执行任何操作。
  2. 当您开始捏合时,通过禁用垂直滚动条并设置 viewport.height =scrollviewer.height 来锁定滚动查看器。这会中和浏览器。
  3. 您可以使用 Image ScaleTransform 进行临时缩放。
  4. 捏合完成后,调整实际图像的大小,使其占据 ViewportControl 内的实际空间。现在,您的 viewportControl 将允许您平移整个缩放图像,并具有良好的反弹效果。
  5. 当您再次缩小时,重新启用滚动查看器。(将高度设置为屏幕高度并打开滚动条。)

仅供参考,我完全忘记了为什么那里有画布,但我觉得它很重要。见下文:

虽然下面的示例没有执行您想要执行的操作,但我基于此示例中的 MediaViewer 的代码并对其进行了修改: 基本镜头示例

但需要注意的是,它是用于图片缩放。