5
votes

Detecting touch in Windows Phone 8 leverages the System.Windows.Input.Touch.FrameReported event which is the most raw and certainly the most responsive touch event available to developers.

You would use the event like this:

public MainPage()
{
    InitializeComponent();

    // setup sounds
    Ellipse1.Tag = new Uri("Sounds/GVD_snr1.wav", UriKind.Relative);
    Ellipse2.Tag = new Uri("Sounds/GVD_snr2.wav", UriKind.Relative);
    Ellipse3.Tag = new Uri("Sounds/GVD_snr3.wav", UriKind.Relative);
    Ellipse4.Tag = new Uri("Sounds/GVD_snr4.wav", UriKind.Relative);
    Ellipse5.Tag = new Uri("Sounds/GVD_snr5.wav", UriKind.Relative);
    Ellipse6.Tag = new Uri("Sounds/GVD_snr6.wav", UriKind.Relative);
    Ellipse7.Tag = new Uri("Sounds/Gong.wav", UriKind.Relative);

    // respond to touch(es)
    var _Ellipses = new[] { Ellipse1, Ellipse2, Ellipse3, Ellipse4, Ellipse5, Ellipse6, Ellipse7 };
    System.Windows.Input.Touch.FrameReported += (s, e) =>
    {
        var _Touches =
            from touch in e.GetTouchPoints(null)
            where touch.Action == System.Windows.Input.TouchAction.Down
            let ellipse = touch.TouchDevice.DirectlyOver as Ellipse
            where _Ellipses.Contains(ellipse)
            select ellipse;
        System.Diagnostics.Debug.WriteLine("{0} touch(es).", _Touches.Count());
        foreach (var ellipse in _Touches)
        {
            var _Stream = Application.GetResourceStream(ellipse.Tag as Uri).Stream;
            var _SoundEffect = Microsoft.Xna.Framework.Audio.SoundEffect.FromStream(_Stream);
            Microsoft.Xna.Framework.FrameworkDispatcher.Update();
            _SoundEffect.Play();
        }
    };
}

(tested with a Lumia 920)

This works like a charm - as long as there is only a single touch at a time. When the user attempts to touch two or more points simultaneously (and I mean exactly the same time) the event is not raised at all. When the user attempts to touch two or more points almost simultaneously (just a split second apart) then the event is raised and both points are reported.

How can I detect two simultaneous touches?

In case you want to see the XAML, here's the XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

    <Grid.Resources>
        <Style TargetType="Ellipse">
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="VerticalAlignment" Value="Top" />
        </Style>
    </Grid.Resources>

    <Ellipse x:Name="Ellipse1" Fill="Blue" Height="177" Margin="17,17,0,0" Width="177"/>
    <Ellipse x:Name="Ellipse2" Fill="#FFFFA300" Height="223" Margin="212,25,0,0" Width="223"/>
    <Ellipse x:Name="Ellipse3" Fill="#FFFF00E8" Height="97" Margin="89,207,0,0" Width="97"/>
    <Ellipse x:Name="Ellipse4" Fill="#FF00C135" Height="162" Margin="186,249,0,0" Width="162"/>
    <Ellipse x:Name="Ellipse5" Fill="#FF00AEFF" Height="272" Margin="59,416,0,-81" Width="272"/>
    <Ellipse x:Name="Ellipse6" Fill="Red" Height="97" Margin="320,395,0,0" Width="97"/>
    <Ellipse x:Name="Ellipse7" Fill="#FFF3FF00" Height="133" Margin="10,304,0,0" Width="133"/>

</Grid>
1
@Jerry.. Did you try this? Have a lastTappedTime tick in a instance variable. Handle the Tap event in all of the ellipses and check the difference between lastTappedTime and now time. If difference is less than 200 milliseconds we can safely consider it Simul-Touch otherwise Set the new lastTappedTime.kanchirk
To be more clear, the problem is not detecting if they are simultaneous, it is that two simultaneous touches do not raise the FrameReported event.Jerry Nixon
Thanks for clarifying.kanchirk

1 Answers

0
votes

Adding this resolved the problem:

var _Timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(50) };
_Timer.Tick += (s, e) =>
{
    try { Microsoft.Xna.Framework.FrameworkDispatcher.Update(); }
    catch { }
};
_Timer.Start();