WPF TouchUp not firing when parent manipulation is enabled - wpf

I have a Canvas, with one child control. The child controls receives all PreviewTouchDown and PreviewTouchUp events fine - but after enabling Manipulation (IsManipulationEnabled = true) on the Canvas, only the "down" events get fired on child object, but the TouchUp and PreviewTouchUp events doesn't fire at all..
Any ideas what's going on here?

You need to set IsManipulationEnabled to true on the child element, too.
The relationship between touch and manipulation events is explained in Input Overview / Touch and Manipulation, section The Relationship Between Touch and Manipulation Events:
A UIElement can always receive touch events. When the
IsManipulationEnabled property is set to true, a UIElement can receive
both touch and manipulation events. If the TouchDown event is not
handled (that is, the Handled property is false), the manipulation
logic captures the touch to the element and generates the manipulation
events. If the Handled property is set to true in the TouchDown event,
the manipulation logic does not generate manipulation events. The
following illustration shows the relationship between touch events and
manipulation events.
Touch and manipulation events

I know its a year old, but this might help someone:
For a workaround, you can capture "Stylus tap" events just fine if the parent element has IsManipulationEnabled = true
....
MyChildElement.StylusSystemGesture += MyChildElement_StylusSystemGesture;
....
void MyChildElement_StylusSystemGesture(object sender, StylusSystemGestureEventArgs e)
{
if (e.SystemGesture == SystemGesture.Tap)
//Do something
}

Related

Strategy for differentiating TouchUp from TouchLeave, and TouchDown from TouchEnter?

For the basic scenario described in the msdn overview (under Touch and Manipulation) TouchEnter and TouchLeave are fired for every corresponding TouchDown and TouchUp respectively. Unlike the mouse, the Touch and Stylus are not constrained to maintain contact with the screen.
Is there a way to use TouchEnter and TouchLeave is to capture only when a finger is dragged into the UIElement. As these events are fired for every touchUp and touchDown, what is the best way to differentiate these events?
One strategy that would work for the single finger case, is to have a flag set on TouchDown, and check if the flag is set on TouchUp. This allows some condition checks on TouchUp. However, for multiple fingers, it isn't feasible.
There are no PreviewTouchEnter and PreviewTouchLeave events fired, only PreviewTouchDown and PreviewTouchUp. The sequence of events for a finger lowered on to a UIElement and then raised over it is as follows:
TouchEnter
PreviewTouchDown
TouchDown
PreviewTouchUp
TouchUp
TouchLeave
This sequence doesn't help differentiate a TouchEnter that has happened due to a finger dragged across the screen into the UIElement, from a finger that is lowered onto the UIElement directly. Am I missing something, or does the framework not support such differentiation itself?
Can you use the TouchDevice Class to keep track of where touches are generated. New touches are given a new ID, so you could distinguish between existing touches and new ones, and which elements are capturing the device. I guess that circumvents the Manipulation events and the normal processes, but I hope that helps.
If you retrieve a TouchPoint for the event, there is a property on it named Action which tells you whether it is a Down, a Move or a Up event.
void m_element_TouchEnter(object sender, System.Windows.Input.TouchEventArgs e)
{
var touchPoint = e.GetTouchPoint(m_someElement);
if (touchPoint.Action == System.Windows.Input.TouchAction.Move)
{
//This is a "true" TouchEnter event
}
else if (touchPoint.Action == System.Windows.Input.TouchAction.Down)
{
//This is a "true" TouchDown event.
}
}

Event to know if Panel lost focus in Winforms application?

I have a simple Form with 4 panels in it. Each of those panels are docked in the parent, to ensure only one is visible at a given time. Now, for Panel2, when it is moving from front to back, I would like to work on that event. I am making panels visible by calling panel.BringToFront()
I have tried Leave event but that doesn't work. For Form, the event is Deactivate, what's the event for Panel?
I'm thinking LostFocus is what you're looking for.
Edit
As another strategy, you know that calling panel.BringToFront will queue an update in your UI. Wherever you are calling panel.BringToFront, perhaps you could just call one of your own methods, or trigger one of your own events. This way, you know when the event will be triggered, and exactly what will trigger it.
The reason I thought of this is that I doubt your Panel will ever actually have the focus itself - rather, one of its child controls will likely have the focus. By doing you own event trigger, you don't have to rely on something as volatile as focus. Plus, even if the Panel did have the focus, it's always possible that it could lose focus in other ways than your own panel switching.
Edit #2
Here's an attempt at a quick implementation of my previous ramblings. I'll be making the assumption that this code be placed somewhere in the same class as all your Panel instances (i.e. in your Form class).
// This will be the custom event to which you can subscribe
// in order to detect a switch in panels.
public event EventHandler PanelSwapEvent;
// This reference the currently visible panel - should be set
// to the default panel in the form's constructor, if possible.
private Panel currentPanel;
// This actually switches the panels, to minimize code duplication.
private void switchToPanel(Panel p)
{
Panel lastPanel = currentPanel;
currentPanel = p;
// Move the panels, and invoke the event.
p.BringToFront();
if(PanelSwapEvent != null)
PanelSwapEvent(lastPanel, new EventArgs());
}
// Here's the actual event handler (replaces your
// pnlServiceInfo_LostFocus handler).
private void PanelSwapHandler(object sender, EventArgs e)
{
// whatever you want to do when panels are swapped
}
In this example, the sender of the event handler is the panel that lost "focus". Using it is as simple as saying switchToPanel(pnl_whatever) to indicate that you would like to switch from the current panel to the panel named pnl_whatever.

