Skip to content

Commit 05d110f

Browse files
[Windows] - Handle Dynamic Updates for CanDrag and AllowDrop in Drag and Drop Gesture (dotnet#27845)
* Fixed-Drag-And-Drop-RunTime * Modified-Test * Reverted-test * Modified-Code * Reverted-Unwanted-Changes * Modified.
1 parent b398b9a commit 05d110f

3 files changed

Lines changed: 130 additions & 13 deletions

File tree

src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,18 @@ void ClearContainerEventHandlers()
406406
_container.ManipulationCompleted -= OnManipulationCompleted;
407407
_container.PointerCanceled -= OnPointerCanceled;
408408
}
409+
410+
if (Element is View && ElementGestureRecognizers is { } gestureRecognizers)
411+
{
412+
if (gestureRecognizers.FirstGestureOrDefault<DragGestureRecognizer>() is { } dragGesture)
413+
{
414+
dragGesture.PropertyChanged -= HandleDragAndDropGesturePropertyChanged;
415+
}
416+
if (gestureRecognizers.FirstGestureOrDefault<DropGestureRecognizer>() is { } dropGesture)
417+
{
418+
dropGesture.PropertyChanged -= HandleDragAndDropGesturePropertyChanged;
419+
}
420+
}
409421
}
410422
}
411423

@@ -822,26 +834,36 @@ void UpdateDragAndDropGestureRecognizers()
822834
return;
823835
}
824836

825-
bool canDrag = gestures.FirstGestureOrDefault<DragGestureRecognizer>()?.CanDrag ?? false;
826-
bool allowDrop = gestures.FirstGestureOrDefault<DropGestureRecognizer>()?.AllowDrop ?? false;
837+
DragGestureRecognizer? dragGesture = gestures.FirstGestureOrDefault<DragGestureRecognizer>();
838+
DropGestureRecognizer? dropGesture = gestures.FirstGestureOrDefault<DropGestureRecognizer>();
827839

828-
if (canDrag)
840+
if (dragGesture is not null)
829841
{
830-
_subscriptionFlags |= SubscriptionFlags.ContainerDragEventsSubscribed;
842+
dragGesture.PropertyChanged -= HandleDragAndDropGesturePropertyChanged;
843+
dragGesture.PropertyChanged += HandleDragAndDropGesturePropertyChanged;
831844

832-
_container.CanDrag = true;
833-
_container.DragStarting += HandleDragStarting;
834-
_container.DropCompleted += HandleDropCompleted;
845+
if (dragGesture.CanDrag && ((_subscriptionFlags & SubscriptionFlags.ContainerDragEventsSubscribed) == 0))
846+
{
847+
_subscriptionFlags |= SubscriptionFlags.ContainerDragEventsSubscribed;
848+
_container.CanDrag = true;
849+
_container.DragStarting += HandleDragStarting;
850+
_container.DropCompleted += HandleDropCompleted;
851+
}
835852
}
836853

837-
if (allowDrop)
854+
if (dropGesture is not null)
838855
{
839-
_subscriptionFlags |= SubscriptionFlags.ContainerDropEventsSubscribed;
856+
dropGesture.PropertyChanged -= HandleDragAndDropGesturePropertyChanged;
857+
dropGesture.PropertyChanged += HandleDragAndDropGesturePropertyChanged;
840858

841-
_container.AllowDrop = true;
842-
_container.DragOver += HandleDragOver;
843-
_container.Drop += HandleDrop;
844-
_container.DragLeave += HandleDragLeave;
859+
if (dropGesture.AllowDrop && ((_subscriptionFlags & SubscriptionFlags.ContainerDropEventsSubscribed) == 0))
860+
{
861+
_subscriptionFlags |= SubscriptionFlags.ContainerDropEventsSubscribed;
862+
_container.AllowDrop = true;
863+
_container.DragOver += HandleDragOver;
864+
_container.Drop += HandleDrop;
865+
_container.DragLeave += HandleDragLeave;
866+
}
845867
}
846868
}
847869

