#749 – Handling the TouchEnter and TouchLeave Events

When handling the raw touch events, if you touch a user interface element and then lift your finger off the element, you’ll see the events:

  • TouchDown
  • TouchUp

These two events do not capture, however, cases when you slide your finger onto or off of the element.  For this situation, you can  handle the TouchEnter and TouchLeave events, which fire when a touch contact enters or leaves the boundaries of the element.

If you then touch an element and then lift your finger off the element, you’ll see:

  • TouchEnter
  • TouchDown
  • TouchUp
  • TouchLeave

If you slide your finger onto the element and then lift your finger off the element, you’ll see:

  • TouchEnter
  • TouchUp
  • TouchLeave

Touching an element and then sliding off it leads to:

  • TouchEnter
  • TouchDown
  • TouchLeave

Finally, sliding onto and then off an element leads to:

  • TouchEnter
  • TouchLeave

#738 – Sample Code – Drawing and Moving Circles at Touch Points

Here’s some sample code that draws a circle for each touch point, when a finger contacts the screen, and then moves that circle around as you move your finger.  This is done using the raw touch events–TouchDown, TouchMove and TouchUp.

    <Canvas Name="canvMain" Background="Transparent"
        TouchDown="Canvas_TouchDown" TouchUp="Canvas_TouchUp" TouchMove="Canvas_TouchMove"/>

 

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            TouchPositions = new Dictionary<int, Point>();
            TouchEllipses = new Dictionary<int, Ellipse>();
        }

        private const double CircleWidth = 55;
        private Dictionary<int, Point> TouchPositions;
        private Dictionary<int, Ellipse> TouchEllipses;

        private void Canvas_TouchDown(object sender, TouchEventArgs e)
        {
            canvMain.CaptureTouch(e.TouchDevice);

            TouchPoint tp = e.GetTouchPoint(null);

            Ellipse el = AddEllipseAt(canvMain, tp.Position, Brushes.Red);

            TouchPositions.Add(e.TouchDevice.Id, tp.Position);
            TouchEllipses.Add(e.TouchDevice.Id, el);
            e.Handled = true;
        }

        private void Canvas_TouchMove(object sender, TouchEventArgs e)
        {
            TouchPoint tp = e.GetTouchPoint(null);

            Canvas.SetLeft(TouchEllipses[e.TouchDevice.Id], tp.Position.X - (CircleWidth / 2));
            Canvas.SetTop(TouchEllipses[e.TouchDevice.Id], tp.Position.Y - (CircleWidth / 2));
            e.Handled = true;
        }

        private void Canvas_TouchUp(object sender, TouchEventArgs e)
        {
            TouchPoint tp = e.GetTouchPoint(null);

            TouchPositions.Remove(e.TouchDevice.Id);

            canvMain.Children.Remove(TouchEllipses[e.TouchDevice.Id]);
            TouchEllipses.Remove(e.TouchDevice.Id);

            canvMain.ReleaseTouchCapture(e.TouchDevice);
            e.Handled = true;
        }

        private Ellipse AddEllipseAt(Canvas canv, Point pt, Brush brush)
        {
            Ellipse el = new Ellipse();
            el.Stroke = brush;
            el.Fill = brush;
            el.Width = CircleWidth;
            el.Height = CircleWidth;

            Canvas.SetLeft(el, pt.X - (CircleWidth / 2));
            Canvas.SetTop(el, pt.Y - (CircleWidth / 2));

            canv.Children.Add(el);

            return el;
        }

    }

738-001

#732 – Basic Events for Raw Touch Input

WPF includes a set of events for handling raw touch input.  These events are defined for all UIElement, ContentElement, and UIElement3D objects.

The most basic events are:

  • TouchDown – User touches the screen
  • TouchMove – User moves finger across the screen
  • TouchUp – User lifts finger off the screen

Below is a simple example that allows drawing using touch.  We’ve defined event handlers and attached them to a main Canvas element.  A red circle is drawn at the TouchDown point and a blue circle at the TouchUp point.  A continuous line is drawn as the user moves their finger across the screen.

        private const double CircleWidth = 10;
        private Point LastPosition;

        private void Canvas_TouchDown(object sender, TouchEventArgs e)
        {
            try
            {
                TouchPoint tp = e.GetTouchPoint(null);

                AddEllipseAt(canvMain, tp.Position, Brushes.Red);
                LastPosition = tp.Position;
            }
            catch (Exception xx)
            {
                MessageBox.Show(xx.ToString());
            }
        }

        private void Canvas_TouchMove(object sender, TouchEventArgs e)
        {
            TouchPoint tp = e.GetTouchPoint(null);

            AddLineFromTo(canvMain, LastPosition, tp.Position, Brushes.Black);
            LastPosition = tp.Position;
        }

        private void Canvas_TouchUp(object sender, TouchEventArgs e)
        {
            TouchPoint tp = e.GetTouchPoint(null);

            AddEllipseAt(canvMain, tp.Position, Brushes.Blue);
        }

        private void AddEllipseAt(Canvas canv, Point pt, Brush brush)
        {
            Ellipse el = new Ellipse();
            el.Stroke = brush;
            el.Fill = brush;
            el.Width = CircleWidth;
            el.Height = CircleWidth;

            Canvas.SetLeft(el, pt.X - (CircleWidth / 2));
            Canvas.SetTop(el, pt.Y - (CircleWidth / 2));

            canv.Children.Add(el);
        }

        private void AddLineFromTo(Canvas canv, Point from, Point to, Brush brush)
        {
            Line l = new Line();
            l.Stroke = brush;
            l.X1 = from.X;
            l.Y1 = from.Y;
            l.X2 = to.X;
            l.Y2 = to.Y;
            l.StrokeThickness = 2;

            canv.Children.Add(l);
        }

So when I touch and drag on a touch-enabled device, I get something that looks like this:

732-BasicTouch

#717 – Drag-and-Drop with Touch on Windows 7

You can implement drag-and-drop on a touch-based system in a similar way to how you implement drag-and-drop using the mouse.

You start by defining a handler for the TouchDown event of the control that serves as a drag source.  You then define a handler for the Drop event of the control that is the drop target.

    <StackPanel>
        <Label Content="Benjamin Disraeli"
               Background="AliceBlue" Margin="15" Padding="30,20" HorizontalAlignment="Center"
               TouchDown="Label_TouchDown"/>
        <Label Content="Drag to here"
               Background="Bisque" Margin="15" Padding="30,20" HorizontalAlignment="Center"
               AllowDrop="True" Drop="Label_Drop"/>
    </StackPanel>

In the code-behind, you call the DoDragDrop method to initiate drag-and-drop.

        // Drag source
        private void Label_TouchDown(object sender, TouchEventArgs e)
        {
            Label l = e.Source as Label;
            DragDrop.DoDragDrop(l, l.Content + " was Dragged!", DragDropEffects.Copy);
        }

        // Drag target
        private void Label_Drop(object sender, DragEventArgs e)
        {
            string draggedText = (string)e.Data.GetData(DataFormats.StringFormat);
            Label l = e.Source as Label;
            l.Content = draggedText;
        }

You can now touch and hold your finger down to drag.

717-001

717-002