How to distinguish between Sender and Source in WPF routed events

I would like to have a clear explanation about how to determine in each situation which control is the sender and which one is the source for a WPF Routed Event event both in the case of tunnelling and bubbling events.
Edit:
Suppose you have an event handler and two controls one child of the other. The handler is in the parent control. How would I know beforehand and without debugging which control is passed as the sender and which one as the e.source? And does this change when you consider bubbling or tunnelling events?The general concept of events is clear to me, but I would like to understand which parameter to use in the eventhandler to indentify both controls without debugging
There probably isn't an exhaustive "clear explanation", because there are so many ways you could end up with events. Especially when a lot of events use EventArgs.Empty, because there are no other details, other than the source.
http://msdn.microsoft.com/en-us/library/17sde2xt(v=VS.100).aspx
or, more specificly:
RoutedEvent: Source vs. OriginalSource
Do you have a specific question you need answered?
Edit: from the above linked article, with an answer similar to your comment
Consider a custom control (called CustomControl1 in this example) that is composed of a TextBlock.
When a MouseDown event is raised on the TextBlock, the OriginalSource property will be the
TextBlock, but in CustomControl1's handler, the Source will be changed to the CustomControl1
object so that other elements along the event's route will know that CustomControl1 received a
MouseDown.

No ManipulationCompleted event in Surface Toolkit for Windows Touch Beta

I am using Surface Toolkit for Windows Touch Beta. I have a UserControl within a ScatterViewItem on a ScatterView. I want to receive ManipulationCompleted event on a UserControl but it doesn't seem to ever be raised even though IsManipulationEnabled="True" is also set. The same thing works perfectly in a non-Surface WPF4 app.
It appears various Touch WPF events play well with Surface but it seems like a lot of work to recreate a tap event and NSWE events that I can easily interpret from ManipulationCompleted event.
I am looking on ways to either receive ManipulationCompleted event on my UserControl or to simulate it by handling existing touch events.
Any pointers?
does the scatterviewitem move when your usercontrol is touched? only one element at a time can be tracking manipulations for a given touch. if the scatterviewitem is getting the manipulation events, that means your user control will not.
if you only want your usercontrol to handle the input, then have it listen to TouchDown and call usercontrol.Capture(touch). if you want to have the SVI do it's thing but also handled the completed event on your own, then you will have to register your event handler manually: usercontrol.AddHandler( ManipulationCompletedEvent, yourHandler, true). the last parameter says you want to handle the event even if SVI already has.

Events routing in WPF

I have implemented a UserControl. Then I would like to handle an event that is originally handled by Window (keyboard press). What is the best way to route the event caught by another component (higher in the components' tree)?
Thanks in advance for the replies and hints!
Cheers
It depends on the event you're trying to access. If it's a Preview event and the Window is setting e.Handled to true you'll need to use the method Alex suggests to circumvent the Window's handling of the tunneling. If it is a bubbling event (i.e. KeyDown) you don't need to do anything special since bubbling events hit the handlers on child elements first and go up the visual tree so the Window handler won't occur until after your UC's.
One thing you need to be careful with using Key events is that the event is only going to get picked up by your UC in the first place if the Focus is on or inside of it. This isn't something you need to worry about with things like Mouse events since they start at a specific location in the tree.
I believe you cannot gurantee that.
Window class is wrapping Win32 message-based event model and this will be the only WPF entity which will have access to those information.
I suggest that you create an attached property (which will be used by the Window) and implement the routing of the events yourself so that controls could subscribe to.
You can attach the routed handler specifying that you want to handle handled messages as well:
this.AddHandler(routedEvent, handler, true);
where this is an UIElement or derived class.
However there may still be events (key presses in this case) which don't make it past the window, not sure.

Resources