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.
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/
In Winforms if the MDI child window is maximized it doesn't receive ResizeBegin (or ResizeEnd) events. It does receive Resize events - why the distinction? If the child isn't maximized it does get ResizeBegin/End events. Is there a nice way around this? There are plenty of ugly ways: calling directly from the MDI container ResizeBegin event to the child for example.
The ResizeBegin/End events are generated when the user starts and stops resizing a window. Implemented by a modal loop inside Windows itself, it keeps the window edge following the mouse cursor when the user moves it. ResizeBegin when he clicks a window edge, ResizeEnd when he releases the mouse button.
Clearly no user is involved when you change the Size or ClientSize property of an MDI child window in your code. So no Begin or End, just the Resize event. And just one Resize event trigger, there's no constant train of them like there will be when the user uses the mouse to resize. Which otherwise explains why Begin/End is important, if you do a lot of work in your Resize event handler then you'll bog down the UI pretty heavily. Common with automatic layout, the visible artifacts are not pretty.
If you really have to then you can simply generate the event yourself. Call OnResizeBegin() before, OnResizeEnd() after you change the window's Client/Size property value. That code needs to live inside the window you resize to get the correct event triggered. Pretty unlikely you should be doing this btw. Do beware that MDI automatically resizes an maximized MDI child window, it of course cannot be maximized anymore when you activate another one. You can't wrap that with OnResizeBegin/End() calls.
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.
In a C# Windows Forms application using Framework 2.X, clicking on a tab control does not send a message to the child controls (such as a lost focus event). Using Microsoft Spy++, I do not see messages sent to my child control. I do get messages when I click back on the tab hosting the control.
Any ideas on what I need to do to have my child control know that its not displayed after the tab was changed. I would like the code to be in the control, not the parent. I am guessing that I am missing out on some event or registration.
Thanks in advance,
Craig
I am guessing that I am missing out on some event or registration.
I don't think you are.
The a lost focus event would be too soon since it happens before the page changes.
The Child Control's VisibleChanged event only fires when the parent TabPage is shown and not when it is hidden which is not what you want.
You can handle either the TabPage.VisibleChanged or the TabControl.SelectedIndexChanged. This of course is from the Parent not the Child, which is also not what you want.
Incidently I believe the TCM_SETCURSEL message is sent to the control on tab change (again not helping with the "not in the Parent requriement"
I have a small Silverlight 4 app that essentially consists of a grid containing a label and a combo box. When I click the label, I replace it with a second text box so that I can edit the label (much the way you can edit the name of a Silverlight control in VS2010).
I have a LostFocus event handler on the text box that will end editing when the control loses focus (restoring the updated label). Trouble is, users tend to click on the panel when they are done editing rather than on another control (or hitting Enter, which is also supported).
I tried adding a left mouse down event handler to the panel. However, that only fires when the text box does not have the focus (I guess the text box captured the mouse?)
Is there an approach to recognize that a non-input control was clicked that would enable me to terminate edit mode?
You can subscribe to Grid's MouseLeftButtonDown routed event using the following code:
panel.AddHandler(UIElement.MouseLeftButtonDownEvent,
new MouseButtonEventHandler(panel_OnMouseLeftButtonDown), true);
Unlike common events routed events are bubbled from innermost control to its parent, then to grandparent etc. In the same way you could subscribe to panel's parent to intercept clicks outside your panel.