Как перерисовать линию на место перетаскивания библиотеки gong-wpf-dragdrop
Использую библиотеку gong-wpf-dragdrop для перетаскивания элементов. В место перетаскивания элемента отображается дефолтная линия, сероватого цвета и треугольники по бокам.
Можно ли как-то перерисовать линию, чтобы она была определенных размеров, цвета и т.п.
Как поменять цвет я знаю, но как отрисовать ее размер, убрать треугольники найти не могу.
Ответы (1 шт):
Автор решения: Voenkomat
→ Ссылка
Нашел как сделать свою линию. Нужен класс.
public class CustomInsertAdorner : DropTargetAdorner
{
private double _animationOffset = 0;
private bool _increasing = true;
public CustomInsertAdorner(UIElement adornedElement, IDropInfo dropInfo) : base(adornedElement, dropInfo)
{
CompositionTarget.Rendering += OnRendering;
}
private void OnRendering(object sender, EventArgs e)
{
if (_increasing)
{
_animationOffset += 0.3;
if (_animationOffset >= 3)
_increasing = false;
}
else
{
_animationOffset -= 0.3;
if (_animationOffset <= 0)
_increasing = true;
}
InvalidateVisual();
}
protected override void OnRender(DrawingContext dc)
{
var items = DropInfo.VisualTarget as ItemsControl;
if (items == null || items.Items.Count == 0)
return;
int index = DropInfo.InsertIndex;
double y;
if (index == 0)
{
var first = items.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement;
if (first != null)
{
var transform = first.TransformToVisual(AdornedElement);
var pos = transform.Transform(new Point(0, 0));
y = pos.Y;
}
else
{
y = 0;
}
}
else if (index >= items.Items.Count)
{
var last = items.ItemContainerGenerator.ContainerFromIndex(items.Items.Count - 1) as FrameworkElement;
if (last != null)
{
var transform = last.TransformToVisual(AdornedElement);
var pos = transform.Transform(new Point(0, 0));
y = pos.Y + last.ActualHeight;
}
else
{
y = items.RenderSize.Height;
}
}
else
{
var container = items.ItemContainerGenerator.ContainerFromIndex(index) as FrameworkElement;
if (container != null)
{
var transform = container.TransformToVisual(AdornedElement);
var pos = transform.Transform(new Point(0, 0));
y = pos.Y;
}
else
{
y = 0;
}
}
DrawAnimatedLineWithBubble(dc, y, index, AdornedElement.RenderSize.Width);
}
private void DrawAnimatedLineWithBubble(DrawingContext dc, double y, int index, double width)
{
var pen = new Pen(Brushes.Red, 2 + _animationOffset)
{
DashStyle = DashStyles.Dash
};
dc.DrawLine(pen, new Point(0, y), new Point(width, y));
string text = index.ToString();
var ft = new FormattedText(text, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Segoe UI"), 12, Brushes.White, VisualTreeHelper.GetDpi(AdornedElement).PixelsPerDip);
double bubbleRadius = Math.Max(ft.Width, ft.Height) + 6;
double bubbleX = width - bubbleRadius - 5;
double bubbleY = y - bubbleRadius / 2;
dc.DrawEllipse(Brushes.Red, null, new Point(bubbleX + bubbleRadius / 2, bubbleY + bubbleRadius / 2), bubbleRadius / 2, bubbleRadius / 2);
dc.DrawText(ft, new Point(bubbleX + bubbleRadius / 2 - ft.Width / 2, bubbleY + bubbleRadius / 2 - ft.Height / 2));
}
}
Логику можно любую сделать, тут как бы пульсация
И нужен Хэндлер:
public class MyDragHandler : IDragSource, IDropTarget
{
readonly Action<bool> _setDraggingState;
public MyDragHandler()
{
}
public MyDragHandler(Action<bool> setDraggingState) => _setDraggingState = setDraggingState;
public bool CanStartDrag(IDragInfo dragInfo)
{
var src = Mouse.DirectlyOver as DependencyObject;
var btn = FindParent<Button>(src);
return btn?.Name == "DragButton";
}
public void StartDrag(IDragInfo dragInfo)
{
dragInfo.Data = dragInfo?.SourceItem;
dragInfo.Effects = DragDropEffects.Move;
_setDraggingState?.Invoke(true);
}
public void DragCancelled() => _setDraggingState?.Invoke(false);
public void Dropped(IDropInfo dropInfo) => _setDraggingState?.Invoke(false);
public void DragDropOperationFinished(DragDropEffects op, IDragInfo info) => _setDraggingState?.Invoke(false);
public bool TryCatchOccurredException(Exception exception) => false;
public void DragOver(IDropInfo dropInfo)
{
dropInfo.Effects = DragDropEffects.Move;
dropInfo.DropTargetAdorner = typeof(CustomInsertAdorner);
}
public void Drop(IDropInfo dropInfo) => GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.Drop(dropInfo);
static T FindParent<T>(DependencyObject child)
where T : DependencyObject
{
while (child != null)
{
if (child is T t)
return t;
child = VisualTreeHelper.GetParent(child);
}
return null;
}
}
Определяем в ресурсах окна/uc
handler:MyDragHandler x:Key="MyDragHandler"/>
Хэндлер цепляем к своем контролу где лежат элементы так:
dd:DragDrop.DragHandler="{StaticResource MyDragHandler}"
dd:DragDrop.DropHandler="{StaticResource MyDragHandler}"