To reproduce this bug you need to create custom ToolStripItem, using ToolStripControlHost.
In my case, I made ToolStripDateTimePicker control (as seen on many good tutorials). The control however behaves slightly different than a regular DateTimePicker.
Regular one produces default Windows bell sound when ESC is pressed while it's active. The ToolStrip hosted control reacts for ESC pressed in a more sensible manner. The control becomes inactive, no beep.
Here's the bug part: when focusing another control with a click - regular DateTimePicker triggers Leave event. As expected. ToolStrip hosted control DOES NOT trigger any event!
Yes, I've tried KeyDown event - it's not sent when ESC key is pressed, but sent when any other key is pressed.
I believe it's a bug in .NET itself.
The consequence of this is broken focus behavior of the form containing the ToolStrip control. The form cannot be focused again after entering ToolStrip hosted control.
But it's a workaround for this: you can focus an other form (or even maybe another control), and then the target form - it works for me.
However I would like to have it done automatically - the moment user exits the hosted control. The problem is I don't have an event for this. Any ideas?
What's weird, Leave event is eventually triggered when the hosted control is disposed - it's clearly a bug, because the event is totally useless there.
Here: sample application illustrating the problem
I've replaced it with sample workaround, to see the problem comment out OnGotFocus() and OnLostFocus() overrides.
It worked nice (and could not reproduce the bug) until I've changed FlowLayoutPanel TabIndex to 0, so the DateTimePicker is not active when the application starts.
Here's what I learned:
The problem was not exactly with
ToolStripControlHostclass, but with theDateTimePickercontrol itself, and to be more specific - with it's interaction withFlowLayoutPanels and possibly other similar controls. And I'm not sure if it's a bug or expected behavior, but seems more like a bug.Here's how it works: If there is another control which can be obviously activated (like
TextBox), leaving theDatePickerControlmeans activating the other control. But if the other control is empty container, or container with no controls which can be activated -Leaveevent is not triggered despite theDateTimePickercontrol is not active anymore.Why would you want to have a container with no active controls active itself? I use
FlowLayoutPanelto produce a read-only, non-editable report. It is not editable, but I want it scrollable, and I don't wantDateTimePickercontrol to steal focus fromFlowLayoutPanel- so in this caseFlowLayoutPanelis an active control.Of course it doesn't work this way. There are more workarounds needed for such behavior to be achieved, like receiving mouse events from containing form, but correct
Focus/Leavebehavior forToolStripDatePickerControlis a good start.So without further ado, my perfect
ToolsStripDateTimePickercontrol, with focus glitch fixed:DesignerToolStripControlHostclass:ToolStripDateTimePickerclass:Workarounds explained:
OnGotFocus()andOnLostFocus()event handlers are overridden to trigger my new controlEnterandLeaveevents. Note that they are triggered almost correctly.EnterandLeaveevents. We don't want those, so I check the time between events, if it's smaller than 10ms I just ignore later event.DesignerToolStripControlHostis used to fix broken designer behavior. If you usedToolStripControlHostdirectly, you would get an exception trying to show the control's designer view, because designer tries to instantiate this class with no argument, and this class does not have a constructor with no argument. So my new class does.ToolStripDateTimePickerbreak which you can tell by seeing DTP disappeared, just close designer view and open it again. It will work fine until you compile or debug your application again.Glitch fix was tested with 1ms time window and worked fine. So I chose 10ms to ensure it works on slower or more loaded machines, but it's still short enough to capture any event from user interaction.