Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support using a custom RootElementFinder #349

Merged
merged 1 commit into from
Oct 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using GongSolutions.WPF.DragDrop.Utilities;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
Expand Down Expand Up @@ -1113,5 +1114,29 @@ public static ScrollViewer GetDropTargetScrollViewer(DependencyObject element)
{
return (ScrollViewer)element?.GetValue(DropTargetScrollViewerProperty);
}

/// <summary>
/// Gets or sets the root element finder.
/// </summary>
public static readonly DependencyProperty RootElementFinderProperty
= DependencyProperty.RegisterAttached("RootElementFinder",
typeof(IRootElementFinder),
typeof(DragDrop));

/// <summary>
/// Gets the root element finder.
/// </summary>
public static IRootElementFinder GetRootElementFinder(UIElement target)
{
return (IRootElementFinder)target.GetValue(RootElementFinderProperty);
}

/// <summary>
/// Sets the root element finder.
/// </summary>
public static void SetRootElementFinder(UIElement target, IRootElementFinder value)
{
target.SetValue(RootElementFinderProperty, value);
}
}
}
28 changes: 22 additions & 6 deletions src/GongSolutions.WPF.DragDrop/DragDrop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
using System.Windows.Media.Imaging;
using GongSolutions.Wpf.DragDrop.Icons;
using GongSolutions.Wpf.DragDrop.Utilities;
using GongSolutions.WPF.DragDrop.Utilities;

namespace GongSolutions.Wpf.DragDrop
{
public static partial class DragDrop
{
private static void CreateDragAdorner(DropInfo dropInfo)
private static void CreateDragAdorner(DropInfo dropInfo, UIElement sender)
{
var dragInfo = dropInfo.DragInfo;
var template = GetDropAdornerTemplate(dropInfo.VisualTarget) ?? GetDragAdornerTemplate(dragInfo.VisualSource);
Expand Down Expand Up @@ -81,19 +82,19 @@ private static void CreateDragAdorner(DropInfo dropInfo)
adornment.Opacity = GetDefaultDragAdornerOpacity(dragInfo.VisualSource);
}

var rootElement = RootElementFinder.FindRoot(dropInfo.VisualTarget ?? dragInfo.VisualSource);
var rootElement = TryGetRootElementFinder(sender).FindRoot(dropInfo.VisualTarget ?? dragInfo.VisualSource);
DragAdorner = new DragAdorner(rootElement, adornment, GetDragAdornerTranslation(dragInfo.VisualSource));
}
}

private static void CreateEffectAdorner(DropInfo dropInfo)
private static void CreateEffectAdorner(DropInfo dropInfo, UIElement sender)
{
var dragInfo = m_DragInfo;
var template = GetEffectAdornerTemplate(dragInfo.VisualSource, dropInfo.Effects, dropInfo.DestinationText, dropInfo.EffectText);

if (template != null)
{
var rootElement = RootElementFinder.FindRoot(dropInfo.VisualTarget ?? dragInfo.VisualSource);
var rootElement = TryGetRootElementFinder(sender).FindRoot(dropInfo.VisualTarget ?? dragInfo.VisualSource);

var adornment = new ContentPresenter();
adornment.Content = dragInfo.Data;
Expand Down Expand Up @@ -280,6 +281,21 @@ private static IDropTarget TryGetDropHandler(DropInfo dropInfo, UIElement sender
return dropHandler ?? DefaultDropHandler;
}

/// <summary>
/// Gets the root element handler from the sender or uses the default implementation, if it is null.
/// </summary>
/// <param name="sender">the sender from an event, e.g. drag over</param>
/// <returns></returns>
private static IRootElementFinder TryGetRootElementFinder(UIElement sender)
{
IRootElementFinder rootElementFinder = null;
if (sender != null)
{
rootElementFinder = GetRootElementFinder(sender);
}
return rootElementFinder ?? new RootElementFinder();
}

private static void DragSourceOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DoMouseButtonDown(sender, e);
Expand Down Expand Up @@ -521,7 +537,7 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy

if (DragAdorner == null && dragInfo != null)
{
CreateDragAdorner(dropInfo);
CreateDragAdorner(dropInfo, sender as UIElement);
}

DragAdorner?.Move(e.GetPosition(DragAdorner.AdornedElement), dragInfo != null ? GetDragMouseAnchorPoint(dragInfo.VisualSource) : default(Point), ref _adornerMousePosition, ref _adornerSize);
Expand Down Expand Up @@ -585,7 +601,7 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy
// Set the drag effect adorner if there is one
if (dragInfo != null && (EffectAdorner == null || EffectAdorner.Effects != dropInfo.Effects))
{
CreateEffectAdorner(dropInfo);
CreateEffectAdorner(dropInfo, sender as UIElement);
}

EffectAdorner?.Move(e.GetPosition(EffectAdorner.AdornedElement), default(Point), ref _effectAdornerMousePosition, ref _effectAdornerSize);
Expand Down
17 changes: 17 additions & 0 deletions src/GongSolutions.WPF.DragDrop/Utilities/IRootElementFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Windows;

namespace GongSolutions.WPF.DragDrop.Utilities
{
/// <summary>
/// Interface implemented by the root element finder.
/// </summary>
public interface IRootElementFinder
{
/// <summary>
/// Gets the root element.
/// </summary>
/// <param name="visual">The visual element to find the root for.</param>
/// <returns>The root element.</returns>
UIElement FindRoot(DependencyObject visual);
}
}
8 changes: 5 additions & 3 deletions src/GongSolutions.WPF.DragDrop/Utilities/RootElementFinder.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Windows;
using GongSolutions.WPF.DragDrop.Utilities;
using System.Windows;
using System.Windows.Controls;

namespace GongSolutions.Wpf.DragDrop.Utilities
{
public static class RootElementFinder
public class RootElementFinder : IRootElementFinder
{
public static UIElement FindRoot(DependencyObject visual)
public UIElement FindRoot(DependencyObject visual)
{
var parentWindow = Window.GetWindow(visual);
var rootElement = parentWindow != null ? parentWindow.Content as UIElement : null;
Expand All @@ -20,6 +21,7 @@ public static UIElement FindRoot(DependencyObject visual)
rootElement = visual.GetVisualAncestor<Page>() ?? visual.GetVisualAncestor<UserControl>() as UIElement;
}
}

// i don't want the fu... windows forms reference
// if (rootElement == null) {
// var elementHost = m_DragInfo.VisualSource.GetVisualAncestor<ElementHost>();
Expand Down