主题:
1.让我们拖拽吧!
2.什么,拖拽时还要缩略图?。。。
3.拖拽时的部件重叠(一个萝卜一个坑,请不要占我的坑)
引子:
BOSS:为啥你的程序不支持拖拽?
我:因为我不会拖拽。。。
BOSS:我每月给你的¥都TMD喂狗了啊。。。
上帝说:我要光,所以有了光。
BOSS说:我要拖拽,于是有了拖拽!
正文:
1.让我们拖拽吧!
话说,WPF,要实现拖拽还是比较简单的。
首先是素材,你得有个拖拽的容器,还要有一些拖拽的部件。
然后无非就是以下几个步骤。
对于想要拖拽的部件
(1)你先得给他弄上MouseMove and MouseLeftButtonDown事件
(2)你还得弄个DataObject包含你拖拽时的数据和你想要的效果
(3)然后调用DragDrop.DoDragDrop()吧
对于容器
(1)你要把它的AllowDrop 设置为true,这样你的容器才能被人随便的丢垃圾进去。
(2)当然,你还得加上DragEnter 事件,拖动进入了你的容器时会发生这个事件。
(3)最后,不要忘记加上DragDrop 事件,它会告诉你有某个部件被扔下来了。
好了,说了这么多,还是弄点代码上来吧。
我们自定义一些UserControl代表部件,容器就使用Canvas,因为Canvas能够很好的定位内部的部件位置。
下面是代码
Container的XMAL
Container XMAL
<Canvas Background="Silver" x:Name="container">
<component:Component x:Name="component1" Canvas.Top="30" Canvas.Left="30" PreviewMouseLeftButtonDown="component1_PreviewMouseLeftButtonDown" PreviewMouseMove="component1_PreviewMouseMove">
</component:Component>
</Canvas>
<component:Component x:Name="component1" Canvas.Top="30" Canvas.Left="30" PreviewMouseLeftButtonDown="component1_PreviewMouseLeftButtonDown" PreviewMouseMove="component1_PreviewMouseMove">
</component:Component>
</Canvas>
Component的XMAL
Component XMAL
<Border Background="Azure" BorderThickness="10" CornerRadius="5" BorderBrush="#FF8C4242">
<DockPanel Margin="10">
<TextBlock FontSize="20" FontWeight="Bold" FontStyle="Normal">
I am a container!
</TextBlock>
</DockPanel>
</Border>
<DockPanel Margin="10">
<TextBlock FontSize="20" FontWeight="Bold" FontStyle="Normal">
I am a container!
</TextBlock>
</DockPanel>
</Border>
主窗体CS文件
代码
this.container.AllowDrop = true;
this.container.DragEnter += new DragEventHandler((sender, e) =>
{
e.Effects = DragDropEffects.None;
}
);
this.container.Drop += new DragEventHandler((sender, e) =>
{
//get the object
var component = e.Data.GetData(typeof(Component)) as Component;
var endPoint = e.GetPosition(container);
//calculate the length of component moved
var moveX = endPoint.X - startPoint.X;
var moveY = endPoint.Y - startPoint.Y;
var x = Canvas.GetLeft(component) + moveX;
var y = Canvas.GetTop(component) + moveY;
Canvas.SetLeft(component, x);
Canvas.SetTop(component, y);
}
);
private Point startPoint;
private void component1_PreviewMouseMove(object sender, MouseEventArgs e)
{
// Get the current mouse position
Point mousePos = e.GetPosition(null);
Vector diff = startPoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
// Initialize the drag & drop operation
var component = sender as Component;
DataObject obj = new DataObject(typeof(Component), component);
DragDrop.DoDragDrop(component, obj, DragDropEffects.All);
}
}
private void component1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(container);
}
this.container.DragEnter += new DragEventHandler((sender, e) =>
{
e.Effects = DragDropEffects.None;
}
);
this.container.Drop += new DragEventHandler((sender, e) =>
{
//get the object
var component = e.Data.GetData(typeof(Component)) as Component;
var endPoint = e.GetPosition(container);
//calculate the length of component moved
var moveX = endPoint.X - startPoint.X;
var moveY = endPoint.Y - startPoint.Y;
var x = Canvas.GetLeft(component) + moveX;
var y = Canvas.GetTop(component) + moveY;
Canvas.SetLeft(component, x);
Canvas.SetTop(component, y);
}
);
private Point startPoint;
private void component1_PreviewMouseMove(object sender, MouseEventArgs e)
{
// Get the current mouse position
Point mousePos = e.GetPosition(null);
Vector diff = startPoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
// Initialize the drag & drop operation
var component = sender as Component;
DataObject obj = new DataObject(typeof(Component), component);
DragDrop.DoDragDrop(component, obj, DragDropEffects.All);
}
}
private void component1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(container);
}
搞定!
总结:至于什么ListView,TreeView的拖拽也都大同小异,无非就是拖拽的部件和容器变化。
可以参考这个文章
http://www.codeproject.com/KB/WPF/WpfDragAndDropSmorgasbord.aspx