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.
Related
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.
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
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.
Is there any way to register a global event handler for catching mouse events in a Silverlight application? I'd like to avoid subscribing to the mouse event handlers of each FrameworkElement and find a more elegant solution (bubbled events).
Thanks
MouseMove is a bubbling event in Silverlight; have you tried to catch it at the level of the Window ?
All the Mouse events are bubbling events so on the surface of it you should be able to attach event handlers to a root UserControl or Page element and get the events.
However many of the controls have use for the mouse events and handle these events themselves. In those cases those events do not bubble any futher.
So I have a Grid on a page that has a few UserControls on it. Each UserControl has a MouseLeftButtonDown event registered, as does the Grid. Before i added the event to the grid, the events on the user controls worked fine. But now that i have the event on the Grid, only the grid event fires regardless of where i click. None of the UseControls are capturing the event.
What do i need to do to allow the MouseLeftButtonDown events on the UserControls to fire while still having the MouseLeftButtonDown event on the Grid?
What you describe is very unusual.
What would often happen in this case it that both events fire. Since MouseLeftButtonDown is a bubbling event when you click on a UserControl it fires its MouseLeftButtonDown, if the handler attached to it doesn't set the Handled property of the MouseButtonEventArgs parameter to True then the event will bubble up to the parent and so on. If the parent controls also have code attached to their MouseLeftButtonDown events that code will also run.
Are sure that in fact the UserControl events don't fire or is that you happen to observe that the Grid event was always firing. If you are absolutely certain that attaching a event handler to the Grid actually prevents the UserControl events from firing can you edit your question with a small Repro, its very hard to see how this could be the case.