Silverlight 应用程序中的抓取到平移 [英] Grab-to-pan in Silverlight app

查看:6
本文介绍了Silverlight 应用程序中的抓取到平移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 ScrollViewer 中有一个 Canvas.我希望用户能够抓取画布并四处移动,滚动条上的拇指会适当更新.
我的初始实现计算每次鼠标移动的偏移量,并更新滚动条:

I have a Canvas inside a ScrollViewer. I want to have the user to be able to grab the canvas and move it around, with the thumbs on the scrollbars updating appropriately.
My initial implementation calculates the offset on each mouse move, and updates the scrollbars:

 // Calculate the new drag distance
 Point newOffsetPos = e.GetPosition(MapCanvas);
 System.Diagnostics.Debug.WriteLine("   newOffsetPos : " + newOffsetPos.X + " " + newOffsetPos.Y);

 double deltaX = newOffsetPos.X - _offsetPosition.X ;
 double deltaY = newOffsetPos.Y - _offsetPosition.Y ;

 System.Diagnostics.Debug.WriteLine("   delta X / Y : " + deltaX + " " + deltaY);
 System.Diagnostics.Debug.WriteLine("   sv offsets X / Y : " + _scrollViewer.HorizontalOffset + " " + _scrollViewer.VerticalOffset);

 _scrollViewer.ScrollToHorizontalOffset(_scrollViewer.HorizontalOffset - deltaX);
 _scrollViewer.ScrollToVerticalOffset(_scrollViewer.VerticalOffset - deltaY);

 _offsetPosition = newOffsetPos;

虽然这有效,但不是很顺利.
有一个更好的方法吗?如果使用 Transforms,当 Canvas 移动时滚动条会自动更新吗?
感谢您提供任何提示...

While this works, it is not very smooth.
Is there a better way to do this? If Transforms are used, will the scrollbars update automagically when the Canvas is moved?
Thanks for any tips...

推荐答案

其实这类问题其实就是使用正确的模式来跟踪鼠标的问题.我在各种情况下都看到过这个问题,而不仅仅是在 Silverlight 中.

Actually this sort of problem is really a matter of using the right pattern to track the mouse. I've seen this issue in variety of cases not just in Silverlight.

最好的模式是捕获鼠标和主体的原始位置,然后根据固定的原始值重新计算新的偏移量.这样,鼠标在被平移的图像上的一个点上保持固定.这是我的简单 Repro:-

The best pattern is to trap the original locations of both mouse and subject, then recalculate the new offset from the fixed original values. That way the mouse stays planted solid at a single point on the image being panned. Here is my simple Repro:-

从 Visual Studio 中的全新 Silverlight 应用程序开始.修改 MainPage.Xaml 如下:-

Start with a fresh Silverlight Application in visual studio. Modify MainPage.Xaml thus:-

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Auto">
            <Image x:Name="Map" Source="test.jpg" Width="1600" Height="1200" />
        </ScrollViewer>
    </Grid>
</UserControl>

将以下代码添加到 MainPage.xaml.cs 文件中:-

Add the following code to the MainPage.xaml.cs file:-

    public MainPage()
    {
        InitializeComponent();
        Map.MouseLeftButtonDown += new MouseButtonEventHandler(Map_MouseLeftButtonDown);
    }

    void Map_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Point mapOrigin = new Point(Scroller.HorizontalOffset, Scroller.VerticalOffset);
        Point mouseOrigin = e.GetPosition(Application.Current.RootVisual);

        MouseEventHandler moveHandler = null;
        MouseButtonEventHandler upHandler = null;

        moveHandler = (s, args) =>
        {
            Point mouseNew = args.GetPosition(Application.Current.RootVisual);
            Scroller.ScrollToHorizontalOffset(mapOrigin.X - (mouseNew.X - mouseOrigin.X));
            Scroller.ScrollToVerticalOffset(mapOrigin.Y - (mouseNew.Y - mouseOrigin.Y));
        };


        upHandler = (s, args) =>
        {
            Scroller.MouseMove -= moveHandler;
            Scroller.MouseLeftButtonUp -= upHandler;
        };

        Scroller.MouseMove += moveHandler;
        Scroller.MouseLeftButtonUp += upHandler;
    }
}

给它一个相当大的 test.jpg(不需要是 1600x1200 Image 会缩放它).

Give it a reasonably large test.jpg (doesn't need to be 1600x1200 Image will scale it).

您会注意到,在拖动鼠标时,鼠标会准确地停留在图像中的一个固定点上,直到您到达边界为止.以您喜欢的速度移动鼠标,它始终跟踪,这是因为它不依赖于准确和最新的增量.唯一的变量是当前鼠标位置,其他值在鼠标按下时保持不变.

You'll note that when dragging the mouse remains exactly over a fixed point in the image until you hit a boundary. Move the mouse as fast as you like it always tracks, this is because it doesn't depend on deltas being accurate and up-to-date. The only variable is the current mouse position, the other values remain fixed as they were at mouse down.

这篇关于Silverlight 应用程序中的抓取到平移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