Auf dieser Grundlage habe ich eine Attached Behavior geschaffen, die leicht wie folgt verwendet werden kann -
<ListView
xmlns:WpfExtensions="clr-namespace:WpfExtensions"
WpfExtensions:DragDropExtension.ScrollOnDragDrop="True"
Hier ist der Code für angebracht Verhalten ist -
/// <summary>
/// Provides extended support for drag drop operation
/// </summary>
public static class DragDropExtension
{
public static read-only DependencyProperty ScrollOnDragDropProperty =
DependencyProperty.RegisterAttached("ScrollOnDragDrop",
typeof(bool),
typeof(DragDropExtension),
new PropertyMetadata(false, HandleScrollOnDragDropChanged));
public static bool GetScrollOnDragDrop(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool)element.GetValue(ScrollOnDragDropProperty);
}
public static void SetScrollOnDragDrop(DependencyObject element, bool value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(ScrollOnDragDropProperty, value);
}
private static void HandleScrollOnDragDropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement container = d as FrameworkElement;
if (d == null)
{
Debug.Fail("Invalid type!");
return;
}
Unsubscribe(container);
if (true.Equals(e.NewValue))
{
Subscribe(container);
}
}
private static void Subscribe(FrameworkElement container)
{
container.PreviewDragOver += OnContainerPreviewDragOver;
}
private static void OnContainerPreviewDragOver(object sender, DragEventArgs e)
{
FrameworkElement container = sender as FrameworkElement;
if (container == null)
{
return;
}
ScrollViewer scrollViewer = GetFirstVisualChild<ScrollViewer>(container);
if (scrollViewer == null)
{
return;
}
double tolerance = 60;
double verticalPos = e.GetPosition(container).Y;
double offset = 20;
if (verticalPos < tolerance) // Top of visible list?
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset); //Scroll up.
}
else if (verticalPos > container.ActualHeight - tolerance) //Bottom of visible list?
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset); //Scroll down.
}
}
private static void Unsubscribe(FrameworkElement container)
{
container.PreviewDragOver -= OnContainerPreviewDragOver;
}
public static T GetFirstVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
return (T)child;
}
T childItem = GetFirstVisualChild<T>(child);
if (childItem != null)
{
return childItem;
}
}
}
return null;
}
}
ich Ihnen Methode versucht und es funktioniert. Wenn Objekte jedoch nach dem Löschen in derselben Liste gezogen werden, kehrt sie zum ursprünglichen Objekt zurück, an dem ich das gelöschte Objekt sehen möchte. Hast du das und hast du es korrigiert? –
@DavidBrunelle Ich kann mich nicht erinnern, sorry. –
+1 große Antwort, obwohl das eine Tiefensuche zuerst ist, nicht eine Breite zuerst wie angegeben. – Cameron