I have the following XAML code:
<Grid Background="Blue">
<Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<CheckBox MouseLeftButtonDown="CheckBox_MouseLeftButtonDown_1"></CheckBox>
</Grid>
</Grid>
When i click the checkbox with the mouse left button, the declared event is not fired.
Can anyone have an explanation for this behaviour?
Thanks in advance
The event is being handled by something else (probably being consumed by the Checked event).
If you change the event to PreviewMouseLeftButtonDown (the tunneling version of MouseLeftButtonDown), it will fire properly.
The CheckBox inherits from ButtonBase, which add a class handler for the left button down event (OnMouseLeftButtonDown). As the documentation for UIElement.MouseLeftButtonDown event mentions (emphasis mine):
Some control classes might have
inherent class handling for mouse
button events. The left mouse button
down event is the most likely event to
have class handling in a control. The
class handling often marks the
underlying Mouse class event as
handled. Once the event is marked
handled, other instance handlers that
are attached to that element are not
ordinarily raised. Any other class or
instance handlers that are attached to
elements in the bubbling direction
towards the root in the UI tree are
also not ordinarily raised.
You can play with the ClickMode and set it to ClickMode.Hover, which seems to prevent the behavior you are seeing. However, you might have to then maintain a custom logic in your event handler for this particular instance to set the proper toggle state of your check box.
You can also try the PreviewMouseLeftButtonDown event. However, marking that event as handled in your handler might have side effects on the rest of the MouseDown events - they will carry the handled information, which will prevent other instance handlers unless they are added with AddHandler with the flag for handling already handled events.
Franci thanks for your reply...I need to checkbox MouseLeftDownEvent to fire, and setting clickMode = hover solved my problem. I need MouseleftDownEvent to bubble the event to the parent grid.
Related
I have a Grid with a Button inside. The button has Flyout menu attached.
I implemented an action which opens the flyout menu when the button is tapped/clicked. This is the default behavior which does not require event writing. I also implemented an action when the grid is tapped/clicked.
The problem is that I do not want the grid to react when I tap/click the button. Based on this fine read, it all makes sense, but in my case, I do not have any code behind to add the e.Handled = true; line to.
Is there any way I could stop event bubbling up the tree using XAML only? Thanks!
While I hate to poach Gusdor's points. There is a built an enumeration property to deal with this types of situations called ClickMode which you can override the default mode for Button of Release and set it at the instance as ClickMode="Press" to get the desired effect and allow it to receive HitTestVisibility individually before any parent does.
Hope this helps, cheers.
I believe you will need to write some code but not the code behind you are trying to avoid.
Create an attached behavior that subscribes to, and handles the
bubbling event.
Attach the behaviour to the element where you want
the event bubbling to stop.
There is a Microsoft article about plugging Behaviours into UWP apps https://blogs.windows.com/buildingapps/2015/11/30/xaml-behaviors-open-source-and-on-uwp/
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.
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.
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.
I would need to draw lots of WPF-paths. I have set them to children of canvas. Problems is that events are tunneled to path-objects. That slows down the performance. I know overriding preview-method fix the problem, but do I really have to override all preview-methods..
I think you can catch the event in the Canvas and set e.Handled to true.
I found solution. I set path objects's IsHitTestVisible-property to false. Now they doesn't slow down the performance.
Not to resurrect old questions but, if there were e.g. buttons instead of paths, setting IsHitTestVisible to true would have not been ok since it effectively prevents Click and other events.
In my case I had a TabItem with a PreviewMouseMove event and a Button on that very TabItem with a Click event that didn't fire.
The thing is that if you got a tunneling event (like PreviewMouseMove) on a parent control, it will "override" similar events on its child controls.
A possible solution - the one that worked out for me - is picking up a different bubbling event, like MouseMove.
In short, bubbling events propagate to parent elements, while tunneling events propagate to child elements; there are also direct events that do not propagate at all.
More on the topic here.