我希望允许用户顺利地在Grid控件周围拖动自定义控件,而且我不确定我到底错过了什么。所有控件都将AllowDrop
设置为true。
在MouseMove
上,我在正在拖动的控件中执行以下操作:
DataObject dataObj = new DataObject("PersistentObject",this);
DragDrop.DoDragDrop(this, dataObj, DragDropEffects.Move);
DragEnter
,DragOver
和DragDrop
事件中,我将DragEventArg
的效果设置为全部。反馈显示网格上的新位置是一个有效的放置目标,但似乎永远不会移动。
有没有办法在网格上执行此操作,或者我尝试在错误的控件上执行此操作(我使用的是网格,因为设计人员开始使用网格)?
是否有其他事件需要修复,和/或我现有的事件是否已损坏?
编辑:如果它显示正在发生的控件被拖动,也会受到赞赏。我不确定我的当前方法是否应该发生这种情况,但这就是目标。
答案 0 :(得分:2)
使用内置的拖放功能,您可以轻松地执行 。
Point mouseOffset = new Point();
userControl.PreviewMouseLeftButtonDown += (sender, e) =>
{
mouseOffset = Mouse.GetPosition(userControl);
userControl.CaptureMouse();
};
userControl.PreviewMouseMove += (sender, e) =>
{
if (userControl.IsMouseCaptured)
{
Point mouseDelta = Mouse.GetPosition(userControl);
mouseDelta.Offset(-mouseOffset.X, -mouseOffset.Y);
userControl.Margin = new Thickness(
userControl.Margin.Left + mouseDelta.X,
userControl.Margin.Top + mouseDelta.Y,
userControl.Margin.Right - mouseDelta.X,
userControl.Margin.Bottom - mouseDelta.Y);
}
};
userControl.PreviewMouseLeftButtonUp += (sender, e) =>
{
userControl.ReleaseMouseCapture();
};
所以我为此编写的演示代码如下所示:
<Window x:Class="StackOverflowScratchpad.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="350"
Width="525">
<Grid>
<!-- I am using a Button here just for simplicity. The code
will function the same no matter what control is used. -->
<Button x:Name="userControl" Width="75" Height="23" />
</Grid>
</Window>
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object obj, RoutedEventArgs args)
{
// Add the above C# here.
}
答案 1 :(得分:1)
我建议使用Canvas控件。下面是一个示例Canvas控件,您放入其中的任何内容都将允许用户拖动以及调整大小:
不是原始代码不是我的,虽然我对它做了一些修改,这是我在网上找到的东西。 (我很乐意在这里引用消息来源,但不幸的是,我很久以前就被遗忘了。)
希望这会有所帮助,或者至少指出你正确的方向指向你。
<强> SuperCanvas:强>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using Meld.Helpers;
namespace Meld.Controls
{
public class SuperCanvas : Canvas
{
private AdornerLayer aLayer;
private bool isDown;
private bool isDragging;
private double originalLeft;
private double originalTop;
private bool selected;
private UIElement selectedElement;
private Point startPoint;
private bool locked;
public SuperCanvas()
{
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
MouseLeftButtonDown += WorkspaceWindow_MouseLeftButtonDown;
MouseLeftButtonUp += DragFinishedMouseHandler;
MouseMove += WorkspaceWindow_MouseMove;
MouseLeave += Window1_MouseLeave;
PreviewMouseLeftButtonDown += myCanvas_PreviewMouseLeftButtonDown;
PreviewMouseLeftButtonUp += DragFinishedMouseHandler;
}
// Handler for drag stopping on leaving the window
private void Window1_MouseLeave(object sender, MouseEventArgs e)
{
StopDragging();
e.Handled = true;
}
// Handler for drag stopping on user choice
private void DragFinishedMouseHandler(object sender, MouseButtonEventArgs e)
{
StopDragging();
e.Handled = true;
}
// Method for stopping dragging
private void StopDragging()
{
if (isDown)
{
isDown = false;
isDragging = false;
}
}
// Hanler for providing drag operation with selected element
private void WorkspaceWindow_MouseMove(object sender, MouseEventArgs e)
{
if (locked) return;
if (isDown)
{
if ((isDragging == false) &&
((Math.Abs(e.GetPosition(this).X - startPoint.X) >
SystemParameters.MinimumHorizontalDragDistance) ||
(Math.Abs(e.GetPosition(this).Y - startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
isDragging = true;
if (isDragging)
{
Point position = Mouse.GetPosition(this);
SetTop(selectedElement, position.Y - (startPoint.Y - originalTop));
SetLeft(selectedElement, position.X - (startPoint.X - originalLeft));
}
}
}
// Handler for clearing element selection, adorner removal
private void WorkspaceWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (locked) return;
if (selected)
{
selected = false;
if (selectedElement != null)
{
aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
selectedElement = null;
}
}
}
// Handler for element selection on the canvas providing resizing adorner
private void myCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//add code to lock dragging and dropping things.
if (locked)
{
e.Handled = true;
return;
}
// Remove selection on clicking anywhere the window
if (selected)
{
selected = false;
if (selectedElement != null)
{
// Remove the adorner from the selected element
aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
selectedElement = null;
}
}
// If any element except canvas is clicked,
// assign the selected element and add the adorner
if (e.Source != this)
{
isDown = true;
startPoint = e.GetPosition(this);
selectedElement = e.Source as UIElement;
originalLeft = GetLeft(selectedElement);
originalTop = GetTop(selectedElement);
aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
aLayer.Add(new ResizingAdorner(selectedElement));
selected = true;
e.Handled = true;
}
}
}
}
ResizingAdorner:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace Meld.Helpers
{
internal class ResizingAdorner : Adorner
{
// Resizing adorner uses Thumbs for visual elements.
// The Thumbs have built-in mouse input handling.
Thumb topLeft, topRight, bottomLeft, bottomRight;
// To store and manage the adorner's visual children.
VisualCollection visualChildren;
// Initialize the ResizingAdorner.
public ResizingAdorner(UIElement adornedElement) : base(adornedElement)
{
visualChildren = new VisualCollection(this);
// Call a helper method to initialize the Thumbs
// with a customized cursors.
BuildAdornerCorner(ref topLeft, Cursors.SizeNWSE);
BuildAdornerCorner(ref topRight, Cursors.SizeNESW);
BuildAdornerCorner(ref bottomLeft, Cursors.SizeNESW);
BuildAdornerCorner(ref bottomRight, Cursors.SizeNWSE);
// Add handlers for resizing.
bottomLeft.DragDelta += new DragDeltaEventHandler(HandleBottomLeft);
bottomRight.DragDelta += new DragDeltaEventHandler(HandleBottomRight);
topLeft.DragDelta += new DragDeltaEventHandler(HandleTopLeft);
topRight.DragDelta += new DragDeltaEventHandler(HandleTopRight);
}
// Handler for resizing from the bottom-right.
void HandleBottomRight(object sender, DragDeltaEventArgs args)
{
FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
Thumb hitThumb = sender as Thumb;
if (adornedElement == null || hitThumb == null) return;
FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;
// Ensure that the Width and Height are properly initialized after the resize.
EnforceSize(adornedElement);
// Change the size by the amount the user drags the mouse, as long as it's larger
// than the width or height of an adorner, respectively.
adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
}
// Handler for resizing from the top-right.
void HandleTopRight(object sender, DragDeltaEventArgs args)
{
FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
Thumb hitThumb = sender as Thumb;
if (adornedElement == null || hitThumb == null) return;
FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;
// Ensure that the Width and Height are properly initialized after the resize.
EnforceSize(adornedElement);
// Change the size by the amount the user drags the mouse, as long as it's larger
// than the width or height of an adorner, respectively.
adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
//adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
double height_old = adornedElement.Height;
double height_new = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
double top_old = Canvas.GetTop(adornedElement);
adornedElement.Height = height_new;
Canvas.SetTop(adornedElement, top_old - (height_new - height_old));
}
// Handler for resizing from the top-left.
void HandleTopLeft(object sender, DragDeltaEventArgs args)
{
FrameworkElement adornedElement = AdornedElement as FrameworkElement;
Thumb hitThumb = sender as Thumb;
if (adornedElement == null || hitThumb == null) return;
// Ensure that the Width and Height are properly initialized after the resize.
EnforceSize(adornedElement);
// Change the size by the amount the user drags the mouse, as long as it's larger
// than the width or height of an adorner, respectively.
//adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
//adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
double width_old = adornedElement.Width;
double width_new = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
double left_old = Canvas.GetLeft(adornedElement);
adornedElement.Width = width_new;
Canvas.SetLeft(adornedElement, left_old - (width_new - width_old));
double height_old = adornedElement.Height;
double height_new = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
double top_old = Canvas.GetTop(adornedElement);
adornedElement.Height = height_new;
Canvas.SetTop(adornedElement, top_old - (height_new - height_old));
}
// Handler for resizing from the bottom-left.
void HandleBottomLeft(object sender, DragDeltaEventArgs args)
{
FrameworkElement adornedElement = AdornedElement as FrameworkElement;
Thumb hitThumb = sender as Thumb;
if (adornedElement == null || hitThumb == null) return;
// Ensure that the Width and Height are properly initialized after the resize.
EnforceSize(adornedElement);
// Change the size by the amount the user drags the mouse, as long as it's larger
// than the width or height of an adorner, respectively.
//adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
double width_old = adornedElement.Width;
double width_new = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
double left_old = Canvas.GetLeft(adornedElement);
adornedElement.Width = width_new;
Canvas.SetLeft(adornedElement, left_old - (width_new - width_old));
}
// Arrange the Adorners.
protected override Size ArrangeOverride(Size finalSize)
{
// desiredWidth and desiredHeight are the width and height of the element that's being adorned.
// These will be used to place the ResizingAdorner at the corners of the adorned element.
double desiredWidth = AdornedElement.DesiredSize.Width;
double desiredHeight = AdornedElement.DesiredSize.Height;
// adornerWidth & adornerHeight are used for placement as well.
double adornerWidth = this.DesiredSize.Width;
double adornerHeight = this.DesiredSize.Height;
topLeft.Arrange(new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
topRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
bottomLeft.Arrange(new Rect(-adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));
bottomRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));
// Return the final size.
return finalSize;
}
// Helper method to instantiate the corner Thumbs, set the Cursor property,
// set some appearance properties, and add the elements to the visual tree.
void BuildAdornerCorner(ref Thumb cornerThumb, Cursor customizedCursor)
{
if (cornerThumb != null) return;
cornerThumb = new Thumb();
// Set some arbitrary visual characteristics.
cornerThumb.Cursor = customizedCursor;
cornerThumb.Height = cornerThumb.Width = 5;
cornerThumb.Opacity = 0.40;
cornerThumb.Background = new SolidColorBrush(Colors.White);
visualChildren.Add(cornerThumb);
}
// This method ensures that the Widths and Heights are initialized. Sizing to content produces
// Width and Height values of Double.NaN. Because this Adorner explicitly resizes, the Width and Height
// need to be set first. It also sets the maximum size of the adorned element.
void EnforceSize(FrameworkElement adornedElement)
{
if (adornedElement.Width.Equals(Double.NaN))
adornedElement.Width = adornedElement.DesiredSize.Width;
if (adornedElement.Height.Equals(Double.NaN))
adornedElement.Height = adornedElement.DesiredSize.Height;
FrameworkElement parent = adornedElement.Parent as FrameworkElement;
if (parent != null)
{
adornedElement.MaxHeight = parent.ActualHeight;
adornedElement.MaxWidth = parent.ActualWidth;
}
}
// Override the VisualChildrenCount and GetVisualChild properties to interface with
// the adorner's visual collection.
protected override int VisualChildrenCount { get { return visualChildren.Count; } }
protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
}
}
答案 2 :(得分:0)
你必须处理代码自己的Drop事件
Drop事件在对象作为放置目标的元素的边界内被删除时发生。
private void grid_Drop(object sender, DragEventArgs eventarg)
{
// check data is present returns a bool
if (eventarg.Data.GetDataPresent("PersistentObject"))
{
var yourdata=eventarg.Data.GetData("PersistentObject")as Model(T) ;
if (yourdata!= null)
{
// add to gird or whatever.
// place the object as you desire
}
}
一些拖放Reference
答案 3 :(得分:0)
几年前我创建了一个DragDropBehaviour类。您应该能够复制粘贴它,只需更改OnDrop功能即可。
public static class DragDropBehaviour
{
#region CanDrag attached dependancy property
/// <summary>
/// The CanDrag attached property'str name.
/// </summary>
public const string CanDragPropertyName = "CanDrag";
/// <summary>
/// Gets the value of the CanDrag attached property
/// for a given dependency object.
/// </summary>
/// <param name="obj">The object for which the property value
/// is read.</param>
/// <returns>The value of the CanDrag property of the specified object.</returns>
public static bool GetCanDrag(DependencyObject obj)
{
return (bool)obj.GetValue(CanDragProperty);
}
/// <summary>
/// Sets the value of the CanDrag attached property
/// for a given dependency object.
/// </summary>
/// <param name="obj">The object to which the property value
/// is written.</param>
/// <param name="value">Sets the CanDrag value of the specified object.</param>
public static void SetCanDrag(DependencyObject obj, bool value)
{
obj.SetValue(CanDragProperty, value);
}
/// <summary>
/// Identifies the CanDrag attached property.
/// </summary>
public static readonly DependencyProperty CanDragProperty = DependencyProperty.RegisterAttached(
CanDragPropertyName,
typeof(bool),
typeof(DragDropBehaviour),
new UIPropertyMetadata(false, OnCanDragChanged));
#endregion
#region CanDrop attached dependancy property
/// <summary>
/// The CanDrop attached property'str name.
/// </summary>
public const string CanDropPropertyName = "CanDrop";
/// <summary>
/// Gets the value of the CanDrop attached property
/// for a given dependency object.
/// </summary>
/// <param name="obj">The object for which the property value
/// is read.</param>
/// <returns>The value of the CanDrop property of the specified object.</returns>
public static bool GetCanDrop(DependencyObject obj)
{
return (bool)obj.GetValue(CanDropProperty);
}
/// <summary>
/// Sets the value of the CanDrop attached property
/// for a given dependency object.
/// </summary>
/// <param name="obj">The object to which the property value
/// is written.</param>
/// <param name="value">Sets the CanDrop value of the specified object.</param>
public static void SetCanDrop(DependencyObject obj, bool value)
{
obj.SetValue(CanDropProperty, value);
}
/// <summary>
/// Identifies the CanDrop attached property.
/// </summary>
public static readonly DependencyProperty CanDropProperty = DependencyProperty.RegisterAttached(
CanDropPropertyName,
typeof(bool),
typeof(DragDropBehaviour),
new UIPropertyMetadata(false, OnCanDropChanged));
#endregion
#region DragDropAction attached dependancy property
/// <summary>
/// The DragDropAction attached property'str name.
/// </summary>
public const string DragDropActionPropertyName = "DragDropAction";
/// <summary>
/// Gets the value of the DragDropAction attached property
/// for a given dependency object.
/// </summary>
/// <param name="obj">The object for which the property value
/// is read.</param>
/// <returns>The value of the DragDropAction property of the specified object.</returns>
public static DragDropAction GetDragDropAction(DependencyObject obj)
{
return (DragDropAction)obj.GetValue(DragDropActionProperty);
}
/// <summary>
/// Sets the value of the DragDropAction attached property
/// for a given dependency object.
/// </summary>
/// <param name="obj">The object to which the property value
/// is written.</param>
/// <param name="value">Sets the DragDropAction value of the specified object.</param>
public static void SetDragDropAction(DependencyObject obj, DragDropAction value)
{
obj.SetValue(DragDropActionProperty, value);
}
/// <summary>
/// Identifies the DragDropAction attached property.
/// </summary>
public static readonly DependencyProperty DragDropActionProperty = DependencyProperty.RegisterAttached(
DragDropActionPropertyName,
typeof(DragDropAction),
typeof(DragDropBehaviour),
new UIPropertyMetadata(null));
#endregion
static void OnCanDragChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = depObj as FrameworkElement;
if (element != null)
{
if ((bool)e.NewValue)
{
GetOrCreateAction(depObj).DragBehaviour(element, true);
}
else
{
GetOrCreateAction(depObj).DragBehaviour(element, false);
}
}
}
static void OnCanDropChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = depObj as FrameworkElement;
if (element != null)
{
if ((bool)e.NewValue)
{
GetOrCreateAction(depObj).DropBehaviour(element, true);
}
else
{
GetOrCreateAction(depObj).DropBehaviour(element, false);
}
}
}
static DragDropAction GetOrCreateAction(DependencyObject depObj)
{
DragDropAction action = depObj.GetValue(DragDropActionProperty) as DragDropAction;
if (action == null)
{
action = new DragDropAction();
depObj.SetValue(DragDropActionProperty, action);
}
return action;
}
}
public class DragDropAction
{
Point _start;
FrameworkElement _dragged;
public void DragBehaviour(FrameworkElement element, bool enable)
{
if (enable)
{
element.PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown;
element.PreviewMouseMove += OnPreviewMouseMove;
}
else
{
element.PreviewMouseLeftButtonDown -= OnPreviewMouseLeftButtonDown;
element.PreviewMouseMove -= OnPreviewMouseMove;
}
}
public void DropBehaviour(FrameworkElement element, bool enable)
{
if (enable)
{
element.Drop += OnDrop;
element.AllowDrop = true;
}
else
{
element.Drop -= OnDrop;
element.AllowDrop = false;
}
}
void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null)
{
int[] position = Win32Mouse.GetMousePosition();
_start = new Point(position[0], position[1]);
_dragged = element;
}
}
void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null && _dragged != null)
{
int[] position = Win32Mouse.GetMousePosition();
Point currentPosition = new Point(position[0], position[1]);
Vector diff = _start - currentPosition;
if (e.LeftButton == MouseButtonState.Pressed &&
Math.Abs(diff.X) > (SystemParameters.MinimumHorizontalDragDistance) &&
Math.Abs(diff.Y) > (SystemParameters.MinimumVerticalDragDistance))
{
DragDropEffects effects = DragDrop.DoDragDrop(element, _dragged.DataContext, DragDropEffects.Move);
_dragged = null;
e.Handled = true;
}
}
}
void OnDrop(object sender, DragEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null)
{
TabViewModel tab = element.DataContext as TabViewModel;
if (tab == null)
{
// TabViewModel not found it element, it's possible that the drop was done on the lastOpened 'Canvas' element.
var tabControls = element.FindVisualChildren<TabControl>();
var menus = element.FindVisualChildren<Menu>();
var itemControls = element.FindVisualChildren<ItemsControl>();
if (tabControls.Count > 0 && tabControls[0].Visibility == Visibility.Visible)
{
// If currently in 'horizontal mode' add to the active tab. If there is no active tab
// just add to the bottom tab.
tab = tabControls[0].SelectedItem as TabViewModel;
if (tab == null)
tab = tabControls[0].Items.GetItemAt(tabControls[0].Items.Count - 1) as TabViewModel;
}
else if (menus.Count > 0 && menus[0].Visibility == Visibility.Visible)
{
// If currently in 'vertical mode' add to the default tab, there is no 'active' menu item after all.
var tabs = menus[0].Items.SourceCollection as ObservableCollection<TabViewModel>;
tab = tabs.SingleOrDefault(obj => obj.Title == Configuration.DefaultTab) ?? tabs.LastOrDefault();
}
else if (itemControls.Count > 0 && itemControls[0].Visibility == Visibility.Visible)
{
var window = element.FindVisualParent<Window>();
if (window != null && window.DataContext is MainViewModel)
{
// Add the currently expanded tab.
MainViewModel mainViewModel = (MainViewModel)window.DataContext;
tab = mainViewModel.ExpandedTab;
// If no tab is expanded, add to the default tab or the bottom tab.
if (tab == null)
{
tab = mainViewModel.Tabs.SingleOrDefault(obj => obj.Title == Configuration.DefaultTab)
?? mainViewModel.Tabs.LastOrDefault();
}
}
}
}
if (tab != null)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() =>
{
string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string fileName in droppedFilePaths)
{
try
{
ApplicationModel model = ApplicationModel.FromFile(fileName, tab.Title);
ApplicationViewModel application = new ApplicationViewModel(model);
Messenger.Default.Send<ApplicationMessage>(ApplicationMessage.Add(application, tab));
}
catch (FileNotFoundException ex)
{
ServiceManager.GetService<IMessageBoxService>().Show(
"Could not add application - " + ex.Message, "Astounding Dock", MessageIcon.Error);
}
}
}));
e.Handled = true;
}
else if (e.Data.GetDataPresent<ApplicationViewModel>())
{
DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() =>
{
ApplicationViewModel application = e.Data.GetData<ApplicationViewModel>();
Messenger.Default.Send<ApplicationMessage>(ApplicationMessage.Move(application, tab));
}));
e.Handled = true;
}
else
{
Debug.WriteLine("DragDropBehaviour: Unknown data droppped - " + String.Join(",", e.Data.GetFormats()));
}
}
}
}
}
https://github.com/notsonormal/AstoundingDock/blob/master/src/AstoundingDock/Ui/DragDropBehaviour.cs
您可以启用像
这样的控件上的删除功能<Canvas ui:DragDropBehaviour.CanDrop="True">
</Canvas>
并启用这样的拖放
<Button ui:DragDropBehaviour.CanDrag="True" ui:DragDropBehaviour.CanDrop="True">
</Button>
https://github.com/notsonormal/AstoundingDock/blob/master/src/AstoundingDock/Views/MainWindow.xaml
看起来非常通用,但我只是将它用于一个特定情况,所以......