I have a rectangle which should trigger an event on TouchEnter.
But when I Touch the rectangle nothing happens until the longtouch is over. It looks like it is waiting to be sure there is no longtouch before the TouchEnter kicks in.
If I touch the rectangle and move slightly (so there can't be a LongTouch anymore) it triggers the event.
How can I get rid of this:
"I better wait for the longTouch to be finished until I trigger the touchEnter" ?
The same happens with the TouchDown event...
Set as high as possible in the visual tree the attached properties Stylus.IsPressAndHoldEnabled and Stylus.IsFlicksEnabled to false in xaml or in code.
These will disable most of the delay experienced when doing a touch enter and down due to the touch needing the delay to figure out what the user wants to do.
It happened only on my Touch-Monitor.
Using a Tablet it worked fine.
So I think it depends on the Hardware.
Related
From a production application, we notice that our WPF buttons fire the ICommand.Execute method twice on fast double click.
Now, on every Command, the application is covered with a full-screen spinner animation, preventing any further interaction with the application.
This github repo contains a minimalistic repro of the issue. Note that:
when the Button's Command fires, the "IsBusy" flag is set to true
as a consequence, the BusyIndicator overlay will be shown
as a consequence, the Button cannot be pressed again until after 300ms
However, especially on slow computers, when fast double-clicking (really fast, like gaming fast that is), it is possible to fire the command twice without the BusyIndicator blocking the second call (this can be seen if the output shows 2 'click' lines right after one another).
This is unexpected behavior to me, as the IsBusy flag is set to true right away on the UI thread.
How come a second click is able to pass through?
I would expect the IsBusy Binding to show the overlay on the UI thread, blocking any further interaction?
The github sample also contains 2 workarounds:
using the ICommand.CanExecute to block the Execute handler
using the PreviewMouseDown to prevent double clicks
I'm trying to understand what the issue is.
What work-around would you prefer?
Diagnosis
This is only my guess and not a solid and confirmed info, but it seems that when you click the mouse button, the hit-testing is done immediately, but all the mouse related events are only scheduled to be raised (using the Dispatcher I presume). The important thing is that the control that is clicked is determined at the time the click occurred, and not after the previous click has been completely handled (including all UI changes that potentially follow).
So in your case, even if the first click results in showing the BusyIndicator covering (and thus blocking) the Button, if you manage to click for the second time before the BusyIndicator is actually shown (and that does not happen immediately), the click event on the Button will be scheduled to be raised (which will happen after the BusyIndicator is shown), causing the command to be executed again even though at that point the BusyIndicator will possibly be blocking the Button.
Solution
If your goal is to prevent command execution while the previous one is still executing the obvious choice is to make the Command.CanExecute result depend on the state of the IsBusy flag. Moreover, I wouldn't even call it a workaround, but a proper design.
What you're facing here is a clear-cut example of why you shouldn't make your business logic rely on UI. Firstly, because rendering strongly depends on the machine's processing power, and secondly because covering a button with another control by far does not guarantee the button cannot be "clicked" (using for example UI Automation framework).
doing a show() does not let gui update until resize window.
I have a window that I hide for a while,(has to be over 30 min. or maybe after screensaver kicks in) then when I try to do a show and the gui pops up but it does not update.
I am making correct updates to the gui, but they aren't seen until i physically resize the window. I'm thinking somehow the gui doesn't focus anymore. If I don't let it sit idle for a long time it never has a problem. Is there something I can do to force it to gain focus when I do the show()? thank you very much
To answer your question directly: You can also do a Focus() to make the window focus (in theory anyway).
But I don't think this is your problem. Have you been able to reproduce this behavior on multiple computers?
I am working on the touch screen application which is running on Windows XP Standard. With current hardware to invoke a right click user has to click and hold for couple of seconds, but this might interfere with other actions like holding a repeat button in the scrollviewer, so I have decide to disable a right click.
I would ideally wan't to disable a right click on the application level, but if it is not possible, disable right click on windows level would also work for me.
The OnPreviewMouseRightButtonDown/Up approach did not work for me.
There is a property Stylus.IsPressAndHoldEnabled on UIElement however. Set that to false to get rid of the press and hold right click behavior. I tested this on Windows 7 with .NET 4.0, but the property is available from .NET 3.0.
<RepeatButton Stylus.IsPressAndHoldEnabled="false" ... />
There is also a blogpost here that provides a code sample for a similar disabling of press and hold at window level. But with this in place, the PreviewTouchDown and TouchDown events will not be raised as soon as the finger touches the screen (which would be necessary for a RepeatButton I guess), only later. Read the 'Remarks' on this msdn page.
You can override the OnPreviewMouseRightButtonDown on the Window and set Handled to true. You also need to handle OnPreviewMouseRightButtonUp (thanks to Vitalij for pointing this out)
That should do the trick.
I'm improving standart WPF TabControl. I want to add undocking functionality to it:
user drags the page just outside the TabControl and this page undocks in the window.
I want two events in this control - PageDragStart (raises when the page dragged outside) and PageDragEnd (raises when the page dropped outside)
I've got no problem with the first event.
But the second... OnDrop doesn't call, because the item dropped outside the tabcontol container. How can I know that it was dropped?
P.S. I want a universal control (so, undocking functionality shouldn't be connected and hardcoded with the window tabcontrol is placed or something like this)
Why use DoDragDrop at all? As I was reading your description, using Mouse.Capture by itself seemed the obvious solution:
Handle OnMouseLeftButtonDown on the tab and start capture
Handle OnMouseMove on the tab and update the cursor based on hit testing
Handle OnMouseLeftButtonUp on the tab, and stop the capture and make the appropriate change
The reasons you might ever consider DoDragDrop over simple mouse capture are:
Integration with Windows' OLE drag and drop so you can drag and drop between applications and technologies
Modal nature of DoDragDrop call (which actually seems to be more of a disadvantage to me)
Automated hit testing of targets
Standardized "drop operation" API to allow unrelated applications to handle copy vs move, etc.
You apparently don't need the OLE integration or multi-application support and you want to customize the hit testing, so it seems that DoDragDrop has no advantages over directly handling the mouse capture.
I solved the problem - in rather brutal and unsafe way. But for it's gonna work as the temporary solution.
Well, when I'm raising PageDragStart event, I call Mouse.Capture(this, CaptureMode.SubTree);
When the page is dropped somewhere - DoDragDrop throws different exceptions (COMException, NullReference (I couldn't find which object is null) and some others I don't remember).
I catch exception and call PageDragEnd event (if the property IsPageDraggingOut set to true).
As far as you can see this solution is really dirty and bad. But it works.
So, any other ideas (or some ideas how to work with Mouse.Capture properly)?
We have a 3rd party control loaded in our C# WinForms app.
When we call a method on this 3rd party ActiveX control, it asynchronously steals focus. For example:
// This call causes 3rd party to spawn a thread and steal focus
// milliseconds later.
foo3rdParty.DoSomething();
Is there a way to prevent a control from stealing focus?
If the control has a GotFocus() event (and it's correctly raised by the control whenever it steals the focus), you could attach a handler to that and set the focus back to the last control that had the focus (or the OK button or whatever).
This might produce weirdness if someone is typing in a textbox in the middle of this. My solution would be to give my money to someone who was willing to do maybe 15 minutes of work to help me.
If this evil little control isn't meant to be visible, you could place it on an invisible form and call DoSomething() on it there. Then, who cares if it grabs the focus?
ugh. you've probably already thought of this but can you disable the control's window during the period (or a guesstimation) when it tries to take focus, without hurting the user experience?
You could try this rough approach:
Find which control has focus before you make the call, say using Form.ActiveControl.
Attach a handler to the active control which gets called when it loses focus.
Make the call to the third-party control's method.
If all goes as expected, the third-party control will gain focus, and the previously focused control will lose focus, and the handler will be called.
In that handler, either set focus back to the previous control, or schedule some code to run on a thread to do so a little later.