2

Я использую обработчик события ManipulationDelta, чтобы перетащить простой эллипс на холсте по всему экрану. Я использую стандартный подход, размещенный в Интернете в нескольких местах. Ниже приведен код в моем обработчике события:Задержка при перетаскивании UIElement в Windows Phone 8.1

Ellipse dragableItem = sender as Ellipse; 
TranslateTransform translateTransform = dragableItem.RenderTransform as TranslateTransform; 
double newPosX = Canvas.GetLeft(dragableItem) + translateTransform.X + e.Delta.Translation.X; 
double newPosY = Canvas.GetTop(dragableItem) + translateTransform.Y + e.Delta.Translation.Y; 

if (!isCanvasBoundary(newPosX, TestCanvas.ActualWidth - dragableItem.ActualWidth, 0)) 
     translateTransform.X += e.Delta.Translation.X; 

if (!isCanvasBoundary(newPosY, TestCanvas.ActualHeight - dragableItem.ActualHeight, 0)) 
     translateTransform.Y += e.Delta.Translation.Y; 

операция перетаскивания работает отлично, но есть неприятная задержка около 1 секунды между моментом, когда пользователь начинает перетаскивание, когда эллипс фактически меняет свое положение. Я могу видеть, распечатывая в Debugger, что сам обработчик событий заканчивает выполнение почти мгновенно, поэтому я предполагаю, что он имеет что-то, чтобы выполнить запрограммированную частоту обновления для всех UIElements на экране, что вызывает эту задержку?

Есть ли вообще вокруг этой проблемы?

ответ

3

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

Для устранения этого запаздывания вы можете использовать PointerMove и PointerPressed события. Вот мой пример. У вас есть холст с двумя эллипсами, которые можно перетаскивать без каких-либо задержек.

XAML

<Grid> 
    <Canvas x:Name="Board" PointerMoved="Canvas_PointerMoved" Background="Black"> 
     <Ellipse Width="64" Height="64" Fill="Red" 
       Canvas.Left="32" Canvas.Top="128" PointerPressed="Ellipse_PointerPressed"/> 
     <Ellipse Width="96" Height=" 96" Fill="Blue" 
       Canvas.Left="128" Canvas.Top="16" PointerPressed="Ellipse_PointerPressed"/> 
    </Canvas> 
</Grid> 

Как вы можете видеть, я обработки PointerMoved событие в полотне и PointerPressed событие в эллипсы. Важно, чтобы фон холста не был прозрачным для обработки событий касания.

C#

public sealed partial class MainPage : Page 
{ 
    UIElement draggedItem = null; 
    Point offset; 

    public MainPage() 
    { 
     this.InitializeComponent(); 
     this.NavigationCacheMode = NavigationCacheMode.Required; 
    } 

    private void Ellipse_PointerPressed(object sender, PointerRoutedEventArgs e) 
    { 
     draggedItem = sender as UIElement; 
     offset = e.GetCurrentPoint(draggedItem).Position; 
    } 

    private void Canvas_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
     if (draggedItem == null) 
      return; 

     Point dragPoint = e.GetCurrentPoint(Board).Position; 
     Canvas.SetLeft(draggedItem, dragPoint.X - offset.X); 
     Canvas.SetTop(draggedItem, dragPoint.Y - offset.Y); 
    } 
} 

Я думаю, что код достаточно прост и понятен. Я использую PointerPressed, чтобы решить, какой объект перетаскивается. Я также вычисляю некоторое смещение, потому что мы хотим переместить объект относительно точки, в которой пользователь прикасается.

screenshot

+0

Спасибо, большое спасибо! Одна из незначительных проблем заключалась в том, что последний перемещенный эллипс изменил бы положение, даже если пользователь нажимает на часть холста, где эллипс не находится. Чтобы исправить это, я добавил событие «PointerReleased» и простую переменную bool, которая установлена ​​в true в «PointerPressed» и обратно на false в «PointerReleased». Тогда в 'PointerMoved' я проверил бы bool и только переместил бы эллипс, если бы это было правдой. Кроме того, я обнаружил, что печать чего-либо в отладчике из события «PointerMoved» знаменует существенное отставание. – Ali250

+0

@ Ali250 Более простым способом было установить 'draggedItem = null;' в событии PointerReleased вместо того, чтобы настраивать новую переменную bool –

+0

отличное альтернативное решение +1. – hushyon