-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
DragGestureRecognizer.cs
139 lines (113 loc) · 5.21 KB
/
DragGestureRecognizer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System;
using System.Windows.Input;
using Microsoft.Maui.Graphics;
namespace Microsoft.Maui.Controls
{
/// <summary>
/// Provides drag gesture recognition and defines the associated events for dragging and dropping.
/// </summary>
/// <seealso href="https://learn.microsoft.com/dotnet/maui/fundamentals/gestures/drag-and-drop">Conceptual documentation on recognizing a drag and drop gesture</seealso>
public class DragGestureRecognizer : GestureRecognizer
{
/// <summary>Bindable property for <see cref="CanDrag"/>.</summary>
public static readonly BindableProperty CanDragProperty = BindableProperty.Create(nameof(CanDrag), typeof(bool), typeof(DragGestureRecognizer), true);
/// <summary>Bindable property for <see cref="DropCompletedCommand"/>.</summary>
public static readonly BindableProperty DropCompletedCommandProperty = BindableProperty.Create(nameof(DropCompletedCommand), typeof(ICommand), typeof(DragGestureRecognizer), null);
/// <summary>Bindable property for <see cref="DropCompletedCommandParameter"/>.</summary>
public static readonly BindableProperty DropCompletedCommandParameterProperty = BindableProperty.Create(nameof(DropCompletedCommandParameter), typeof(object), typeof(DragGestureRecognizer), null);
/// <summary>Bindable property for <see cref="DragStartingCommand"/>.</summary>
public static readonly BindableProperty DragStartingCommandProperty = BindableProperty.Create(nameof(DragStartingCommand), typeof(ICommand), typeof(DragGestureRecognizer), null);
/// <summary>Bindable property for <see cref="DragStartingCommandParameter"/>.</summary>
public static readonly BindableProperty DragStartingCommandParameterProperty = BindableProperty.Create(nameof(DragStartingCommandParameter), typeof(object), typeof(DragGestureRecognizer), null);
bool _isDragActive;
/// <summary>
/// Initializes a new instance of the <see cref="DragGestureRecognizer"/> class.
/// </summary>
public DragGestureRecognizer()
{
}
/// <summary>
/// Occurs when a drop gesture is completed.
/// </summary>
public event EventHandler<DropCompletedEventArgs>? DropCompleted;
/// <summary>
/// Occurs when a drag gesture is detected.
/// </summary>
public event EventHandler<DragStartingEventArgs>? DragStarting;
/// <summary>
/// Gets or sets the value which indicates whether the element the gesture recognizer is attached to can be a drag source.
/// </summary>
/// <remarks>Default value is <see langword="true"/>.</remarks>
public bool CanDrag
{
get { return (bool)GetValue(CanDragProperty); }
set { SetValue(CanDragProperty, value); }
}
/// <summary>
/// Gets or sets the command to be executed when a drop gesture is completed.
/// </summary>
public ICommand DropCompletedCommand
{
get { return (ICommand)GetValue(DropCompletedCommandProperty); }
set { SetValue(DropCompletedCommandProperty, value); }
}
/// <summary>
/// Gets or sets the parameter that's to be passed to the <see cref="DropCompletedCommand"/>.
/// </summary>
public object DropCompletedCommandParameter
{
get { return (object)GetValue(DropCompletedCommandParameterProperty); }
set { SetValue(DropCompletedCommandParameterProperty, value); }
}
/// <summary>
/// Gets or sets the command to be executed when a drag gesture is first recognized.
/// </summary>
public ICommand DragStartingCommand
{
get { return (ICommand)GetValue(DragStartingCommandProperty); }
set { SetValue(DragStartingCommandProperty, value); }
}
/// <summary>
/// Gets or sets the parameter that's to be passed to the <see cref="DragStartingCommand"/>.
/// </summary>
public object DragStartingCommandParameter
{
get { return (object)GetValue(DragStartingCommandParameterProperty); }
set { SetValue(DragStartingCommandParameterProperty, value); }
}
internal void SendDropCompleted(DropCompletedEventArgs args)
{
if (!_isDragActive)
{
// this is mainly relevant for Android
// Android fires an Ended action on every single view that has a drop handler
// but we only need one of those DropCompleted actions to make it through
return;
}
_isDragActive = false;
_ = args ?? throw new ArgumentNullException(nameof(args));
DropCompletedCommand?.Execute(DropCompletedCommandParameter);
DropCompleted?.Invoke(this, args);
}
internal DragStartingEventArgs SendDragStarting(View element, Func<IElement?, Point?>? getPosition = null, PlatformDragStartingEventArgs? platformArgs = null)
{
var args = new DragStartingEventArgs(getPosition, platformArgs);
DragStartingCommand?.Execute(DragStartingCommandParameter);
DragStarting?.Invoke(this, args);
#pragma warning disable CS0618 // Type or member is obsolete
if (!args.Handled)
args.Data.PropertiesInternal.Add("DragSource", element);
#pragma warning restore CS0618 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
if (args.Cancel || args.Handled)
return args;
#pragma warning restore CS0618 // Type or member is obsolete
_isDragActive = true;
if (args.Data.Image == null && element is IImageElement ie)
args.Data.Image = ie.Source;
if (String.IsNullOrWhiteSpace(args.Data.Text))
args.Data.Text = element?.GetStringValue();
return args;
}
}
}