Захватить в приложении Silverlight - PullRequest
3 голосов
/ 01 февраля 2010

У меня есть холст внутри ScrollViewer. Я хочу, чтобы пользователь мог захватывать холст и перемещать его, при этом большие пальцы на полосах прокрутки обновляются соответствующим образом.
Моя первоначальная реализация вычисляет смещение при каждом движении мыши и обновляет полосы прокрутки:

 // 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;

Хотя это работает, это не очень гладко.
Есть лучший способ сделать это? Если используются преобразования, будут ли полосы прокрутки обновляться автоматически при перемещении холста?
Спасибо за любые советы ...

Ответы [ 2 ]

2 голосов
/ 02 февраля 2010

На самом деле проблема такого рода заключается в использовании правильного шаблона для отслеживания мыши. Я видел эту проблему во многих случаях, а не только в Silverlight.

Лучший шаблон - отловить исходные местоположения как мыши, так и объекта, а затем пересчитать новое смещение из фиксированных исходных значений. Таким образом, мышь остается сплошной в одной точке на панорамируемом изображении. Вот мое простое Repro: -

Начните со свежего приложения Silverlight в визуальной студии. Измените MainPage.Xaml таким образом: -

<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: -

    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 будет масштабировать его).

Вы заметите, что при перетаскивании мышь остается точно над фиксированной точкой на изображении, пока не достигнет границы. Двигайте мышь так быстро, как вам нравится, она всегда отслеживается, это потому, что она не зависит от точности и актуальности дельт. Единственная переменная - текущая позиция мыши, остальные значения остаются неизменными, как при наведении мыши.

0 голосов
/ 01 февраля 2010

Вы можете попробовать это (или хотя бы взглянуть на то, как это реализовано).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...