Capture all Click or Touch events recursively in WPF - wpf

am pretty new to WPF, but am looking to capture whenever anyone touches inside a window or any child controls.
If I capture the click event for a Window, only the windows inner space capture the click. It's child controls do not.
How do i recursively capture any click/touch event ANYWHERE on the screen in a full size window?
many thanks in advance

The routed event handling implementation in WPF is intended to give all controls in a nested hierarchy a chance to intercept and handle touch & mouse events. However, controls have the ability to prevent children from receiving the event notification.
There's a pretty good explanation of event routing here: http://nui.joshland.org/2010/04/why-wont-wpf-controls-work-with-touch.html
All controls receive a Preview event (for click or touch), and this cannot be prevented. After this, the event is 'promoted' to a regular Mouse/Touch event (touch is handled before click) However, if any control in the hierarchy for the 'click' (_MouseDown in WPF) event handling sets the Handled property on the event args to true, then the event will not be propagated any further.
Unless you are handling touch events or manipulations, or explicitly setting e.Handled = true in your code, then all controls in a nested stack should receive the _MouseDown event.
As noted in the comments below, some controls will set 'Handled = true' which would prevent their containers from receiving corresponding _TouchDown or _MouseDown events. However, they would all receive a PreviewTouch/PreviewMouseDown first.
Also note that handling touch events prevents handling of mouse events.

Related

WPF TouchUp Event Strange behaivor

My WPF app functions perfectly, but only when using a mouse. Troubles start when using it on a device with a touch screen..
I have a grid that handles MouseLeftButtonUp and TouchUp events.
Now, I press on the grid, it handles related events, then I press on some other control, that other control catches TouchUp event as expected, then TouchUp event is transformed into MouseLeftButtonUp event, which is also something to expect.
However, the newly fired MouseLeftButtonUp event is fired NOT for the control that I pressed on, but for the above mentioned grid! Why does it behave this way?
Thank you in advance...
This is normal behaviour for all RoutedEvents. From the UIElement.MouseLeftButtonUp event page on MSDN:
Although this routed event seems to follow a bubbling route through an element tree, it actually is a direct routed event that is raised and reraised along the element tree by each UIElement.
MSDN provides far more answers and far quicker than Stack Overflow.

Difference between Bubbling and Tunneling events

What is the exact difference between Bubbling Events and Tunneling events?
Where should I use Bubbling Events and where should I use Tunneling events?
WPF gives us a number of different mechanisms for handling events –
they are bubbling, tunneling, and direct. These are all known as
Routed events.
Direct event
You are probably already used to the direct routed event. This is
where the item itself handles the event that occurred. A good example
would be handling he onClick-event of a mouse button in standard
WinForms. This is where the event is raised in the GUI item and gets
handled by said GUI element.
Bubbling Event
Now we all like some bubbles in one form or another. Bubbling happens
when the event is not handled by the element ( say a textbox) and the
event "bubbles" its way up the UI containers which hold it. For
example, let's say you have a window that contains a panel and inside
that panel you have a grid and inside the grid you have a textbox. If
the event is not handled by the textbox, then it moves, is passed or
"bubbles" up to the grid level (as the grid contains the textbox), if
it is not handled at that level then the event bubbles further up the
"tree" (known as a visual tree) to the panel where it may or may not
be handled. This process continues until it is handled or the event
"escapes" the top most element.
Examples of a bubbling event would be something like a
MouseButtonDown event. Or a Keydown event.
Tunneling
Tunneling is the opposite of Bubbling. So instead of an event going
"up" the visual tree, the event travels down the visual tree toward
the element that is considered the source. The standard WPF naming
definition of a tunneling event is that they all start with "preview"
for example previewdownkey and previewmousebuttondown. You can
catch them on their way to the "target" element and handle it. An
example for this might be perhaps you have some controls inside a grid
control and for some reason you have decided that no control within
that grid will be allowed to have the letter "t" reach it.
Source with the opinion of the author which I don't support nor agree with.
And another StackOverflow question which is pretty much the same.
A nice demo project
And last but not least some explanation and another tutorial.
As a start: the naming convention in WPF for some default events is Preview<event> for tunneling and <event> for bubbling. So for example for the KeyDown we would have PreviewKeyDown and KeyDown, tunneling and bubbling respectively.
The difference between the two, as the naming convention implies, is that a tunneling event will start at the highest node in the tree (probably the Window) and going down to the lowest child. A bubbling event will start at the child and then go upwards again.
This guide should explain it clearly:
http://www.codeproject.com/Articles/464926/To-bubble-or-tunnel-basic-WPF-events

