diff --git a/src/Compatibility/Core/src/iOS/DragAndDropDelegate.cs b/src/Compatibility/Core/src/iOS/DragAndDropDelegate.cs
index 726a42c027d5..18985431364d 100644
--- a/src/Compatibility/Core/src/iOS/DragAndDropDelegate.cs
+++ b/src/Compatibility/Core/src/iOS/DragAndDropDelegate.cs
@@ -147,8 +147,9 @@ public UIDragItem[] HandleDragStarting(View element, IVisualElementRenderer rend
if (args.Cancel)
return;
-
+#pragma warning disable CS0618 // Type or member is obsolete
if (!args.Handled)
+#pragma warning restore CS0618 // Type or member is obsolete
{
UIImage uIImage = null;
string clipDescription = String.Empty;
diff --git a/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropEventArgs.xaml b/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropEventArgs.xaml
new file mode 100644
index 000000000000..f19212fd7c00
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropEventArgs.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropEventArgs.xaml.cs b/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropEventArgs.xaml.cs
new file mode 100644
index 000000000000..19eb2328daf1
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropEventArgs.xaml.cs
@@ -0,0 +1,151 @@
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Controls.Xaml;
+
+namespace Maui.Controls.Sample;
+
+[XamlCompilation(XamlCompilationOptions.Compile)]
+public partial class DragAndDropEventArgs : ContentView
+{
+ bool _emittedDragOver = false;
+ public DragAndDropEventArgs()
+ {
+ InitializeComponent();
+ }
+
+ void AddEvent(string name)
+ {
+ events.Text += $"{name},";
+ }
+
+ void DragStarting(object sender, DragStartingEventArgs e)
+ {
+ _emittedDragOver = false;
+ if (e.PlatformArgs is PlatformDragStartingEventArgs platformArgs)
+ {
+#if IOS || MACCATALYST
+ if (platformArgs.Sender is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragInteraction is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.DragInteraction));
+ if (platformArgs.DragSession is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.DragSession));
+#elif ANDROID
+ if (platformArgs.Sender is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.Sender));
+ if (platformArgs.MotionEvent is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.MotionEvent));
+#elif WINDOWS
+ if (platformArgs.Sender is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragStartingEventArgs is not null)
+ AddEvent("DragStarting:" + nameof(platformArgs.DragStartingEventArgs));
+ AddEvent("DragStarting:" + nameof(platformArgs.Handled));
+#endif
+ }
+ }
+
+ void DropCompleted(object sender, DropCompletedEventArgs e)
+ {
+ if (e.PlatformArgs is PlatformDropCompletedEventArgs platformArgs)
+ {
+#if IOS || MACCATALYST
+ if (platformArgs.Sender is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.Sender));
+ if (platformArgs.DropInteraction is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.DropInteraction));
+ if (platformArgs.DropSession is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.DropSession));
+#elif ANDROID
+ if (platformArgs.Sender is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEvent is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.DragEvent));
+#elif WINDOWS
+ if (platformArgs.Sender is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.Sender));
+ if (platformArgs.DropCompletedEventArgs is not null)
+ AddEvent("DropCompleted:" + nameof(platformArgs.DropCompletedEventArgs));
+#endif
+ }
+ }
+
+ void DragLeave(object sender, DragEventArgs e)
+ {
+ if (e.PlatformArgs is PlatformDragEventArgs platformArgs)
+ {
+#if IOS || MACCATALYST
+ if (platformArgs.Sender is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.Sender));
+ if (platformArgs.DropInteraction is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.DropInteraction));
+ if (platformArgs.DropSession is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.DropSession));
+#elif ANDROID
+ if (platformArgs.Sender is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEvent is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.DragEvent));
+#elif WINDOWS
+ if (platformArgs.Sender is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEventArgs is not null)
+ AddEvent("DragLeave:" + nameof(platformArgs.DragEventArgs));
+ AddEvent("DragLeave:" + nameof(platformArgs.Handled));
+#endif
+ }
+ }
+
+ void DragOver(object sender, DragEventArgs e)
+ {
+ if (!_emittedDragOver) // This can generate a lot of noise, only add it once
+ {
+ if (e.PlatformArgs is PlatformDragEventArgs platformArgs)
+ {
+#if IOS || MACCATALYST
+ if (platformArgs.Sender is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.Sender));
+ if (platformArgs.DropInteraction is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.DropInteraction));
+ if (platformArgs.DropSession is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.DropSession));
+#elif ANDROID
+ if (platformArgs.Sender is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEvent is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.DragEvent));
+#elif WINDOWS
+ if (platformArgs.Sender is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEventArgs is not null)
+ AddEvent("DragOver:" + nameof(platformArgs.DragEventArgs));
+#endif
+ }
+ _emittedDragOver = true;
+ }
+ }
+
+ void Drop(object sender, DropEventArgs e)
+ {
+ if (e.PlatformArgs is PlatformDropEventArgs platformArgs)
+ {
+#if IOS || MACCATALYST
+ if (platformArgs.Sender is not null)
+ AddEvent("Drop:" + nameof(platformArgs.Sender));
+ if (platformArgs.DropInteraction is not null)
+ AddEvent("Drop:" + nameof(platformArgs.DropInteraction));
+ if (platformArgs.DropSession is not null)
+ AddEvent("Drop:" + nameof(platformArgs.DropSession));
+#elif ANDROID
+ if (platformArgs.Sender is not null)
+ AddEvent("Drop:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEvent is not null)
+ AddEvent("Drop:" + nameof(platformArgs.DragEvent));
+#elif WINDOWS
+ if (platformArgs.Sender is not null)
+ AddEvent("Drop:" + nameof(platformArgs.Sender));
+ if (platformArgs.DragEventArgs is not null)
+ AddEvent("Drop:" + nameof(platformArgs.DragEventArgs));
+#endif
+ }
+ }
+}
diff --git a/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropGallery.cs b/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropGallery.cs
index 1920c272e780..35b62daabda9 100644
--- a/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropGallery.cs
+++ b/src/Controls/samples/Controls.Sample.UITests/Elements/DragAndDropGallery.cs
@@ -9,6 +9,7 @@ public DragAndDropGallery()
{
Add(new DragAndDropEvents());
Add(new DragAndDropBetweenLayouts());
+ Add(new DragAndDropEventArgs());
}
}
}
\ No newline at end of file
diff --git a/src/Controls/src/Core/DragAndDrop/DragEventArgs.cs b/src/Controls/src/Core/DragAndDrop/DragEventArgs.cs
index 0b1ae0e4320e..a04cdf1c3d10 100644
--- a/src/Controls/src/Core/DragAndDrop/DragEventArgs.cs
+++ b/src/Controls/src/Core/DragAndDrop/DragEventArgs.cs
@@ -24,10 +24,12 @@ public DragEventArgs(DataPackage dataPackage)
///
/// The data package associated with the drag source.
/// The current location in the coordinate system of the drag.
- internal DragEventArgs(DataPackage dataPackage, Func? getPosition)
+ /// The platform-specific data associated with the drag.
+ internal DragEventArgs(DataPackage dataPackage, Func? getPosition, PlatformDragEventArgs platformArgs)
{
Data = dataPackage;
_getPosition = getPosition;
+ PlatformArgs = platformArgs;
}
///
@@ -40,6 +42,11 @@ internal DragEventArgs(DataPackage dataPackage, Func? getPosi
///
public DataPackageOperation AcceptedOperation { get; set; } = DataPackageOperation.Copy;
+ ///
+ /// Gets the platform-specific arguments associated with the .
+ ///
+ public PlatformDragEventArgs? PlatformArgs { get; }
+
///
/// Gets the location of the drag relative to the specified element.
///
diff --git a/src/Controls/src/Core/DragAndDrop/DragGestureRecognizer.cs b/src/Controls/src/Core/DragAndDrop/DragGestureRecognizer.cs
index 7daec858f44f..4b3303031182 100644
--- a/src/Controls/src/Core/DragAndDrop/DragGestureRecognizer.cs
+++ b/src/Controls/src/Core/DragAndDrop/DragGestureRecognizer.cs
@@ -108,18 +108,22 @@ internal void SendDropCompleted(DropCompletedEventArgs args)
DropCompleted?.Invoke(this, args);
}
- internal DragStartingEventArgs SendDragStarting(View element, Func? getPosition = null)
+ internal DragStartingEventArgs SendDragStarting(View element, Func? getPosition = null, PlatformDragStartingEventArgs? platformArgs = null)
{
- var args = new DragStartingEventArgs(getPosition);
+ 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;
diff --git a/src/Controls/src/Core/DragAndDrop/DragStartingEventArgs.cs b/src/Controls/src/Core/DragAndDrop/DragStartingEventArgs.cs
index 7604d61d90de..dbb21ba8d151 100644
--- a/src/Controls/src/Core/DragAndDrop/DragStartingEventArgs.cs
+++ b/src/Controls/src/Core/DragAndDrop/DragStartingEventArgs.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using Microsoft.Maui.Graphics;
namespace Microsoft.Maui.Controls
@@ -21,14 +22,18 @@ public DragStartingEventArgs()
/// Initializes a new instance of the class.
///
/// Function used to get the position relative a specified .
- internal DragStartingEventArgs(Func? getPosition)
+ /// The platform-specific data associated with the drag.
+ internal DragStartingEventArgs(Func? getPosition, PlatformDragStartingEventArgs? platformArgs)
{
_getPosition = getPosition;
+ PlatformArgs = platformArgs;
}
///
/// Gets or sets a value that indicates whether the event handler has handled the event or whether .NET MAUI should continue its own processing.
///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("Use PlatformArgs to handle customization. On Windows, set the PlatformArgs.Handled property to true if changing DragStartingEventArgs.")]
public bool Handled { get; set; }
///
@@ -36,6 +41,11 @@ internal DragStartingEventArgs(Func? getPosition)
///
public bool Cancel { get; set; }
+ ///
+ /// Gets the platform-specific arguments associated with the .
+ ///
+ public PlatformDragStartingEventArgs? PlatformArgs { get; }
+
///
/// Gets the data package that accompanies the drag source.
///
diff --git a/src/Controls/src/Core/DragAndDrop/DropCompletedEventArgs.cs b/src/Controls/src/Core/DragAndDrop/DropCompletedEventArgs.cs
index e2969c6dcfe6..52294930b95e 100644
--- a/src/Controls/src/Core/DragAndDrop/DropCompletedEventArgs.cs
+++ b/src/Controls/src/Core/DragAndDrop/DropCompletedEventArgs.cs
@@ -1,4 +1,3 @@
-#nullable disable
using System;
namespace Microsoft.Maui.Controls
@@ -7,5 +6,26 @@ namespace Microsoft.Maui.Controls
public class DropCompletedEventArgs : EventArgs
{
DataPackageOperation DropResult { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DropCompletedEventArgs()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The platform-specific data associated with the drag.
+ internal DropCompletedEventArgs(PlatformDropCompletedEventArgs platformArgs) : this()
+ {
+ PlatformArgs = platformArgs;
+ }
+
+ ///
+ /// Gets the platform-specific arguments associated with the .
+ ///
+ public PlatformDropCompletedEventArgs? PlatformArgs { get; }
}
}
diff --git a/src/Controls/src/Core/DragAndDrop/DropEventArgs.cs b/src/Controls/src/Core/DragAndDrop/DropEventArgs.cs
index 22b778b52b08..d15ac61f401a 100644
--- a/src/Controls/src/Core/DragAndDrop/DropEventArgs.cs
+++ b/src/Controls/src/Core/DragAndDrop/DropEventArgs.cs
@@ -25,11 +25,12 @@ public DropEventArgs(DataPackageView view)
///
/// The data package associated with the drop.
/// Function used to get the position relative a specified .
- internal DropEventArgs(DataPackageView view, Func? getPosition)
+ /// The platform-specific data associated with the drag.
+ internal DropEventArgs(DataPackageView? view, Func? getPosition, PlatformDropEventArgs platformArgs)
{
- _ = view ?? throw new ArgumentNullException(nameof(view));
- Data = view;
+ Data = view ?? new DataPackageView(new DataPackage());
_getPosition = getPosition;
+ PlatformArgs = platformArgs;
}
///
@@ -44,6 +45,11 @@ internal DropEventArgs(DataPackageView view, Func? getPositio
///
public bool Handled { get; set; }
+ ///
+ /// Gets the platform-specific arguments associated with the .
+ ///
+ public PlatformDropEventArgs? PlatformArgs { get; }
+
///
/// Gets the location of the drag relative to the specified element.
///
diff --git a/src/Controls/src/Core/DragAndDrop/PlatformDragEventArgs.cs b/src/Controls/src/Core/DragAndDrop/PlatformDragEventArgs.cs
new file mode 100644
index 000000000000..2c5008d52d95
--- /dev/null
+++ b/src/Controls/src/Core/DragAndDrop/PlatformDragEventArgs.cs
@@ -0,0 +1,96 @@
+using System;
+namespace Microsoft.Maui.Controls;
+
+///
+/// Platform-specific arguments associated with the .
+///
+public class PlatformDragEventArgs
+{
+#if IOS || MACCATALYST
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public UIKit.UIView? Sender { get; }
+
+ ///
+ /// Gets the interaction used for dropping items.
+ ///
+ public UIKit.UIDropInteraction DropInteraction { get; }
+
+ ///
+ /// Gets the associated information from the drop session.
+ ///
+ public UIKit.IUIDropSession DropSession { get; }
+
+ internal UIKit.UIDropProposal? DropProposal { get; private set; }
+
+ internal PlatformDragEventArgs(UIKit.UIView? sender, UIKit.UIDropInteraction dropInteraction,
+ UIKit.IUIDropSession dropSession)
+ {
+ Sender = sender;
+ DropInteraction = dropInteraction;
+ DropSession = dropSession;
+ }
+
+ ///
+ /// Sets the drop proposal when dragging over a view.
+ ///
+ /// The custom drop proposal to use.
+ ///
+ /// is used for DragOver and DragLeave events, but this method
+ /// only has an effect with DragOver events.
+ ///
+ public void SetDropProposal(UIKit.UIDropProposal dropProposal)
+ {
+ DropProposal = dropProposal;
+ }
+
+#elif ANDROID
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Android.Views.View Sender { get; }
+
+ ///
+ /// Gets the event containing information for drag and drop status.
+ ///
+ public Android.Views.DragEvent DragEvent { get; }
+
+ internal PlatformDragEventArgs(Android.Views.View sender, Android.Views.DragEvent dragEvent)
+ {
+ Sender = sender;
+ DragEvent = dragEvent;
+ }
+
+#elif WINDOWS
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Microsoft.UI.Xaml.UIElement? Sender { get; }
+
+ ///
+ /// Gets data for drag and drop events.
+ ///
+ public Microsoft.UI.Xaml.DragEventArgs DragEventArgs { get; }
+
+ ///
+ /// Gets or sets a value that indicates whether the DragEventArgs are changed.
+ ///
+ ///
+ /// Set the value of this property to true when changing the DragEventArgs so the system does not override the changes.
+ ///
+ public bool Handled { get; set; }
+
+ internal PlatformDragEventArgs(Microsoft.UI.Xaml.UIElement? sender,
+ Microsoft.UI.Xaml.DragEventArgs dragEventArgs)
+ {
+ Sender = sender;
+ DragEventArgs = dragEventArgs;
+ }
+
+#else
+ internal PlatformDragEventArgs()
+ {
+ }
+#endif
+}
diff --git a/src/Controls/src/Core/DragAndDrop/PlatformDragStartingEventArgs.cs b/src/Controls/src/Core/DragAndDrop/PlatformDragStartingEventArgs.cs
new file mode 100644
index 000000000000..5b0faf1929fd
--- /dev/null
+++ b/src/Controls/src/Core/DragAndDrop/PlatformDragStartingEventArgs.cs
@@ -0,0 +1,163 @@
+using System;
+
+namespace Microsoft.Maui.Controls;
+
+///
+/// Platform-specific arguments associated with the DragStartingEventArgs.
+///
+public class PlatformDragStartingEventArgs
+{
+#if IOS || MACCATALYST
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public UIKit.UIView? Sender { get; }
+
+ ///
+ /// Gets the interaction used for dragging items.
+ ///
+ public UIKit.UIDragInteraction DragInteraction { get; }
+
+ ///
+ /// Gets the associated information from the drag session.
+ ///
+ public UIKit.IUIDragSession DragSession { get; }
+
+ internal Foundation.NSItemProvider? ItemProvider { get; private set; }
+ internal Func? PreviewProvider { get; private set; }
+ internal UIKit.UIDragItem[]? DragItems { get; private set; }
+
+ internal PlatformDragStartingEventArgs(UIKit.UIView? sender, UIKit.UIDragInteraction dragInteraction,
+ UIKit.IUIDragSession dragSession)
+ {
+ Sender = sender;
+ DragInteraction = dragInteraction;
+ DragSession = dragSession;
+ }
+
+ ///
+ /// Sets the item provider when dragging begins.
+ ///
+ /// The custom item provider to use.
+ ///
+ /// This itemProvider will be applied to the MAUI generated dragItem.
+ ///
+ public void SetItemProvider (Foundation.NSItemProvider itemProvider)
+ {
+ ItemProvider = itemProvider;
+ }
+
+ ///
+ /// Sets the preview provider when dragging begins.
+ ///
+ /// The custom preview provider to use.
+ ///
+ /// This previewProvider will be applied to the MAUI generated dragItem.
+ ///
+ public void SetPreviewProvider(Func previewProvider)
+ {
+ PreviewProvider = previewProvider;
+ }
+
+ ///
+ /// Sets the drag items when dragging begins.
+ ///
+ /// The custom drag items to use.
+ ///
+ /// These dragItems will be used in place of the MAUI generated dragItem.
+ ///
+ public void SetDragItems(UIKit.UIDragItem[] dragItems)
+ {
+ DragItems = dragItems;
+ }
+
+#elif ANDROID
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Android.Views.View Sender { get; }
+
+ ///
+ /// Gets the event containing information for drag and drop status.
+ ///
+ public Android.Views.MotionEvent MotionEvent { get; }
+
+ internal Android.Views.View.DragShadowBuilder? DragShadowBuilder { get; private set; }
+ internal Android.Content.ClipData? ClipData { get; private set; }
+ internal Java.Lang.Object? LocalData { get; private set; }
+ internal Android.Views.DragFlags? DragFlags { get; private set; }
+
+ internal PlatformDragStartingEventArgs(Android.Views.View sender, Android.Views.MotionEvent motionEvent)
+ {
+ Sender = sender;
+ MotionEvent = motionEvent;
+ }
+
+ ///
+ /// Sets the drag shadow when dragging begins.
+ ///
+ /// The custom drag shadow builder to use.
+ public void SetDragShadowBuilder(Android.Views.View.DragShadowBuilder dragShadowBuilder)
+ {
+ DragShadowBuilder = dragShadowBuilder;
+ }
+
+ ///
+ /// Sets the clip data when dragging begins.
+ ///
+ /// The custom clip data to use.
+ public void SetClipData(Android.Content.ClipData clipData)
+ {
+ ClipData = clipData;
+ }
+
+ ///
+ /// Sets the local data when dragging begins.
+ ///
+ /// The custom local data to use.
+ public void SetLocalData(Java.Lang.Object localData)
+ {
+ LocalData = localData;
+ }
+
+ ///
+ /// Sets the drag flags when dragging begins.
+ ///
+ /// The custom drag flags to use.
+ public void SetDragFlags(Android.Views.DragFlags dragFlags)
+ {
+ DragFlags = dragFlags;
+ }
+
+#elif WINDOWS
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Microsoft.UI.Xaml.UIElement Sender { get; }
+
+ ///
+ /// Gets data for the DragStarting event.
+ ///
+ public Microsoft.UI.Xaml.DragStartingEventArgs DragStartingEventArgs { get; }
+
+ ///
+ /// Gets or sets a value that indicates whether the DragStartingEventArgs are changed.
+ ///
+ ///
+ /// Set this property's value to true when changing the DragStartingEventArgs so the system does not override the changes.
+ ///
+ public bool Handled { get; set; }
+
+ internal PlatformDragStartingEventArgs(Microsoft.UI.Xaml.UIElement sender,
+ Microsoft.UI.Xaml.DragStartingEventArgs dragStartingEventArgs)
+ {
+ Sender = sender;
+ DragStartingEventArgs = dragStartingEventArgs;
+ }
+
+#else
+ internal PlatformDragStartingEventArgs()
+ {
+ }
+#endif
+}
diff --git a/src/Controls/src/Core/DragAndDrop/PlatformDropCompletedEventArgs.cs b/src/Controls/src/Core/DragAndDrop/PlatformDropCompletedEventArgs.cs
new file mode 100644
index 000000000000..528457aaa454
--- /dev/null
+++ b/src/Controls/src/Core/DragAndDrop/PlatformDropCompletedEventArgs.cs
@@ -0,0 +1,112 @@
+using System;
+namespace Microsoft.Maui.Controls;
+
+///
+/// Platform-specific arguments associated with the DropCompletedEventArgs
+///
+public class PlatformDropCompletedEventArgs
+{
+#if IOS || MACCATALYST
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public UIKit.UIView? Sender { get; }
+
+ ///
+ /// Gets the interaction used for dragging items.
+ ///
+ /// ///
+ /// This property is used when is called from the SessionWillEnd method.
+ ///
+ public UIKit.UIDragInteraction? DragInteraction { get; }
+
+ ///
+ /// Gets the associated information from the drag session.
+ ///
+ ///
+ /// This property is used when is called from the SessionWillEnd method.
+ ///
+ public UIKit.IUIDragSession? DragSession { get; }
+
+ ///
+ /// Gets the value representing the response to a drop.
+ ///
+ ///
+ /// This property is used when is called from the SessionWillEnd method.
+ ///
+ public UIKit.UIDropOperation? DropOperation { get; }
+
+ ///
+ /// Gets the interaction used for dropping items.
+ ///
+ /// ///
+ /// This property is used when is called from the PerformDrop method.
+ ///
+ public UIKit.UIDropInteraction? DropInteraction { get; }
+
+ ///
+ /// Gets the associated information from the drop session.
+ ///
+ ///
+ /// This property is used when is called from the PerformDrop method.
+ ///
+ public UIKit.IUIDropSession? DropSession { get; }
+
+ internal PlatformDropCompletedEventArgs(UIKit.UIView? sender, UIKit.UIDragInteraction dragInteraction,
+ UIKit.IUIDragSession dragSession, UIKit.UIDropOperation dropOperation)
+ {
+ Sender = sender;
+ DragInteraction = dragInteraction;
+ DragSession = dragSession;
+ DropOperation = dropOperation;
+ }
+
+ internal PlatformDropCompletedEventArgs(UIKit.UIView? sender, UIKit.UIDropInteraction dropInteraction,
+ UIKit.IUIDropSession dropSession)
+ {
+ Sender = sender;
+ DropInteraction = dropInteraction;
+ DropSession = dropSession;
+ }
+
+#elif ANDROID
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Android.Views.View Sender { get; }
+
+ ///
+ /// Gets the event containing information for drag and drop status.
+ ///
+ public Android.Views.DragEvent DragEvent { get; }
+
+ internal PlatformDropCompletedEventArgs(Android.Views.View sender, Android.Views.DragEvent dragEvent)
+ {
+ Sender = sender;
+ DragEvent = dragEvent;
+ }
+
+#elif WINDOWS
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Microsoft.UI.Xaml.UIElement Sender { get; }
+
+ ///
+ /// Gets data for the DropCompleted event.
+ ///
+ public Microsoft.UI.Xaml.DropCompletedEventArgs DropCompletedEventArgs { get; }
+
+ internal PlatformDropCompletedEventArgs(Microsoft.UI.Xaml.UIElement sender,
+ Microsoft.UI.Xaml.DropCompletedEventArgs dropCompletedEventArgs)
+ {
+ Sender = sender;
+ DropCompletedEventArgs = dropCompletedEventArgs;
+ }
+
+#else
+ internal PlatformDropCompletedEventArgs()
+ {
+ }
+#endif
+}
diff --git a/src/Controls/src/Core/DragAndDrop/PlatformDropEventArgs.cs b/src/Controls/src/Core/DragAndDrop/PlatformDropEventArgs.cs
new file mode 100644
index 000000000000..13bc13d3d102
--- /dev/null
+++ b/src/Controls/src/Core/DragAndDrop/PlatformDropEventArgs.cs
@@ -0,0 +1,74 @@
+using System;
+
+namespace Microsoft.Maui.Controls;
+
+///
+/// Platform-specific arguments associated with the DropEventArgs.
+///
+public class PlatformDropEventArgs
+{
+#if IOS || MACCATALYST
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public UIKit.UIView? Sender { get; }
+
+ ///
+ /// Gets the interaction used for dropping items.
+ ///
+ public UIKit.UIDropInteraction DropInteraction { get; }
+
+ ///
+ /// Gets the associated information from the drop session.
+ ///
+ public UIKit.IUIDropSession DropSession { get; }
+
+ internal PlatformDropEventArgs(UIKit.UIView? sender, UIKit.UIDropInteraction dropInteraction,
+ UIKit.IUIDropSession dropSession)
+ {
+ Sender = sender;
+ DropInteraction = dropInteraction;
+ DropSession = dropSession;
+ }
+
+#elif ANDROID
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Android.Views.View Sender { get; }
+
+ ///
+ /// Gets the event containing information for drag and drop status.
+ ///
+ public Android.Views.DragEvent DragEvent { get; }
+
+ internal PlatformDropEventArgs(Android.Views.View sender, Android.Views.DragEvent dragEvent)
+ {
+ Sender = sender;
+ DragEvent = dragEvent;
+ }
+
+#elif WINDOWS
+ ///
+ /// Gets the native view attached to the event.
+ ///
+ public Microsoft.UI.Xaml.UIElement? Sender { get; }
+
+ ///
+ /// Gets data for drag and drop events.
+ ///
+ public Microsoft.UI.Xaml.DragEventArgs DragEventArgs { get; }
+
+ internal PlatformDropEventArgs(Microsoft.UI.Xaml.UIElement? sender,
+ Microsoft.UI.Xaml.DragEventArgs dragEventArgs)
+ {
+ Sender = sender;
+ DragEventArgs = dragEventArgs;
+ }
+
+#else
+ internal PlatformDropEventArgs()
+ {
+ }
+#endif
+}
diff --git a/src/Controls/src/Core/Platform/Android/DragAndDropGestureHandler.cs b/src/Controls/src/Core/Platform/Android/DragAndDropGestureHandler.cs
index a79c124477a2..d6033fe2f1b1 100644
--- a/src/Controls/src/Core/Platform/Android/DragAndDropGestureHandler.cs
+++ b/src/Controls/src/Core/Platform/Android/DragAndDropGestureHandler.cs
@@ -134,40 +134,40 @@ public bool OnDrag(AView v, DragEvent e)
_currentCustomLocalStateData = null;
if (dragSourceElement is View vSource)
{
- HandleDropCompleted(vSource);
+ HandleDropCompleted(vSource, new PlatformDropCompletedEventArgs(v, e));
}
}
break;
case DragAction.Started:
break;
case DragAction.Location:
- HandleDragOver(package, e);
+ HandleDragOver(package, e, new PlatformDragEventArgs(v, e));
break;
case DragAction.Drop:
{
- HandleDrop(e, _currentCustomLocalStateData);
+ HandleDrop(e, _currentCustomLocalStateData, new PlatformDropEventArgs(v, e));
break;
}
case DragAction.Entered:
- HandleDragOver(package, e);
+ HandleDragOver(package, e, new PlatformDragEventArgs(v, e));
break;
case DragAction.Exited:
- HandleDragLeave(package, e);
+ HandleDragLeave(package, e, new PlatformDragEventArgs(v, e));
break;
}
return true;
}
- void HandleDropCompleted(View element)
+ void HandleDropCompleted(View element, PlatformDropCompletedEventArgs platformArgs)
{
- var args = new DropCompletedEventArgs();
+ var args = new DropCompletedEventArgs(platformArgs);
SendEventArgs(rec => rec.SendDropCompleted(args), element);
}
- bool HandleDragLeave(DataPackage package, DragEvent e)
+ bool HandleDragLeave(DataPackage package, DragEvent e, PlatformDragEventArgs platformArgs)
{
- var dragEventArgs = new DragEventArgs(package, (relativeTo) => e.CalculatePosition(GetView(), relativeTo));
+ var dragEventArgs = new DragEventArgs(package, (relativeTo) => e.CalculatePosition(GetView(), relativeTo), platformArgs);
bool validTarget = false;
SendEventArgs(rec =>
{
@@ -182,9 +182,9 @@ bool HandleDragLeave(DataPackage package, DragEvent e)
return validTarget;
}
- bool HandleDragOver(DataPackage package, DragEvent e)
+ bool HandleDragOver(DataPackage package, DragEvent e, PlatformDragEventArgs platformArgs)
{
- var dragEventArgs = new DragEventArgs(package, (relativeTo) => e.CalculatePosition(GetView(), relativeTo));
+ var dragEventArgs = new DragEventArgs(package, (relativeTo) => e.CalculatePosition(GetView(), relativeTo), platformArgs);
bool validTarget = false;
SendEventArgs(rec =>
@@ -200,7 +200,7 @@ bool HandleDragOver(DataPackage package, DragEvent e)
return validTarget;
}
- void HandleDrop(DragEvent e, CustomLocalStateData customLocalStateData)
+ void HandleDrop(DragEvent e, CustomLocalStateData customLocalStateData, PlatformDropEventArgs platformArgs)
{
if (customLocalStateData.AcceptedOperation == DataPackageOperation.None)
return;
@@ -231,7 +231,7 @@ void HandleDrop(DragEvent e, CustomLocalStateData customLocalStateData)
datapackage.Image = text;
}
- var args = new DropEventArgs(datapackage?.View, (relativeTo) => e.CalculatePosition(GetView(), relativeTo));
+ var args = new DropEventArgs(datapackage?.View, (relativeTo) => e.CalculatePosition(GetView(), relativeTo), platformArgs);
SendEventArgs(async rec =>
{
if (!rec.AllowDrop)
@@ -266,7 +266,7 @@ public void OnLongPress(MotionEvent e)
if (v.Handle == IntPtr.Zero)
return;
- var args = rec.SendDragStarting(element, (relativeTo) => e.CalculatePosition(GetView(), relativeTo));
+ var args = rec.SendDragStarting(element, (relativeTo) => e.CalculatePosition(GetView(), relativeTo), new PlatformDragStartingEventArgs(v, e));
if (args.Cancel)
return;
@@ -274,64 +274,82 @@ public void OnLongPress(MotionEvent e)
CustomLocalStateData customLocalStateData = new CustomLocalStateData();
customLocalStateData.DataPackage = args.Data;
-
// TODO MAUI
string clipDescription = String.Empty;//AutomationPropertiesProvider.ConcatenateNameAndHelpText(element) ?? String.Empty;
- ClipData.Item item = null;
+ ClipData data = null;
List mimeTypes = new List();
+#pragma warning disable CS0618 // Type or member is obsolete
if (!args.Handled)
+#pragma warning restore CS0618 // Type or member is obsolete
{
- if (args.Data.Image != null)
+ if (args.PlatformArgs?.ClipData is null)
{
- mimeTypes.Add("image/jpeg");
- item = ConvertToClipDataItem(args.Data.Image, mimeTypes);
- }
- else
- {
- string text = clipDescription ?? args.Data.Text;
- if (Uri.TryCreate(text, UriKind.Absolute, out _))
+ ClipData.Item item = null;
+
+ if (args.Data.Image != null)
{
- item = new ClipData.Item(AUri.Parse(text));
- mimeTypes.Add(ClipDescription.MimetypeTextUrilist);
+ mimeTypes.Add("image/jpeg");
+ item = ConvertToClipDataItem(args.Data.Image, mimeTypes);
}
else
{
- item = new ClipData.Item(text);
- mimeTypes.Add(ClipDescription.MimetypeTextPlain);
+ string text = clipDescription ?? args.Data.Text;
+ if (Uri.TryCreate(text, UriKind.Absolute, out _))
+ {
+ item = new ClipData.Item(AUri.Parse(text));
+ mimeTypes.Add(ClipDescription.MimetypeTextUrilist);
+ }
+ else
+ {
+ item = new ClipData.Item(text);
+ mimeTypes.Add(ClipDescription.MimetypeTextPlain);
+ }
}
- }
- }
- var dataPackage = args.Data;
- ClipData.Item userItem = null;
- if (dataPackage.Image != null)
- userItem = ConvertToClipDataItem(dataPackage.Image, mimeTypes);
+ var dataPackage = args.Data;
+ ClipData.Item userItem = null;
+ if (dataPackage.Image != null)
+ userItem = ConvertToClipDataItem(dataPackage.Image, mimeTypes);
- if (dataPackage.Text != null)
- userItem = new ClipData.Item(dataPackage.Text);
+ if (dataPackage.Text != null)
+ userItem = new ClipData.Item(dataPackage.Text);
- if (item == null)
- {
- item = userItem;
- userItem = null;
- }
+ if (item == null)
+ {
+ item = userItem;
+ userItem = null;
+ }
- ClipData data = new ClipData(clipDescription, mimeTypes.ToArray(), item);
+ data = new ClipData(clipDescription, mimeTypes.ToArray(), item);
- if (userItem != null)
- data.AddItem(userItem);
+ if (userItem != null)
+ data.AddItem(userItem);
+ }
- var dragShadowBuilder = new AView.DragShadowBuilder(v);
+ else
+ {
+ data = args.PlatformArgs.ClipData;
+ }
+ }
customLocalStateData.SourcePlatformView = v;
customLocalStateData.SourceElement = element;
+ var dragShadowBuilder = args.PlatformArgs?.DragShadowBuilder ?? new AView.DragShadowBuilder(v);
+ var localData = args.PlatformArgs?.LocalData ?? customLocalStateData;
+
+ int dragFlags;
+ if (args.PlatformArgs?.DragFlags is ADragFlags d)
+ dragFlags = (int)d;
+ else
+ dragFlags = (int)ADragFlags.Global | (int)ADragFlags.GlobalUriRead;
+
if (OperatingSystem.IsAndroidVersionAtLeast(24))
- v.StartDragAndDrop(data, dragShadowBuilder, customLocalStateData, (int)ADragFlags.Global | (int)ADragFlags.GlobalUriRead);
+ v.StartDragAndDrop(data, dragShadowBuilder, localData, dragFlags);
else
#pragma warning disable CS0618, CA1416 // DragFlags.Global added in API 24: https://developer.android.com/reference/android/view/View#DRAG_FLAG_GLOBAL
- v.StartDrag(data, dragShadowBuilder, customLocalStateData, (int)ADragFlags.Global | (int)ADragFlags.GlobalUriRead);
+ v.StartDrag(data, dragShadowBuilder, localData, dragFlags);
#pragma warning restore CS0618, CA1416
});
}
diff --git a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs
index 9eaf9328a6e8..414ea88b4080 100644
--- a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs
+++ b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs
@@ -29,6 +29,7 @@ class GesturePlatformManager : IDisposable
bool _isPinching;
bool _wasPanGestureStartedSent;
bool _wasPinchGestureStartedSent;
+ const string _doNotUsePropertyString = "_XFPropertes_DONTUSE";
public GesturePlatformManager(IViewHandler handler)
{
@@ -136,7 +137,7 @@ void SendEventArgs(Action func)
void HandleDragLeave(object sender, Microsoft.UI.Xaml.DragEventArgs e)
{
- var dragEventArgs = ToDragEventArgs(e);
+ var dragEventArgs = ToDragEventArgs(e, new PlatformDragEventArgs(sender as UIElement, e));
dragEventArgs.AcceptedOperation = (DataPackageOperation)((int)dragEventArgs.AcceptedOperation);
SendEventArgs(rec =>
@@ -155,7 +156,7 @@ void HandleDragLeave(object sender, Microsoft.UI.Xaml.DragEventArgs e)
// e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
// Even if AcceptedOperation is already set to Copy it will cause the copy animation
// to remain even after the the dragged element has left
- if (operationPriorToSend != dragEventArgs.AcceptedOperation)
+ if (!dragEventArgs.PlatformArgs?.Handled ?? true && operationPriorToSend != dragEventArgs.AcceptedOperation)
{
var result = (int)dragEventArgs.AcceptedOperation;
e.AcceptedOperation = (global::Windows.ApplicationModel.DataTransfer.DataPackageOperation)result;
@@ -165,7 +166,7 @@ void HandleDragLeave(object sender, Microsoft.UI.Xaml.DragEventArgs e)
void HandleDragOver(object sender, Microsoft.UI.Xaml.DragEventArgs e)
{
- var dragEventArgs = ToDragEventArgs(e);
+ var dragEventArgs = ToDragEventArgs(e, new PlatformDragEventArgs(sender as UIElement, e));
SendEventArgs(rec =>
{
@@ -176,20 +177,23 @@ void HandleDragOver(object sender, Microsoft.UI.Xaml.DragEventArgs e)
}
rec.SendDragOver(dragEventArgs);
- var result = (int)dragEventArgs.AcceptedOperation;
- e.AcceptedOperation = (global::Windows.ApplicationModel.DataTransfer.DataPackageOperation)result;
+ if (!dragEventArgs.PlatformArgs?.Handled ?? true)
+ {
+ var result = (int)dragEventArgs.AcceptedOperation;
+ e.AcceptedOperation = (global::Windows.ApplicationModel.DataTransfer.DataPackageOperation)result;
+ }
});
}
void HandleDropCompleted(UIElement sender, Microsoft.UI.Xaml.DropCompletedEventArgs e)
{
- var args = new DropCompletedEventArgs();
+ var args = new DropCompletedEventArgs(new PlatformDropCompletedEventArgs(sender, e));
SendEventArgs(rec => rec.SendDropCompleted(args));
}
void HandleDrop(object sender, Microsoft.UI.Xaml.DragEventArgs e)
{
- var datapackage = e.DataView.Properties["_XFPropertes_DONTUSE"] as DataPackage;
+ var datapackage = e.DataView.Properties[_doNotUsePropertyString] as DataPackage;
VisualElement? element = null;
if (sender is IViewHandler handler &&
@@ -201,7 +205,7 @@ void HandleDrop(object sender, Microsoft.UI.Xaml.DragEventArgs e)
if (datapackage is null)
return;
- var args = new DropEventArgs(datapackage.View, (relativeTo) => GetPosition(relativeTo, e));
+ var args = new DropEventArgs(datapackage.View, (relativeTo) => GetPosition(relativeTo, e), new PlatformDropEventArgs(sender as UIElement, e));
SendEventArgs(async rec =>
{
if (!rec.AllowDrop)
@@ -231,13 +235,15 @@ void HandleDragStarting(UIElement sender, Microsoft.UI.Xaml.DragStartingEventArg
}
var handler = sender as IViewHandler;
- var args = rec.SendDragStarting(view, (relativeTo) => GetPosition(relativeTo, e));
+ var args = rec.SendDragStarting(view, (relativeTo) => GetPosition(relativeTo, e), new PlatformDragStartingEventArgs(sender, e));
- e.Data.Properties["_XFPropertes_DONTUSE"] = args.Data;
+ e.Data.Properties[_doNotUsePropertyString] = args.Data;
- if (!args.Handled && handler != null)
+#pragma warning disable CS0618 // Type or member is obsolete
+ if ((!args.Handled || (!args.PlatformArgs?.Handled ?? true)) && handler != null)
+#pragma warning restore CS0618 // Type or member is obsolete
{
- if (handler.PlatformView is UI.Xaml.Controls.Image nativeImage &&
+ if (handler?.PlatformView is UI.Xaml.Controls.Image nativeImage &&
nativeImage.Source is BitmapImage bi && bi.UriSource != null)
{
e.Data.SetBitmap(RandomAccessStreamReference.CreateFromUri(bi.UriSource));
@@ -257,10 +263,11 @@ void HandleDragStarting(UIElement sender, Microsoft.UI.Xaml.DragStartingEventArg
e.Data.SetText(args.Data.Text);
}
}
+
+ e.AllowedOperations = global::Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
}
e.Cancel = args.Cancel;
- e.AllowedOperations = global::Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
});
}
@@ -771,12 +778,12 @@ void HandleDoubleTapped(object sender, DoubleTappedRoutedEventArgs doubleTappedR
doubleTappedRoutedEventArgs.Handled = true;
}
- DragEventArgs ToDragEventArgs(UI.Xaml.DragEventArgs e)
+ DragEventArgs ToDragEventArgs(UI.Xaml.DragEventArgs e, PlatformDragEventArgs platformArgs)
{
// The package should never be null here since the UI.Xaml.DragEventArgs have already been initialized
- var package = e.DataView.Properties["_XFPropertes_DONTUSE"] as DataPackage;
+ var package = e.DataView.Properties[_doNotUsePropertyString] as DataPackage;
- return new DragEventArgs(package!, (relativeTo) => GetPosition(relativeTo, e));
+ return new DragEventArgs(package!, (relativeTo) => GetPosition(relativeTo, e), platformArgs);
}
}
}
diff --git a/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs b/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs
index e4344dda2364..24ed35c691e9 100644
--- a/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs
+++ b/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs
@@ -27,7 +27,7 @@ public void SessionWillEnd(UIDragInteraction interaction, IUIDragSession session
session.Items.Length > 0 &&
session.Items[0].LocalObject is CustomLocalStateData cdi)
{
- this.HandleDropCompleted(cdi.View);
+ this.HandleDropCompleted(cdi.View, new PlatformDropCompletedEventArgs(cdi.View.Handler.PlatformView as UIView, interaction, session, operation));
}
}
@@ -36,24 +36,12 @@ public UIDragItem[] GetItemsForBeginningSession(UIDragInteraction interaction, I
{
var originalPoint = session.LocationInView(_viewHandler.PlatformView);
- return HandleDragStarting((View)_viewHandler.VirtualView, _viewHandler, session);
+ return HandleDragStarting((View)_viewHandler.VirtualView, _viewHandler, session, new PlatformDragStartingEventArgs(_viewHandler.PlatformView, interaction, session));
}
[Export("dropInteraction:canHandleSession:")]
[Preserve(Conditional = true)]
- public bool CanHandleSession(UIDropInteraction interaction, IUIDropSession session)
- {
- if (session.LocalDragSession == null)
- return false;
-
- if (session.LocalDragSession.Items.Length > 0 &&
- session.LocalDragSession.Items[0].LocalObject is CustomLocalStateData)
- {
- return true;
- }
-
- return false;
- }
+ public bool CanHandleSession(UIDropInteraction interaction, IUIDropSession session) => true;
[Export("dropInteraction:sessionDidExit:")]
[Preserve(Conditional = true)]
@@ -61,13 +49,14 @@ public void SessionDidExit(UIDropInteraction interaction, IUIDropSession session
{
DataPackage package = null;
- if (session.LocalDragSession.Items.Length > 0 &&
+ if (session.LocalDragSession?.Items.Length > 0 &&
session.LocalDragSession.Items[0].LocalObject is CustomLocalStateData cdi)
{
package = cdi.DataPackage;
}
- HandleDragLeave((View)_viewHandler.VirtualView, package, session.LocalDragSession);
+
+ HandleDragLeave((View)_viewHandler.VirtualView, package, session.LocalDragSession, new PlatformDragEventArgs(_viewHandler.PlatformView, interaction, session));
}
[Export("dropInteraction:sessionDidUpdate:")]
@@ -88,9 +77,13 @@ public UIDropProposal SessionDidUpdate(UIDropInteraction interaction, IUIDropSes
}
var dragLocation = session.LocalDragSession.LocationInView(_viewHandler.PlatformView);
+ var platformArgs = new PlatformDragEventArgs(_viewHandler.PlatformView, interaction, session);
- if (HandleDragOver((View)_viewHandler.VirtualView, package, session.LocalDragSession))
+ if (HandleDragOver((View)_viewHandler.VirtualView, package, session.LocalDragSession, platformArgs))
{
+ if (platformArgs.DropProposal is not null)
+ return platformArgs.DropProposal;
+
operation = UIDropOperation.Copy;
}
@@ -101,15 +94,17 @@ public UIDropProposal SessionDidUpdate(UIDropInteraction interaction, IUIDropSes
[Preserve(Conditional = true)]
public void PerformDrop(UIDropInteraction interaction, IUIDropSession session)
{
- if (session.LocalDragSession == null)
- return;
-
- if (session.LocalDragSession.Items.Length > 0 &&
+ if (session.LocalDragSession?.Items.Length > 0 &&
session.LocalDragSession.Items[0].LocalObject is CustomLocalStateData cdi &&
_viewHandler.VirtualView is View view)
{
- HandleDrop(view, cdi.DataPackage, session);
- HandleDropCompleted(cdi.View);
+ HandleDrop(view, cdi.DataPackage, session, new PlatformDropEventArgs(cdi.View.Handler.PlatformView as UIView, interaction, session));
+ HandleDropCompleted(cdi.View, new PlatformDropCompletedEventArgs(cdi.View.Handler.PlatformView as UIView, interaction, session));
+ }
+ else if (_viewHandler.VirtualView is View v)
+ {
+ // if the developer added their own LocalObject, pass in null and still allow the HandleDrop to fire
+ HandleDrop(v, null, session, new PlatformDropEventArgs(null, interaction, session));
}
}
@@ -130,7 +125,8 @@ void SendEventArgs(Action func, View view)
}
}
- public UIDragItem[] HandleDragStarting(View element, IPlatformViewHandler handler, IUIDragSession session)
+
+ public UIDragItem[] HandleDragStarting(View element, IPlatformViewHandler handler, IUIDragSession session, PlatformDragStartingEventArgs platformArgs)
{
UIDragItem[] returnValue = null;
SendEventArgs(rec =>
@@ -141,13 +137,27 @@ public UIDragItem[] HandleDragStarting(View element, IPlatformViewHandler handle
var viewHandlerRef = new WeakReference(handler);
var sessionRef = new WeakReference(session);
- var args = rec.SendDragStarting(element, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef));
+ var args = rec.SendDragStarting(element, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef), platformArgs);
if (args.Cancel)
return;
+#pragma warning disable CS0618 // Type or member is obsolete
if (!args.Handled)
+#pragma warning restore CS0618 // Type or member is obsolete
{
+
+ if (args.PlatformArgs.DragItems is UIDragItem[] dragItems)
+ {
+ foreach (var item in dragItems)
+ {
+ if (item.LocalObject is null)
+ SetLocalObject(item, handler, args.Data);
+ }
+ returnValue = dragItems;
+ return;
+ }
+
UIImage uIImage = null;
string clipDescription = String.Empty;
NSItemProvider itemProvider = null;
@@ -182,13 +192,12 @@ public UIDragItem[] HandleDragStarting(View element, IPlatformViewHandler handle
}
}
- var dragItem = new UIDragItem(itemProvider);
- dragItem.LocalObject = new CustomLocalStateData()
- {
- Handler = handler,
- View = handler.VirtualView as View,
- DataPackage = args.Data
- };
+ var dragItem = new UIDragItem(args.PlatformArgs.ItemProvider ?? itemProvider);
+
+ SetLocalObject(dragItem, handler, args.Data);
+
+ if (args.PlatformArgs.PreviewProvider is not null)
+ dragItem.PreviewProvider = args.PlatformArgs.PreviewProvider;
returnValue = new UIDragItem[] { dragItem };
}
@@ -198,18 +207,28 @@ public UIDragItem[] HandleDragStarting(View element, IPlatformViewHandler handle
return returnValue ?? new UIDragItem[0];
}
- void HandleDropCompleted(View element)
+ void SetLocalObject (UIDragItem dragItem, IPlatformViewHandler handler, DataPackage data)
+ {
+ dragItem.LocalObject = new CustomLocalStateData()
+ {
+ Handler = handler,
+ View = handler.VirtualView as View,
+ DataPackage = data
+ };
+ }
+
+ void HandleDropCompleted(View element, PlatformDropCompletedEventArgs platformArgs)
{
- var args = new DropCompletedEventArgs();
+ var args = new DropCompletedEventArgs(platformArgs);
SendEventArgs(rec => rec.SendDropCompleted(args), element);
}
- bool HandleDragLeave(View element, DataPackage dataPackage, IUIDragSession session)
+ bool HandleDragLeave(View element, DataPackage dataPackage, IUIDragSession session, PlatformDragEventArgs platformArgs)
{
var viewHandlerRef = new WeakReference(_viewHandler);
- var sessionRef = new WeakReference(session);
+ var sessionRef = session is null ? null : new WeakReference(session);
- var dragEventArgs = new DragEventArgs(dataPackage, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef));
+ var dragEventArgs = new DragEventArgs(dataPackage, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef), platformArgs);
bool validTarget = false;
SendEventArgs(rec =>
@@ -224,12 +243,12 @@ bool HandleDragLeave(View element, DataPackage dataPackage, IUIDragSession sessi
return validTarget;
}
- bool HandleDragOver(View element, DataPackage dataPackage, IUIDragSession session)
+ bool HandleDragOver(View element, DataPackage dataPackage, IUIDragSession session, PlatformDragEventArgs platformArgs)
{
var viewHandlerRef = new WeakReference(_viewHandler);
var sessionRef = new WeakReference(session);
- var dragEventArgs = new DragEventArgs(dataPackage, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef));
+ var dragEventArgs = new DragEventArgs(dataPackage, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef), platformArgs);
bool validTarget = false;
SendEventArgs(rec =>
@@ -244,12 +263,12 @@ bool HandleDragOver(View element, DataPackage dataPackage, IUIDragSession sessio
return validTarget;
}
- void HandleDrop(View element, DataPackage datapackage, IUIDropSession session)
+ void HandleDrop(View element, DataPackage datapackage, IUIDropSession session, PlatformDropEventArgs platformArgs)
{
var viewHandlerRef = new WeakReference(_viewHandler);
- var sessionRef = new WeakReference(session);
+ var sessionRef = session is null ? null : new WeakReference(session);
- var args = new DropEventArgs(datapackage?.View, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef));
+ var args = new DropEventArgs(datapackage?.View, (relativeTo) => CalculatePosition(relativeTo, viewHandlerRef, sessionRef), platformArgs);
SendEventArgs(async rec =>
{
if (!rec.AllowDrop)
@@ -268,6 +287,8 @@ void HandleDrop(View element, DataPackage datapackage, IUIDropSession session)
static internal Point? CalculatePosition(IElement relativeTo, WeakReference viewHandlerRef, WeakReference sessionRef)
{
+ if (sessionRef is null)
+ return null;
var viewHandler = viewHandlerRef.Target as IPlatformViewHandler;
var session = sessionRef.Target as IUIDragDropSession;
diff --git a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
index 8707dce47f01..c06ad53add3a 100644
--- a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
@@ -1,4 +1,24 @@
#nullable enable
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.Sender.get -> Android.Views.View!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.MotionEvent.get -> Android.Views.MotionEvent!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetDragShadowBuilder(Android.Views.View.DragShadowBuilder! dragShadowBuilder) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetClipData(Android.Content.ClipData! clipData) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetLocalData(Java.Lang.Object! localData) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetDragFlags(Android.Views.DragFlags dragFlags) -> void
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.Sender.get -> Android.Views.View!
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DragEvent.get -> Android.Views.DragEvent!
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs.Sender.get -> Android.Views.View!
+Microsoft.Maui.Controls.PlatformDragEventArgs.DragEvent.get -> Android.Views.DragEvent!
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs.Sender.get -> Android.Views.View!
+Microsoft.Maui.Controls.PlatformDropEventArgs.DragEvent.get -> Android.Views.DragEvent!
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.DragEventArgs.Data.get -> Microsoft.Maui.Controls.DataPackage!
Microsoft.Maui.Controls.DragEventArgs.DragEventArgs(Microsoft.Maui.Controls.DataPackage! dataPackage) -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
index bbda42527ee0..103361925146 100644
--- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
@@ -1,4 +1,28 @@
#nullable enable
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs.DropInteraction.get -> UIKit.UIDropInteraction!
+Microsoft.Maui.Controls.PlatformDragEventArgs.DropSession.get -> UIKit.IUIDropSession!
+Microsoft.Maui.Controls.PlatformDragEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.PlatformDragEventArgs.SetDropProposal(UIKit.UIDropProposal! dropProposal) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragInteraction.get -> UIKit.UIDragInteraction!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragSession.get -> UIKit.IUIDragSession!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetItemProvider(Foundation.NSItemProvider! itemProvider) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetPreviewProvider(System.Func! previewProvider) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetDragItems(UIKit.UIDragItem![]! dragItems) -> void
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DragInteraction.get -> UIKit.UIDragInteraction?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DragSession.get -> UIKit.IUIDragSession?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropInteraction.get -> UIKit.UIDropInteraction?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropOperation.get -> UIKit.UIDropOperation?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropSession.get -> UIKit.IUIDropSession?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs.DropInteraction.get -> UIKit.UIDropInteraction!
+Microsoft.Maui.Controls.PlatformDropEventArgs.DropSession.get -> UIKit.IUIDropSession!
+Microsoft.Maui.Controls.PlatformDropEventArgs.Sender.get -> UIKit.UIView?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.DropEventArgs.Data.get -> Microsoft.Maui.Controls.DataPackageView!
Microsoft.Maui.Controls.DropEventArgs.DropEventArgs(Microsoft.Maui.Controls.DataPackageView! view) -> void
@@ -97,6 +121,9 @@ static Microsoft.Maui.Controls.Region.operator !=(Microsoft.Maui.Controls.Region
static Microsoft.Maui.Controls.Region.operator ==(Microsoft.Maui.Controls.Region left, Microsoft.Maui.Controls.Region right) -> bool
static Microsoft.Maui.Controls.Shapes.Matrix.operator !=(Microsoft.Maui.Controls.Shapes.Matrix left, Microsoft.Maui.Controls.Shapes.Matrix right) -> bool
static Microsoft.Maui.Controls.Shapes.Matrix.operator ==(Microsoft.Maui.Controls.Shapes.Matrix left, Microsoft.Maui.Controls.Shapes.Matrix right) -> bool
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
~Microsoft.Maui.Controls.Handlers.Compatibility.FrameRenderer.FrameRenderer(Microsoft.Maui.IPropertyMapper mapper) -> void
~Microsoft.Maui.Controls.Handlers.Compatibility.FrameRenderer.FrameRenderer(Microsoft.Maui.IPropertyMapper mapper, Microsoft.Maui.CommandMapper commandMapper) -> void
override Microsoft.Maui.Controls.View.ChangeVisualState() -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
index 2e2430d1af8d..228329607d18 100644
--- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
@@ -1,4 +1,31 @@
#nullable enable
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragInteraction.get -> UIKit.UIDragInteraction!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragSession.get -> UIKit.IUIDragSession!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetItemProvider(Foundation.NSItemProvider! itemProvider) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetPreviewProvider(System.Func! previewProvider) -> void
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.SetDragItems(UIKit.UIDragItem![]! dragItems) -> void
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DragInteraction.get -> UIKit.UIDragInteraction?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DragSession.get -> UIKit.IUIDragSession?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropInteraction.get -> UIKit.UIDropInteraction?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropOperation.get -> UIKit.UIDropOperation?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropSession.get -> UIKit.IUIDropSession?
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs.DropInteraction.get -> UIKit.UIDropInteraction!
+Microsoft.Maui.Controls.PlatformDragEventArgs.DropSession.get -> UIKit.IUIDropSession!
+Microsoft.Maui.Controls.PlatformDragEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.PlatformDragEventArgs.SetDropProposal(UIKit.UIDropProposal! dropProposal) -> void
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs.DropInteraction.get -> UIKit.UIDropInteraction!
+Microsoft.Maui.Controls.PlatformDropEventArgs.DropSession.get -> UIKit.IUIDropSession!
+Microsoft.Maui.Controls.PlatformDropEventArgs.Sender.get -> UIKit.UIView?
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.DragEventArgs.Data.get -> Microsoft.Maui.Controls.DataPackage!
Microsoft.Maui.Controls.DragEventArgs.DragEventArgs(Microsoft.Maui.Controls.DataPackage! dataPackage) -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
index 2dfb099584a1..9829c8174121 100644
--- a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
@@ -1,4 +1,12 @@
#nullable enable
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.KeyboardAccelerator.Key.get -> string?
Microsoft.Maui.Controls.KeyboardAccelerator.Key.set -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
index 7ca700624bfa..fa3c0d170092 100644
--- a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
@@ -1,4 +1,24 @@
#nullable enable
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.Sender.get -> Microsoft.UI.Xaml.UIElement!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragStartingEventArgs.get -> Microsoft.UI.Xaml.DragStartingEventArgs!
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.Handled.get -> bool
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs.Handled.set -> void
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.Sender.get -> Microsoft.UI.Xaml.UIElement!
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs.DropCompletedEventArgs.get -> Microsoft.UI.Xaml.DropCompletedEventArgs!
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs.Sender.get -> Microsoft.UI.Xaml.UIElement?
+Microsoft.Maui.Controls.PlatformDragEventArgs.DragEventArgs.get -> Microsoft.UI.Xaml.DragEventArgs!
+Microsoft.Maui.Controls.PlatformDragEventArgs.Handled.get -> bool
+Microsoft.Maui.Controls.PlatformDragEventArgs.Handled.set -> void
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs.Sender.get -> Microsoft.UI.Xaml.UIElement?
+Microsoft.Maui.Controls.PlatformDropEventArgs.DragEventArgs.get -> Microsoft.UI.Xaml.DragEventArgs!
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.KeyboardAccelerator.Key.get -> string?
Microsoft.Maui.Controls.KeyboardAccelerator.Key.set -> void
diff --git a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
index d07dba8b4a81..648ab0cb564e 100644
--- a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
@@ -1,4 +1,12 @@
#nullable enable
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.DragEventArgs.Data.get -> Microsoft.Maui.Controls.DataPackage!
Microsoft.Maui.Controls.DragEventArgs.DragEventArgs(Microsoft.Maui.Controls.DataPackage! dataPackage) -> void
diff --git a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
index 13fe27cd7424..308faee82f23 100644
--- a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
@@ -1,4 +1,12 @@
#nullable enable
+Microsoft.Maui.Controls.DragEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragEventArgs?
+Microsoft.Maui.Controls.PlatformDragStartingEventArgs
+Microsoft.Maui.Controls.PlatformDropCompletedEventArgs
+Microsoft.Maui.Controls.PlatformDragEventArgs
+Microsoft.Maui.Controls.PlatformDropEventArgs
+Microsoft.Maui.Controls.DragStartingEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDragStartingEventArgs?
+Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
+Microsoft.Maui.Controls.DropEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropEventArgs?
Microsoft.Maui.Controls.KeyboardAccelerator
Microsoft.Maui.Controls.KeyboardAccelerator.Key.get -> string?
Microsoft.Maui.Controls.KeyboardAccelerator.Key.set -> void
diff --git a/src/Controls/tests/UITests/Tests/DragAndDropUITests.cs b/src/Controls/tests/UITests/Tests/DragAndDropUITests.cs
index e014136014ed..2182e2ac720c 100644
--- a/src/Controls/tests/UITests/Tests/DragAndDropUITests.cs
+++ b/src/Controls/tests/UITests/Tests/DragAndDropUITests.cs
@@ -4,6 +4,7 @@
using Microsoft.Maui.Graphics;
using NUnit.Framework;
using TestUtils.Appium.UITests;
+using Xamarin.UITest;
namespace Microsoft.Maui.AppiumTests
{
@@ -66,6 +67,83 @@ public void DragAndDropBetweenLayouts()
}
[Test]
+ public void PlatformDragEventArgs()
+ {
+ App.WaitForElement("TargetView");
+ App.EnterText("TargetView", "DragAndDropEventArgs");
+ App.Tap("GoButton");
+
+ App.WaitForElement("LabelDragElement");
+ App.DragAndDrop("LabelDragElement", "DragTarget");
+ App.WaitForElement("DragEventsLabel");
+
+ var textAfterDrag = App.Query("DragEventsLabel").First().Text;
+
+ if (UITestContext?.TestConfig.TestDevice == TestDevice.iOS ||
+ UITestContext?.TestConfig.TestDevice == TestDevice.Mac)
+ {
+ Assert.True(textAfterDrag.Contains("DragStarting:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragStarting:DragInteraction", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragStarting:DragSession", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("DropCompleted:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DropCompleted:DropInteraction", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DropCompleted:DropSession", StringComparison.OrdinalIgnoreCase));
+
+ // Until the UI test can drag over an item without placing it down
+ //Assert.True(textAfterDrag.Contains("DragLeave:Sender", StringComparison.OrdinalIgnoreCase));
+ //Assert.True(textAfterDrag.Contains("DragLeave:DropInteraction", StringComparison.OrdinalIgnoreCase));
+ //Assert.True(textAfterDrag.Contains("DragLeave:DropSession", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("DragOver:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragOver:DropInteraction", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragOver:DropSession", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("Drop:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("Drop:DropInteraction", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("Drop:DropSession", StringComparison.OrdinalIgnoreCase));
+ }
+ else if (UITestContext?.TestConfig.TestDevice == TestDevice.Android)
+ {
+ Assert.True(textAfterDrag.Contains("DragStarting:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragStarting:MotionEvent", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("DropCompleted:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DropCompleted:DragEvent", StringComparison.OrdinalIgnoreCase));
+
+ // Until the UI test can drag over an item without placing it down
+ //Assert.True(textAfterDrag.Contains("DragLeave:Sender", StringComparison.OrdinalIgnoreCase));
+ //Assert.True(textAfterDrag.Contains("DragLeave:DragEvent", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("DragOver:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragOver:DragEvent", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("Drop:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("Drop:DragEvent", StringComparison.OrdinalIgnoreCase));
+
+ }
+ else if (UITestContext?.TestConfig.TestDevice == TestDevice.Windows)
+ {
+ Assert.True(textAfterDrag.Contains("DragStarting:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragStarting:DragStartingEventArgs", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragStarting:Handled", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("DropCompleted:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DropCompleted:DropCompletedEventArgs", StringComparison.OrdinalIgnoreCase));
+
+ // Until the UI test can drag over an item without placing it down
+ //Assert.True(textAfterDrag.Contains("DragLeave:Sender", StringComparison.OrdinalIgnoreCase));
+ //Assert.True(textAfterDrag.Contains("DragLeave:DragEventArgs", StringComparison.OrdinalIgnoreCase));
+ //Assert.True(textAfterDrag.Contains("DragLeave:Handled", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("DragOver:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("DragOver:DragEventArgs", StringComparison.OrdinalIgnoreCase));
+
+ Assert.True(textAfterDrag.Contains("Drop:Sender", StringComparison.OrdinalIgnoreCase));
+ Assert.True(textAfterDrag.Contains("Drop:DragEventArgs", StringComparison.OrdinalIgnoreCase));
+ }
+ }
+
public void DragStartEventCoordinates()
{
App.WaitForElement("TargetView");