Der Beispielcode, den ich unten zur Verfügung stelle, zeigt, dass das StackPanel-Steuerelement das Objekt prüft, das verschoben wird, um festzustellen, ob es sich in einem bestimmten Abstand zu einem anderen Objekt befindet und dieses Objekt verschiebt. Ein einfacher Test des folgenden Codes zeigt, dass es nicht möglich ist, ein Objekt so zu ziehen, dass es sich mit einem anderen überlappt, und es ist nicht möglich, ein Objekt so zu ziehen, dass es nicht an einem anderen anliegt. Die Funktionalität, die es dem Benutzer ermöglicht, ein Objekt ... an den Rand eines anderen zu fangen, wird von der WPF-Bibliothek und genauer vom StackPanel-Steuerelement bereitgestellt. Im Geiste der allgemeinen Natur der Frage des OP werde ich auch darauf hinweisen, dass WPF eine robuste Bibliothek von Steuerelementen und Funktionen bietet, die es dem Entwickler erlauben, die Nähe eines Steuerelements zu einem anderen zu testen und Objekte nach Belieben anzuordnen Verwenden von speziellen Containern wie Grid, Canvas und StackPanel.
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private bool _isDown;
private bool _isDragging;
private Point _startPoint;
private UIElement _realDragSource;
private UIElement _dummyDragSource = new UIElement();
private void sp_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.Source != this.sp)
{
_isDown = true;
_startPoint = e.GetPosition(this.sp);
}
}
private void sp_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_isDown = false;
_isDragging = false;
_realDragSource.ReleaseMouseCapture();
}
private void sp_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (_isDown)
{
if ((! _isDragging) && ((Math.Abs(e.GetPosition(this.sp).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
(Math.Abs(e.GetPosition(this.sp).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
{
_isDragging = true;
_realDragSource = e.Source as UIElement;
_realDragSource.CaptureMouse();
DragDrop.DoDragDrop(_dummyDragSource, new DataObject("UIElement", e.Source, true), DragDropEffects.Move);
}
}
}
private void sp_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("UIElement"))
e.Effects = DragDropEffects.Move;
}
private void sp_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("UIElement"))
{
UIElement droptarget = e.Source as UIElement;
int droptargetIndex = -1, i = 0;
foreach (UIElement element in this.sp.Children)
{
if (element.Equals(droptarget))
{
droptargetIndex = i;
break;
}
i++;
}
if (droptargetIndex != -1)
{
this.sp.Children.Remove(_realDragSource);
this.sp.Children.Insert(droptargetIndex, _realDragSource);
}
_isDown = false;
_isDragging = false;
_realDragSource.ReleaseMouseCapture();
}
}
}
MainWindow.xaml
<Window x:Class="DragShapes.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Border Background="Red">
<StackPanel Name="sp" AllowDrop="True" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"
PreviewMouseLeftButtonDown="sp_PreviewMouseLeftButtonDown"
PreviewMouseLeftButtonUp="sp_PreviewMouseLeftButtonUp"
PreviewMouseMove="sp_PreviewMouseMove"
DragEnter="sp_DragEnter" Drop="sp_Drop">
<Rectangle Height="80" Width="100" Fill="SkyBlue" />
<Rectangle Height="110" Width="90" Fill="LightGreen" />
<Rectangle Height="60" Width="60" Fill="Violet" />
</StackPanel>
</Border>
</Window>
Haben Sie XAML/WPF/UWP untersucht? – Sam
Kurz - ich gehe zurück und schaue sie mir genauer an, danke! – DSGD
Ich würde die Lösung in der referenzierten Antwort kaum als "relativ einfach" bezeichnen. Oder alternativ, da Sie in jeder grafischen API, die Sie verwenden, etwas Ähnliches tun müssten, wenn Sie das für "relativ einfach" halten, ist es in jeder API relativ einfach. Die JavaScript-Sprache bietet dies nicht "out of the box" und auch keine der grafischen APIs, die häufig mit C# verwendet werden, sei es Winforms, WPF, Winrt, Xamarin oder was auch immer. Sobald Sie eine grafische API kennen, sollten Sie in der Lage sein, die grundlegende Technik anzuwenden, die sich in dem JavaScript-Code befindet, den Sie bereits gefunden haben. –