@@ -983,6 +1005,15 @@ void HandleDoubleTapped(object sender, DoubleTappedRoutedEventArgs doubleTappedR
9831005
doubleTappedRoutedEventArgs.Handled = true;
9841006
}
9851007

1008+
void HandleDragAndDropGesturePropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
1009+
{
1010+
if (e.PropertyName == DragGestureRecognizer.CanDragProperty.PropertyName ||
1011+
e.PropertyName == DropGestureRecognizer.AllowDropProperty.PropertyName)
1012+
{
1013+
UpdateDragAndDropGestureRecognizers();
1014+
}
1015+
}
1016+
9861017
DragEventArgs ToDragEventArgs(UI.Xaml.DragEventArgs e, PlatformDragEventArgs platformArgs)
9871018
{
9881019
// The package should never be null here since the UI.Xaml.DragEventArgs have already been initialized
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
namespace Maui.Controls.Sample.Issues
2+
{
3+
4+
[Issue(IssueTracker.Github, 12726, "Drag and Drop Gesture Fails on Runtime Changes of CanDrag and AllowDrop in Windows",
5+
PlatformAffected.UWP)]
6+
public class Issue12726 : TestContentPage
7+
{
8+
protected override void Init()
9+
{
10+
Label dragResult = new Label();
11+
Label dropResult = new Label();
12+
13+
DragGestureRecognizer dragGestureRecognizer = new DragGestureRecognizer { CanDrag = false };
14+
Label dragBox = new Label
15+
{
16+
HeightRequest = 200,
17+
WidthRequest = 200,
18+
BackgroundColor = Colors.Purple,
19+
GestureRecognizers = { dragGestureRecognizer },
20+
AutomationId = "DragElement"
21+
};
22+
dragGestureRecognizer.DragStarting += (_, __) => dragResult.Text = "DragEventTriggered";
23+
24+
DropGestureRecognizer dropGestureRecognizer = new DropGestureRecognizer { AllowDrop = false };
25+
Label dropBox = new Label
26+
{
27+
HeightRequest = 200,
28+
WidthRequest = 200,
29+
BackgroundColor = Colors.Pink,
30+
GestureRecognizers = { dropGestureRecognizer },
31+
AutomationId = "DropTarget"
32+
};
33+
dropGestureRecognizer.Drop += (_, __) => dropResult.Text = "DropEventTriggered";
34+
35+
Button button = new Button
36+
{
37+
Text = "Enable Drag and Drop",
38+
AutomationId = "EnableDragAndDrop"
39+
};
40+
41+
button.Clicked += (_, __) =>
42+
{
43+
dragGestureRecognizer.CanDrag = true;
44+
dropGestureRecognizer.AllowDrop = true;
45+
};
46+
47+
Content = new StackLayout
48+
{
49+
Spacing = 5,
50+
Children =
51+
{
52+
dragBox,
53+
dropBox,
54+
button,
55+
dragResult,
56+
dropResult
57+
}
58+
};
59+
}
60+
}
61+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using NUnit.Framework;
2+
using UITest.Appium;
3+
using UITest.Core;
4+
5+
namespace Microsoft.Maui.TestCases.Tests.Issues
6+
{
7+
public class Issue12726 : _IssuesUITest
8+
{
9+
public Issue12726(TestDevice testDevice) : base(testDevice)
10+
{
11+
}
12+
13+
public override string Issue => "Drag and Drop Gesture Fails on Runtime Changes of CanDrag and AllowDrop in Windows";
14+
15+
[Test]
16+
[Category(UITestCategories.DragAndDrop)]
17+
public void DragAndDropShouldWorkRunTime()
18+
{
19+
App.WaitForElement("EnableDragAndDrop");
20+
App.Tap("EnableDragAndDrop");
21+
App.DragAndDrop("DragElement", "DropTarget");
22+
App.WaitForElement("DragEventTriggered");
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)