1、设置源控件和目标控件的AllowDrop=true
listBox1.AllowDrop = true;
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Name="grid">
<Image Source="{Binding}"/>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="lbi_PreviewMouseMove"/>
<EventSetter Event="ListBoxItem.QueryContinueDrag" Handler="lbi_QueryContinueDrag"/>
<EventSetter Event="ListBoxItem.GiveFeedback" Handler="lbi_GiveFeedback"/>
</Style>
2、源控件的PreviewMouseMove事件来控制拖动的数据以及效果
AdornerLayer mAdornerLayer = null;
void lbi_PreviewMouseMove(object sender, MouseEventArgs e)
{
ListBoxItem li = sender as ListBoxItem;
if (li != null && li.IsSelected)
{
DragDropAdorner adorner = new DragDropAdorner(li);(DragDropAdorner实现Adorner抽象类)
mAdornerLayer = AdornerLayer.GetAdornerLayer(grid);
mAdornerLayer.Add(adorner);
DataObject dob = new DataObject(li);
DragDrop.DoDragDrop(li, dob, DragDropEffects.Copy);//启动拖拽
mAdornerLayer.Remove(adorner);
}
}
public class DragDropAdorner : Adorner
{
public DragDropAdorner(UIElement parent)
: base(parent)
{
IsHitTestVisible = false; // Seems Adorner is hit test visible?
mDraggedElement = parent as FrameworkElement;
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
if (mDraggedElement != null)
{
Win32.POINT screenPos = new Win32.POINT();
if (Win32.GetCursorPos(ref screenPos))
{
Point pos = PointFromScreen(new Point(screenPos.X, screenPos.Y));
Rect rect = new Rect(pos.X, pos.Y, mDraggedElement.ActualWidth, mDraggedElement.ActualHeight);
drawingContext.PushOpacity(1.0);
Brush highlight = mDraggedElement.TryFindResource(SystemColors.HighlightBrushKey) as Brush;
if (highlight != null)
drawingContext.DrawRectangle(highlight, new Pen(Brushes.Transparent, 0), rect);
drawingContext.DrawRectangle(new VisualBrush(mDraggedElement),
new Pen(Brushes.Transparent, 0), rect);
drawingContext.Pop();
}
}
}
FrameworkElement mDraggedElement = null;
}
public static class Win32
{
public struct POINT { public Int32 X; public Int32 Y; }
// During drag-and-drop operations, the position of the mouse cannot be
// reliably determined through GetPosition. This is because control of
// the mouse (possibly including capture) is held by the originating
// element of the drag until the drop is completed, with much of the
// behavior controlled by underlying Win32 calls. As a workaround, you
// might need to use Win32 externals such as GetCursorPos.
[DllImport("user32.dll")]
public static extern bool GetCursorPos(ref POINT point);
}
3、目标控件接收数据,使用DragDrop.Drop事件(以Button为例DragDrop.Drop="button1_Drop")
private void button1_Drop(object sender, DragEventArgs e)
{
Point p = e.GetPosition(button1);
HitTestResult result = VisualTreeHelper.HitTest(button1, p);
if (result == null)
return ;
ListBoxItem li=e.Data.GetData(typeof(ListBoxItem)) as ListBoxItem;
}
注:参见http://www.cnblogs.com/loveis715/archive/2011/12/05/2277384.html