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");