differences between routed events and attached events and what differences they make?

I am just going through the WPF concepts I came across these routed events ,dependency properties and attached events.
I think I am not able to understand the concepts behind them and why they were being called in the place of .net originated methods?
Routed Events provide the ability for different controls in the element tree to react to events.
For instance, if we have a Window containing a StackPanel containing a Button and someone presses the mouse key on the button, the events will be fired in this order:
PreviewMouseDown on Window
PreviewMouseDown on StackPanel
PreviewMouseDown on Button
MouseDown on Button
MouseDown on StackPanel
MouseDown on Window
These "preview" events use a behavior called Tunneling. The normal events Bubble up again.
If you set the Handled property of the EventArgs to true, the tunneling and bubbling will stop. Tunneling or Bubbling is called the Routing Strategy.
This enables handling a variety of situations, for instance:
Preventing any child element of the StackPanel to receive mouse down events. (Set Handled to true on StackPanel.PreviewMouseDown).
Handling key presses on a Window that have not been handled by any other control (Window.KeyDown)
I would advise not looking into Attached Events untill this becomes absolutely necessary. The scenario's for attached events are very limited. Attached events are also routed events.

Event called by the control or its Parent control

If there is a button within a group box on a win form, and when the "click" event occurs, then who is actually calling the Event. Is it the button contorl or its parent i.e. GroupBox.
If you'd have written a native Windows GUI program then it would be the group box that got the click message. Buttons send notification to their parents. But that gets re-routed in Winforms, both through sub-classing and having the container window reflect messages back to the child control.
Events always originate at the control. Their OnClick() method in case of a click. You however still handle the event at a higher level window. Typically the form, not the groupbox. The sender argument of the event handler passes a reference to the control. Having a choice over exactly where you handle the event is a major advantage over the native way. It makes controls highly adaptable and composable.

MouseLeftButtonUpEvent & Bubbling in Canvas

I think I'm going crazy...
I have Canvas with event handlers for MouseMove & MouseLeftButtonUp.
However MouseLeftButtonUp is not being fired when it happens with cursor over TextBlock that is inside canvas.
(it fires just fine when I release mouse button in empty space of the canvas)
I tried attaching handler via AddHandler and using regular += syntax, nothing seems to work.
I tried using Canvas.CaptureMouse() but it doesnt seem to work either (CaptureMouse returns true btw).
MouseLeftButtonUp just doesnt want to propagate to it's parent when it happens over TextBlock (or any other element with IsHitTestVisible = true) inside Canvas.
Please help.
First I'd like to say that you are not going crazy. I've seen this before in Silverlight applications. Silverlight has some interesting event strategies. Silverlight events follow a bubble up approach for routed events but not with all events (msdn has some information on this) The events you are listening to are in that list but they are being handled by the TextBlock. Most UIElements have IsHitTestVisible=true so that mouse events and others are captured by the control and not bubbled up to its parent. Setting IsHitTestVisible=false should solve the problem. Other than that I can tell you what I have tried to overcome this issue when needing IsHitTestVisible=true.
Set the event hanlder from the parent on the TextBlock. Downside is you need to do this for every control in your canvas.
Try to fire the event through an extension class. I could not get this one to work cause i couldn't fire events using reflection.
You mentioned you tried AddHandler - did you try the AddHandler overload that accepts two parameters, the second one being "true" to indicate you want to get handled events as well?

Resources