Changing Tabs in a Tab Control does not send Child a Message - winforms

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"

Related

Capture all Click or Touch events recursively in 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.

Disabling content behind an in-page dialog in WPF

I have some simple code for popping up a "dialog"-like thing over part of my application window. The idea is, the user must dismiss the dialog before continuing to work with that part of the page.
This works by hovering a large semi-transparent rectangle over the part of the page that is supposed to be disabled - which does a nice enough job of blocking clicks to the region. You see this sort of thing a lot in WPF and Web apps, I think.
The problem I have is, the user can still reach all those juicy blocked controls by tabbing to them using the keyboard. "No problem", I hear you say, "just set the IsEnabled on the panel to false, thereby blocking keyboard access".
Unfortunately, disabling the controls:
Doesn't look very nice
Tends to have unintended consequences with custom styles and bindings further down the tree
So, is there a better way to disable a part of the page, without setting the "IsEnabled" property, such that it doesn't change the visual appearance of any of the controls?
Thanks,
Mark
Can you put your "dialog" XAML in a popup window? Then, call ShowDialog() on the window to make it a modal window? If you don't want your popup to look like a standard window, you could always syle it to remove borders, etc.
I solved this by subscribing to the PreviewGotKeyboardFocus event, from the parent element in the tree, and then handling the event such that focus never gets passed to the children.
Also, I had to explicitly remove focus from the "disabled" controls as well, of course.

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.

Silverlight: Modal ChildWindow keeps parent grayed after closing

When my modal ChildWindow closes, the parent control does not get "un-grayed" and all user input is blocked, forcing me to restart the application. Exact scenario which causes this behavior consistently:
ChildWindow A pops up and user clicks a custom button on the bottom of the window (instead of OK or Cancel). My code does some work and then calls the Close() method for the ChildWindow.
ChildWindow A closes and functionality is restored to parent control (controls are un-grayed).
User causes ChildWindow B to pop up. User clicks system-generated OK or Cancel button.
ChildWindow B closes, but the parent controls are still grayed out and inaccessible.
Either of the windows work fine repeatedly on their own. Any thoughts?
I saw something similar (it might not fix your exact problem) and found some discussion about the ChildWindow here
they suggested this method in the ChildWindow Closed event and it worked for me.
Application.Current.RootVisual.SetValue(Control.IsEnabledProperty, true);
Also try calling this.DialogResult = true instead of the Close method.

Hiding Popup control when other window's in focus

I have a custom UserControl which tries to recreate auto-complete for a textbox. When user types, the text is used to filter a provided collection of items and then a Popup displays a ListBox with items that match what user have typed.
Unfortunately, if user decides to switch away from the application to another window (browser, MSWord, anything!), the Popup remains on top of every other window!
Also, if I move my window (which hosts the custom control) with the popup open, the popup stays in place (and doesn't follow the window)! It's kinda funny but obviously not acceptable behaviour. I've looked around but only found one post about this that went unanswered for two years :(
Actually, I didn't realize that I had StaysOpen property of the Popup set to true.
<Popup StaysOpen="False" />
actually does the trick for me.
I had the same problem in a similar scenario. What I did was I subscribed to all posible "lost focus" events of the control and also got the window which hosts the control and subscribed to its GotMouseCapture and LocationChanged events. Event handlers of all those events are setting the popup's IsOpen property to false.
You can get the hosting window with this:
parentWindow = Window.GetWindow(this);
all other code is simply a lot of subscribing to events to do the same thing.
P.S. I'm not saying it's a pretty or optimal solution, but it works fine for me :)
According to the Popup documentation:
When Popup is displayed on the screen, it does not reposition itself if its parent is repositioned.
So it does not look like it would be a very good candidate for an autocomplete textbox. I think the class is meant more for showing information when you hover over an item.

Resources