Reputation: 9397
I am working on a WPF application which is being used on a Touch Screen Tablet. I develop using VS2015 IDE and I use my Mouse to debug.
I must handle buttons' down
and up
events to execute certain tasks. I use PreviewMouse
and PreviewTouch
event handlers and I have a problem in every case I use:
Case 1: Using PreviewMouseDown
,PreviewMouseUp
,PreviewTouchDown
and PreviewTouchUp
. For each button, I need to duplicate my code to include separate Touch and Mouse Event handlers but the exact same functionality. I do this for me to be able to use the Application (Mouse) and for the the user to use it (Touch). Problem: Touch Event Handlers executes Mouse Event Handlers; Causing the application to duplicate the behavior. Ex: A button that increments x
by one, will increment by one if you "Click" it but increment by two if you "Touch" it.
Case 2: Using Click
, PreviewMouseUp
and PreviewTouchUp
. Problem: The PreviewTouchUp
and PreviewMouseUp
do not get called on Mouse Click.
Case 3: Create a method for each button and call it from both Touch and Mouse events like How to get Touchscreen to use Mouse Events. Problem: Duplicate behavior (method gets called twice)
Case 4: Remove all Touch events since PreviewMouseDown
and PreviewMouseUp
are being executed on any Touch. The behavior works but I need to Touch certain positions on the button in order for it to execute. (Transparency? I must touch exactly one position - like a mouse?)
Case 5: Using MouseUp
and MouseDown
instead of Preview
. Didn't work on Touch at all, touching any position on the button.
I want something similar to this Prevent a WPF application to interpret touch events as mouse events but only on the tablet. I still need to use my mouse in my environment. How can I fix that?
Button sample XAML:
<Button x:Name="locationScrollUpButton" Margin="0,5,5,0" Background="Transparent" Padding="0" Grid.Row="1" Grid.Column="1" PreviewMouseUp="locationScrollUpButton_PreviewMouseUp" PreviewMouseDown="locationScrollUpButton_PreviewMouseDown" BorderThickness="0" PreviewTouchDown="locationScrollUpButton_PreviewTouchDown" PreviewTouchUp="locationScrollUpButton_PreviewTouchUp" >
<StackPanel>
<TextBlock x:Name="locationUpButtonText" Text="Up" FontSize="13" Margin="0,2,0,4" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image x:Name="locationUpButtonImage" Source="/ProjectName;component/Resources/CaptureView/Location-Scroll-Up-White.png" Width="55" Height="60"/>
</StackPanel>
</Button>
Upvotes: 8
Views: 8008
Reputation: 9397
So I ended up doing it using a cool hack. Based on Ahmad's answer on this other question HERE we know the fire order of the handlers:
On Touch Devices:
TouchDown > PreviewMouseDown > TouchUp > PreviewMouseUp
On Non Touch:
PreviewMouseDown > PreviewMouseUp
And based on @M.Kazem comments here. The fix now looks something like this:
private bool ButtonPreview = true;
private void Button_TouchDown(object sender, TouchEventArgs e)
{
// task 1
ButtonPreview = false;
}
private void Button_TouchUp(object sender, TouchEventArgs e)
{
// task 2
// ..
}
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (ButtonXPreview)
{
// task 1
}
else
ButtonXPreview = true;
}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (ButtonXPreview)
{
// task 2
}
else
ButtonXPreview = true;
}
Upvotes: 4
Reputation: 191
Check the StylusDevice property of the MouseEventArgs. If it is null, then the mouse event is not a promoted touch event. If it's not null, then the StylusDevice will be the touch device that initiated the touch that got promoted.
Upvotes: 10