编写拖放装饰器的辅助方法

This commit is contained in:
zengwenjie
2025-09-18 18:03:00 +08:00
parent ed1f451121
commit 83fbda7f6d
3 changed files with 122 additions and 9 deletions

View File

@@ -729,14 +729,7 @@ namespace Deedy.Activity
if (eventSource is not ActionViewer && eventSource is DependencyObject dobj && this == dobj.FindAncestor<ActionViewer>()) result = true;
return result;
}
protected virtual void RemoveDragAdorner()
{
//TODO移除拖拽装饰器
}
protected virtual void UpdateDragAdorner(Dock? dock)
{
//TODO更新拖拽装饰器
}
#region
protected override void OnDragEnter(DragEventArgs e)
{
@@ -904,7 +897,7 @@ namespace Deedy.Activity
/// 节点被选中
/// </summary>
/// <remarks>
/// 节点被选中:当视图节点被选中时发生
/// 当视图节点被选中时发生
/// </remarks>
public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble,
typeof(EventHandler<RoutedEventArgs>), typeof(ActionViewer));

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace Deedy.Activity
{
public class DragPlacementAdorner : Adorner
{
private static readonly Pen _PrevPen;
private static readonly Pen _NextPen;
private static readonly Pen _PartPen;
public Dock? Position { get; private set; }
static DragPlacementAdorner()
{
// 定义装饰器的画笔
_PrevPen = new Pen(Brushes.Red, 5.0);
_PrevPen.Freeze();
_NextPen = new Pen(Brushes.Red, 5.0);
_NextPen.Freeze();
_PartPen = new Pen(Brushes.Blue, 3.0);
_PartPen.Freeze();
}
public DragPlacementAdorner(UIElement adornedElement, Dock? dock) : base(adornedElement)
{
this.Position = dock;
IsHitTestVisible = false;
}
protected override void OnRender(DrawingContext drawingContext)
{
var adornedElementRect = new Rect(AdornedElement.RenderSize);
// 根据位置信息绘制不同的视觉效果
switch (this.Position)
{
case Dock.Top:
drawingContext.DrawLine(_PrevPen,
new Point(0, 0),
new Point(adornedElementRect.Right, 0));
break;
case Dock.Bottom:
drawingContext.DrawLine(_NextPen,
new Point(0, adornedElementRect.Bottom),
new Point(adornedElementRect.Right, adornedElementRect.Bottom));
break;
case Dock.Left:
drawingContext.DrawLine(_PrevPen,
new Point(0, 0),
new Point(0, adornedElementRect.Bottom));
break;
case Dock.Right:
drawingContext.DrawLine(_NextPen,
new Point(adornedElementRect.Right, 0),
new Point(adornedElementRect.Right, adornedElementRect.Bottom));
break;
case null:
drawingContext.DrawRectangle(null, _PartPen, adornedElementRect);
break;
default: break;
}
}
}
}

View File

@@ -7,6 +7,9 @@ using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Collections.Concurrent;
namespace Deedy.Activity
{
@@ -299,5 +302,51 @@ namespace Deedy.Activity
}
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_ParentElement")]
private static extern void ActionSetter_ParentElement(BasalAction action, IElement? value);
/// <summary>
/// 拖放装饰层的集合
/// </summary>
private readonly static ConcurrentDictionary<UIElement, AdornerLayer> AdornerLayers = new();
/// <summary>
/// 拖放装饰器的集合
/// </summary>
private readonly static ConcurrentDictionary<UIElement, DragPlacementAdorner> DragAdorners = new();
/// <summary>
/// 移除一个「UIElement」上的拖放装饰器
/// </summary>
/// <param name="viewer">目标「UIElement」对象</param>
public static void RemoveDragAdorner(this UIElement viewer)
{
if (viewer is null) return;
AdornerLayers.Remove(viewer, out var _AdornerLayer);
DragAdorners.Remove(viewer, out var _DragAdorner);
if (_AdornerLayer != null && _DragAdorner != null)
_AdornerLayer.Remove(_DragAdorner);
if (_AdornerLayer != null) _AdornerLayer = null;
if (_DragAdorner != null) _DragAdorner = null;
}
/// <summary>
/// 更新一个「UIElement」上的拖放装饰器
/// </summary>
/// <param name="viewer">目标「UIElement」对象</param>
/// <param name="dock">画线位置「null」表示画4面框线</param>
public static void UpdateDragAdorner(this UIElement viewer, Dock? dock)
{
if (viewer is null) return;
AdornerLayers.Remove(viewer, out var _AdornerLayer);
DragAdorners.Remove(viewer, out var _DragAdorner);
if (_AdornerLayer != null && _DragAdorner != null)
_AdornerLayer.Remove(_DragAdorner);
_AdornerLayer ??= AdornerLayer.GetAdornerLayer(viewer);
if (_AdornerLayer is null) return;
_DragAdorner = new DragPlacementAdorner(viewer, dock);
_AdornerLayer.Add(_DragAdorner);
AdornerLayers.TryAdd(viewer, _AdornerLayer);
DragAdorners.TryAdd(viewer, _DragAdorner);
}
}
}