My form contains a UserControl, and for now on this I have a MouseDown event handler, which works with a MouseEventArgs. However, I'd like to get an event handler with a MouseButtonEventArgs, so that I can access ClicksCount property to distinguish between simple and double clicking. For now I've some code found on StackOverflow that ways for double click time to be elapsed to know how many times were clicked but this causes redraw being delayed, so it's not user-friendly. Redraw is speedy in itself.
The UserControl displays a background image and small images drawn onto, from user clicks.
So how can I bind an event to an event handler that accepts a MouseButtonEventArgs event? MouseDown, both on UserControl or parent Form, only likes a MouseEventArgs.
I use pure Winforms, not WPF for this project.
Thank you for helping me finding.
So how can I bind an event to an event handler that accepts a MouseButtonEventArgs event? MouseDown, both on UserControl or parent Form, only likes a MouseEventArgs.
You cannot. MouseButtonEventArgs is for WPF. WinForms uses MouseEventArgs.
If you want to catch double clicks, you should handle the DoubleClick event.
For now I've some code found on StackOverflow that ways for double click time to be elapsed to know how many times were clicked but this causes redraw being delayed
This is the only way to know that a click event was a double-click. The only way to tell the difference is to wait the system-specified double-click interval. If a second click happens within that time, it should be interpreted as a double-click. If there is no second click, or it happened outside of that time span, the original click should be interpreted as a single click.
If you don't want the operation to be delayed, you need to react to a single click.
Related
I wonder if D&D events not always firing (DragLeave/DragEnter).
I implemented a D&D feature in my WPF GUI. While dragging some element around I 'dragleave' a GUI element. Normally it fires an appropriate 'DragLeave' event, but not always. I fear, that for some speed reasons sometimes these events get not fired reliable. If that's the case, how can I overcome these issue?
Short Version:
I wrote some sample app to check it myself - and yes - the DragLeave event is not fired reliable.
Long Version:
What I did:
I placed a Label as a draggable object inside a StackPanel. Then I implemented the code for the MouseMove and DragLeave events. An additional TextBlock - added to the StackPanel as well - served as event output. If the DragLeave handler gets called, I changed the Text Property of the TextBlock to 'DragLeave occured'. Afterwards I tested it dragging the Label towards the StackPanel.
What I recognized:
If I was fast enough or pressed the mouse button close to the border of the Label, the DragLeave event was not fired. If I did it slow, everything worked fine as expected.
What I conclude:
I guess, if the mouse leaves the Label before the 'DoDragDrop' thread is initiated, the event is not fired, since the mouse is already outside the Label. So there is a small glitch between starting the D&D and the firing of the first event.
One can see the same behavior in the DragOver/MouseMove handler. The faster you move the mouse, the fewer points (e.GetPosition(...)) you can capture in the event handler.
Problem is, that for the DragLeave that missing event can be critical, since it is only fired once. However, the DragOver event is fired very often during a dragging and a missing event can be balanced by the next DragOver event directly afterwards.
I want to be able in my WPF application to detect the MouseUp event from anywhere. That is to say, if the user clicks in the control and holds his click, then releases it outside the Control, I want my MouseUp event to fire.
I have done the MouseDown event, it works, but the MouseUp event isn't fired if released outside the Window.
Add the CaptureMouse method in your MouseButtonDown handler
You can look up here on what it actually does.
Another way is using the windows API's for mouse_event described here:
Simulating Mouse Clicks
I would use the CaptureMouse listed above first but if that doesn't work for you this one should.
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.
I have a search screen in my WPF application. The screen is implemented as a UserControl in a TabItem of a TabControl. When the user switches to the Search tab, I want the focus to go into one particular field.
So I added a Loaded event handler to the UserControl tag in the Xaml and I called the Focus method of the control I want to have the initial focus in the Loaded event handler. This worked great until I upgraded the Telerik control library I'm using today. Now, when I switch to the Search tab, the focus is NOT in the field I want to have it, but I can't tell what control does have the focus.
The field I want to have focus already has GotFocus & LostFocus event handlers for other reasons. I remembered that in Win Forms, the LostFocus event handler arguments tell you which control is going to get the focus. So I put a breakpoint in my LostFocus handler & discovered that the arguments to the LostFocus event handler in WPF don't include that information.
How can I figure out where the focus is going without putting GotFocus handlers on every control in my UserControl?
Tony
You can try putting your breakpoint on the LostKeyboardFocus Attached Event instead of the LostFocus Event. It uses the KeyboardFocusChangedEventArgs Class which does have properties that show which element had focus and where the focus is going.
private void textBox1_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
textBox1.Text = ((FrameworkElement)e.NewFocus).Name ;
}
Try to press Tab Key and see if it helps you find the control in focus.
You can also use Snoop as suggested in this Q/A: Any tips on debugging focus issues in WPF?
For starters, Snoop shows the current focused element and the current
FocusScope in the status bar.
You can get it to show you all the GotFocus and LostFocus events:
1. Run your app.
2. Run Snoop.
3. Choose your app in the dropdown.
4. Click the binoculars ("Snoop") button.
5. On the right pane, click the Events tab.
6. Click to bring down the dropdown.
7. Scroll down to the Keyboard section and check GotKeyboardFocus, LostKeyboardFocus, and optionally the PreviewXXX events.
8. Now do what you need to do to manipulate focus and watch the Snoop window.
Similarly you can track the FocusManager events the same way.
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.