Reputation: 70
What I'm looking for is like the Mail application installed on Windows 8.1. You start dragging and at any time, you can press the Escape key to cancel the drag.
I tried two things, but they failed:
My hypothesis at the moment is the Mail app is built around HTML5/JS and it has features that XAML app cannot have... I hope I'm wrong.
Thanks ArchieCoder
Upvotes: 1
Views: 141
Reputation: 31831
I think it is worth discussing why retaining a reference to a cancel event argument is not the solution because of how cancel events are programmed. This will be worthwhile for everyone a little later. So, let's pretend we were going to fire a rocket into space. The Fire() method itself might look like this.
void Fire()
{
Rocket.Fire();
}
But because we will people to react to it after it was completed we might creat an AfterFire
event to let people know it is completed. It would might look like this.
event EventHandler AfterFire;
void Fire()
{
Rocket.Fire();
AfterFire(this, EventArgs.Empty);
}
In all reality you would need some error handling to make this right.
But because we want people to interrogate if the rocket launch is safe prior to the actual fire action, we include a BeforeFire
event to let people know it is imminent. But in case the rocket is not safe, we want to include the ability to cancel. Like this.
class BeforeFireEventArgs: EventArgs { public bool Cancel { get; set; }}
event EventHandler<BeforeFireEventArgs> BeforeFire;
event EventHandler AfterFire;
void Fire()
{
var args = new BeforeFireEventArgs();
BeforeFire(this, args);
if (args.Cancel)
return;
Rocket.Fire();
AfterFire(this, EventArgs.Empty);
}
The thing to notice here is that the BeforeFireEventArgs
are created in this method, passed to the event by this method, and interrogated after the event is returned to this method. If you were to handle the BeforeFire
event you could set Cancel
to true and it would not fire.
The WinRT GetDeferral() pattern exists to handle this scenario
If, however, you were to handle the BeforeFire
event, not set Cancel
to true but retain a reference to the BeforeFireEventArgs
for later, the handler would release the event and the Cancel
would either prevent or allow the rocket to fire.
Then, a minute later if you use that same reference of the BeforeFireEventArgs
and set Cancel
to true! The timing is all too late. Far too late. The event was already raised. It was already handled. And Cancel
was already interrogated.
Make sense?
Upvotes: 0
Reputation: 31831
Ah, sure. You can do this. Here's how.
public sealed partial class MainPage : Page
{
Pointer _Pointer = default(Pointer);
public MainPage()
{
this.InitializeComponent();
this.Dispatcher.AcceleratorKeyActivated += (s, e) =>
{
if (e.EventType == (CoreAcceleratorKeyEventType.SystemKeyDown & CoreAcceleratorKeyEventType.KeyDown)
&& e.VirtualKey == VirtualKey.Escape)
{ MyListView.ReleasePointerCapture(_Pointer); }
};
this.PointerMoved += (s, e) =>
{ _Pointer = e.Pointer; };
}
}
Also, the ListView
is named MyListView.
Best of luck!
Upvotes: 2
Reputation: 31724
I haven't used that drag & drop API too much, so the only things I can see is the ones you tried. I did recently discover though (thanks to Tim Heuer's mention somewhere) this sample on advanced input concepts that might be helpful. I think it describes an API new to 8.1 that allows you to handle manipulation events inside of a ScrollViewer
(when you combine System
and TranslateX/Y
ManipulationModes
) and cancel scrolling them you don't want to scroll anymore (e.g. when you start dragging). That could let you implement your own, customized version of drag&drop with any features you need.
Upvotes: 0