我有一个包含许多按钮的 Stackpanel,那么如何像 Expression Blend 或“Visual Studio Xaml Window Designer”那样通过拖放按钮来重新排序按钮
此线程提供了一些有用的信息。尽管如此,您可以通过搜索找到很多资源,这些资源将提供大量这方面的信息。
我正在开发一个可排列的堆栈面板,当我触摸或按下该项目并释放鼠标并移动堆栈面板中的对象或子对象时,它会粘在它上面。我的代码如下。
namespace Controls.ArrangableGrid
{
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;
public class ArrangableControl : StackPanel
{
#region - Variables -
private bool _isDown;
private bool _isDragging;
private Point _startPoint;
private DragAdorner _adorner;
private UIElement _draggedItem = null;
private int _draggedItemIndex = -1;
private ILoggingService _logging = null;
private ILogger _logger;
private CypherComponentModel _parentComponent = null;
#endregion
public ArrangableControl()
{
Orientation = Orientation.Horizontal;
Background = Brushes.Transparent;
if (!DesignerProperties.GetIsInDesignMode(this))
{
Loaded += OnLoaded;
}
}
#region - Functions -
private void SetEvetns()
{
AllowDrop = true;
Drop += OnDrop;
StylusDown += OnEventDown;
StylusUp += OnEventUp;
StylusMove += OnEventMove;
MouseLeftButtonDown += OnEventDown;
MouseLeftButtonUp += OnEventUp;
MouseMove += OnEventMove;
}
private Point GetPosition(InputEventArgs e, IInputElement obj)
{
if (e is MouseEventArgs)
{
Mouse.Capture(obj);
return (e as MouseEventArgs).GetPosition(obj);
}
else if (e is TouchEventArgs)
{
(e as TouchEventArgs).TouchDevice.Capture(obj);
return (e as TouchEventArgs).GetTouchPoint(obj).Position;
}
else if (e is StylusEventArgs)
{
Stylus.Capture(obj);
return (e as StylusEventArgs).GetPosition(obj);
}
return new Point();
}
private void DragStarted()
{
if (_draggedItem == null) return;
_isDragging = true;
_adorner = new DragAdorner(_draggedItem);
var layer = AdornerLayer.GetAdornerLayer(_draggedItem);
layer.Add(_adorner);
}
private void DragMoved()
{
var currentPosition = Mouse.GetPosition(this);
_adorner.LeftOffset = currentPosition.X - _startPoint.X;
_adorner.TopOffset = currentPosition.Y - _startPoint.Y;
}
private void DragFinished(bool cancelled, InputEventArgs e)
{
this.ReleaseMouseCapture();
if (null != _adorner)
AdornerLayer.GetAdornerLayer(_adorner.AdornedElement).Remove(_adorner);
if (cancelled == false)
{
UIElement _dropItem = this.GetChildElement(GetPosition(e, this)) as UIElement;
if (null != _dropItem)
DragDrop.DoDragDrop(_draggedItem, new DataObject("UIElement", e.Source, true), DragDropEffects.Move);
}
_adorner = null;
_isDragging = false;
_isDown = false;
}
#endregion
#region - Events -
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (this.IsLoaded)
{
SetEvetns();
}
}
private void OnEventDown(object sender, InputEventArgs e)
{
if(e.Source != this)
{
_isDown = true;
_isDragging = false;
_startPoint = GetPosition(e, this);
_draggedItem = e.Source as UIElement;
if (null != _draggedItem)
_draggedItemIndex = this.Children.IndexOf(_draggedItem);
}
}
private void OnEventUp(object sender, InputEventArgs e)
{
if (_isDown && _isDragging)
{
DragFinished(false, e);
e.Handled = true;
}
else
{
e.Handled = true;
ReleaseMouseCapture();
ReleaseAllTouchCaptures();
ReleaseStylusCapture();
}
}
private void OnEventMove(object sender, InputEventArgs e)
{
if (_isDown)
{
if ((_isDragging == false) &&
((Math.Abs(GetPosition(e, this).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
(Math.Abs(GetPosition(e, this).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
DragStarted();
if (_isDragging)
DragMoved();
}
e.Handled = true;
}
private void OnDrop(object sender, DragEventArgs e)
{
try
{
UIElement droptarget = e.Source as UIElement;
int droptargetIndex = this.Children.IndexOf(droptarget);
if (_draggedItem != null && (droptargetIndex != _draggedItemIndex))
{
if (droptargetIndex != -1)
{
this.Children.Remove(_draggedItem);
this.Children.Insert(droptargetIndex, _draggedItem);
}
}
_draggedItem = null;
_draggedItemIndex = -1;
}
catch (Exception ex)
{
_logger.Error($"Drop Error: {ex} at {nameof(ArrangableControl)}");
}
finally
{
e.Handled = true;
ReleaseMouseCapture();
ReleaseAllTouchCaptures();
ReleaseStylusCapture();
}
}
#endregion
}
}