leo
leo

Reputation: 455

How can I get touch input in uwp?

I need that if user touch on canvas control with one finger, drawing process must start and if user touch on the canvas control with two finger, canvas area must scroll/pan. How can I do this?

Thanks

Upvotes: 1

Views: 2230

Answers (1)

Grace Feng
Grace Feng

Reputation: 16652

We can use Pointer events to detect multiple fingers input in UWP. For example:

<ScrollViewer x:Name="scrollViewer" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden"
              VerticalScrollMode="Disabled" HorizontalScrollMode="Disabled">
    <canvas:CanvasControl x:Name="canvasControl" Draw="CanvasControl_Draw" CreateResources="canvasControl_CreateResources" ClearColor="CornflowerBlue"
                          PointerPressed="canvasControl_PointerPressed" PointerReleased="canvasControl_PointerReleased" PointerExited="canvasControl_PointerReleased"
                          PointerCanceled="canvasControl_PointerPressed"
                          PointerMoved="canvasControl_PointerMoved" Width="1200">
    </canvas:CanvasControl>
</ScrollViewer>

As you can see, I put a ScrollViewer out of the canvas:CanvasControl, so will the canvas be able to be scrolled. Code behind:

private CanvasRenderTarget renderTarget;

private async void CanvasControl_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
    args.DrawingSession.DrawImage(renderTarget);
}

private void canvasControl_CreateResources(CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
    renderTarget = new CanvasRenderTarget(sender, (float)sender.ActualWidth, (float)sender.ActualHeight);
}

private List<PointerPoint> m_pt = new List<PointerPoint>();

private void canvasControl_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    PointerPoint cp = e.GetCurrentPoint(canvasControl);
    m_pt.Add(cp);
    if (m_pt.Count == 2)
    {
        scrollViewer.HorizontalScrollMode = ScrollMode.Enabled;
        scrollViewer.VerticalScrollMode = ScrollMode.Enabled;
    }
}

private void canvasControl_PointerReleased(object sender, PointerRoutedEventArgs e)
{
    if (m_pt.Count == 1)
        canvasControl.Invalidate();
    scrollViewer.HorizontalScrollMode = ScrollMode.Disabled;
    scrollViewer.VerticalScrollMode = ScrollMode.Disabled;
    m_pt.Clear();
}

private void canvasControl_PointerMoved(object sender, PointerRoutedEventArgs e)
{
    if (m_pt.Count == 1)
    {
        var pt = e.GetCurrentPoint(canvasControl);
        using (var ds = renderTarget.CreateDrawingSession())
        {
            ds.DrawCircle(new Vector2((float)pt.Position.X, (float)pt.Position.Y), 2, Colors.Black);
        }
    }
    else
    {
        if (m_pt.Count > 2)
            m_pt.Clear();
    }
}

When draw with one finger, in my demo the canvas will update its layout only when the pointer is released. You can change the code to let the canvas to update every time when the pointer is moved. But I think for this, you will need to replace the canvas:CanvasControl with another Win2D control, for more information, you can refer to CanvasControl.Invalidate Method.

Upvotes: 2

Related Questions