The included gestures doesn't provide enough information

Editor
Sep 22, 2010 at 10:48 AM
Edited Sep 22, 2010 at 10:49 AM

The gesture triggers included in Blake.NUI.WPF has events that allows code behind to react to these gestures. The problem is that in reality, when trying to respond to these events they contain way to little information in order to be useful.

For reference, I'm trying to start a drag and drop operation when an element receives a hold gesture, and the following issues hit me immediately:

  • The sender parameter is the actual trigger object. This totally makes sense since it's that object that raises the event, but what you are really interested in is the framework element that's involved in the gesture. Now, the only way to get it is to explicitly cast the sender to IAttachedObject and get the AssociatedObject property.
  • The event args are of the dummy type EventArgs lacks relevant information about the background of the event (where it came from, what touch devices were involved, etc)

It would be nice if it was possible to do gesture recognition and have them raise routed events on the actual UIElement. This would solve all my problems actually and it would hopefully also allow events to be declared in xaml like <Grid blake:HoldGesture="myEventHandler">
I'm not sure if this is possible to do outside the scope of the input manager though..

Another approach would be to use a custom EventArgs derived class that holds the relevant information. Not as elegant perhaps, but it would make the events usable at least.

Coordinator
Sep 22, 2010 at 4:40 PM

Hi isaks,

Thanks for the good feedback on how you want to use the gesture triggers. I had considered using attach properties like you suggest but that doesn't expose as much customization as using triggers. Triggers also let the traditional C# developer work normally but also allow composition of Blend SDK Actions for those that use them. Technically we could expose both but I think that would cause too much confusion.

We can change the sender of the event to be the associated object. That makes more sense. Is there any other information that you'd find useful in the EventArgs? Anything about the start or duration of the gesture?

On your hold gesture patch -- TagGestureTrigger already has a hold feature. The customizable properties are:

HandlesTouches
MaxMovement
MaxMilliseconds
MinMilliseconds
Mode = Long or Regular

When you set Mode="Long", such as this:

<i:Interaction.Triggers>
    <gesture:TapGestureTrigger Tap="grid_Tapped" Mode="Long"/>
</i:Interaction.Triggers>

Then it configures the min and max milliseconds to only respond to a long tap, or a hold.

You can actually submit patches on the Source Code tab if you click upload patch, and can associate it with a work item.

I know I need more documentation on these features so I'm sorry that you went through the trouble of creating a HoldGesture* when the functionality was already there.

 

Editor
Sep 22, 2010 at 7:12 PM

No worries.. it wasn't much effort creating the triggers - most of the code was copy-paste from your existing triggers. And I also got an opportunity to look at how these triggers work under the hood :-)

Just to avoid confusion, is the tap gesture in long mode raising the event while the contact is still pressed? Cause that's what I needed - hold down an element for a while to start a drag and drop operation without releasing the contact.

and I'm also thinking that maybe the it should be named hold anyway. I managed to miss this even though I saw that there was "long" feature and I'm sure others will as well

 

Coordinator
Sep 22, 2010 at 7:18 PM

Hm, no it waits until the touch is released.

So would you prefer a single TapGestureTrigger that is configurable to cover different scenarios (short tap, long tap, hold) or separate triggers for each configuration (even if they use the same engine)?

Editor
Sep 22, 2010 at 7:25 PM

The naming convention I'm used to is

  • Tap: a short click - press then quickly release
  • Click: press then release after a slightly (technically indefinite) delay
  • Hold: Press and hold until event is raised

I don't have a strong opinion on whether tap/click (short vs long tap) should be separated since they are pretty much the same gesture but with different time so anyway you like is fine with me. I do, however, think that Hold deserves it's own trigger to promote discoverability a familiarity with other touch APIs (like the Surface SDK)

Coordinator
Sep 22, 2010 at 7:41 PM

Makes sense. Can you upload the patch through the source code tab? I haven't had a chance to see how that one works out. I'll take a look and incorporate it.

Editor
Sep 22, 2010 at 7:54 PM
Edited Sep 22, 2010 at 7:56 PM

Done. i also linked it to the original work item

Editor
Sep 22, 2010 at 8:05 PM
joshb wrote:

Hi isaks,

Thanks for the good feedback on how you want to use the gesture triggers. I had considered using attach properties like you suggest but that doesn't expose as much customization as using triggers. Triggers also let the traditional C# developer work normally but also allow composition of Blend SDK Actions for those that use them. Technically we could expose both but I think that would cause too much confusion.

We can change the sender of the event to be the associated object. That makes more sense. Is there any other information that you'd find useful in the EventArgs? Anything about the start or duration of the gesture?

The benefit of having it as attached events is that it would be consistent with how other events works. To me, there's no fundamental difference between a "tap" or "hold compared with, say "mouse down" or "click". But to be honest, I have never used Blend actions so perhaps I'm missing some obvious benefit with the triggers?

Could we do both? Have this exposed as both normal routed events as well as triggers?

I don't think that 'sender' should be the associated object. Events raised by a class always has the instance raising the event as sender and it would be confusing to change that convention. I'd rather see the associated object exposed in the event args somehow (or, if it can be done with routed events, this wouldn't be an issue)