Событие WPF C# PreviewDrop/Drop не запускается (с помощью dragadorner)
Я предполагаю, что предпросмотр / удаление событий происходит, когда он обнаруживает цель перетаскивания с элементом в качестве цели перетаскивания. В этом случае моя цель перетаскивания - это текстовое поле, а цель перетаскивания - метка. Оба они динамически создаются из БД. Я использую DragAdorner для клонирования перетаскиваемого элемента, до реализации DragAdorner мой DnD работает хорошо, но после того, как я использую dragadorner, он не будет работать. И я замечаю, что мое событие предварительного просмотра не запускается, когда я пытаюсь отладить.
Вот мои коды:
tbox.Drop += new DragEventHandler(tbox_PreviewDrop); // text box , Drop Target
tbox.DragOver += new DragEventHandler(tbox_DragOver);
Label lbl = new Label(); // Label , Drag Target
lbl.Content = s;
lbl.Width = Double.NaN;
lbl.Height = 40;
lbl.FontSize = 19;
lbl.PreviewMouseDown += new MouseButtonEventHandler(lbl_MouseDown);
lbl.PreviewMouseMove += new MouseEventHandler(lbl_MouseMove);
lbl.PreviewGiveFeedback += new GiveFeedbackEventHandler(lbl_GiveFeedback);
private void lbl_MouseDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(this);
// Mouse.OverrideCursor = Cursors.None;
}
private void lbl_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
// Mouse.OverrideCursor = Cursors.None;
var source = sender as UIElement;
Label lbl = sender as Label;
Point current = e.GetPosition(this);
Vector diff = startPoint - current;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
adorner = new DragAdorner(lbl, e.GetPosition(lbl));
AdornerLayer.GetAdornerLayer(lbl).Add(adorner);
var dragData = new DataObject(this);
DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy);
AdornerLayer.GetAdornerLayer(lbl).Remove(adorner);
}
startPoint = current;
}
}
private void lbl_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (adorner != null)
{
Label lbl = sender as Label;
var pos = lbl.PointFromScreen(GetMousePosition());
adorner.UpdatePosition(pos);
e.Handled = true;
}
}
private void tbox_PreviewDrop(object sender, DragEventArgs e)
{
(sender as TextBox).Text = string.Empty; // Empty the textbox from previous answer.
(sender as TextBox).Background = Brushes.White;
e.Effects = DragDropEffects.Move;
e.Handled = true;
}
private void tbox_DragOver(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.Move;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
public static Point GetMousePosition()
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}
private Point startPoint;
private DragAdorner adorner;
И файл класса Adorner:
public class DragAdorner : Adorner {
public DragAdorner(UIElement adornedElement, Point offset)
: base(adornedElement) {
this.offset = offset;
vbrush = new VisualBrush(AdornedElement);
//vbrush.Opacity = .7;
}
public void UpdatePosition(Point location) {
this.location = location;
this.InvalidateVisual();
}
protected override void OnRender(DrawingContext dc) {
var p = location;
p.Offset(-offset.X, -offset.Y);
dc.DrawRectangle(vbrush, null, new Rect(p, this.RenderSize));
}
private Brush vbrush;
private Point location;
private Point offset;
}
Я видел http://www.adorkable.us/books/wpf_control_development.pdf (стр. 103), но это слишком сложно для меня, так как я новичок.
Это из-за моего события GiveFeedBack, которое конфликтует с другими событиями?
2 ответа
Так как ваш DragAdorner
всегда находится под вашим курсором, это будет объект, получающий падение. Если вы установите IsHitTestVisible = false;
в конструкторе для Adorner
, это должно исправить это.
Даже если вы не установили AllowDrop
на Adorner
, поскольку он находится под курсором, он будет перехватывать попытку сброса. Но так как он не принимает сброс, он просто отменит его.
Обновить
Другая проблема заключается в том, что вы устанавливаете разрешенные эффекты в вашей операции перетаскивания на DragDropEffects.Copy
, но в DragOver
а также Drop
обработчики, вы пытаетесь сделать DragDropEffects.Move
, Это не будет работать, так как это не та же самая операция. Они должны совпадать. Если вы хотите включить обе операции при перетаскивании, вы можете указать обе с помощью побитового или:
DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy | DragDropEffects.Move);
Обновление 2
Если вы хотите отбросить что-либо кроме string
на TextBox
, вы должны использовать PreviewDrop
а также PreviewDragOver
События. В противном случае TextBox
Обработка по умолчанию игнорирует все остальное. Так это будет выглядеть так:
tbox.PreviewDrop += new DragEventHandler(tbox_PreviewDrop);
tbox.PreviewDragOver += new DragEventHandler(tbox_DragOver);
Попробуйте установить цвет фона для вашей этикетки и посмотрите, будет ли он работать правильно.