现在想要把一个项目从FromBox拖拽到ToBox。可以像往常一样,在代码中对围绕着索引和移动规则等进行调整。但现在我们可以应用工具箱中的新功能,添加System.Windows.Controls.Toolkit应用调用MainPage.xaml中的复合命名即可。代码如下:
<UserControl x:Class="SilverlightApplication105.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
xmlns:mswindows="clr-namespace:Microsoft.Windows;assembly=System.Windows.Controls.Toolkit">
<Grid x:Name="LayoutRoot">
<StackPanel Orientation="Horizontal" Margin="10">
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName"/>
<ListBox Width="200" Height="500" x:Name="ToBox" DisplayMemberPath="FullName"/>
</StackPanel>
</Grid>
</UserControl>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
xmlns:mswindows="clr-namespace:Microsoft.Windows;assembly=System.Windows.Controls.Toolkit">
<Grid x:Name="LayoutRoot">
<StackPanel Orientation="Horizontal" Margin="10">
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName"/>
<ListBox Width="200" Height="500" x:Name="ToBox" DisplayMemberPath="FullName"/>
</StackPanel>
</Grid>
</UserControl>
<StackPanel Orientation="Horizontal" Margin="10">
<toolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True">
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName"/>
</toolkit:ListBoxDragDropTarget>
<toolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True">
<ListBox Width="200" Height="500" x:Name="ToBox" DisplayMemberPath="FullName"/>
</toolkit:ListBoxDragDropTarget>
</StackPanel>
<toolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True">
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName"/>
</toolkit:ListBoxDragDropTarget>
<toolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True">
<ListBox Width="200" Height="500" x:Name="ToBox" DisplayMemberPath="FullName"/>
</toolkit:ListBoxDragDropTarget>
</StackPanel>
之后,当运行这个应用的时候,就可以将菜单中的项目拖来拖去了。在拖动过程中,项目呈现半透明状。

图1 演示效果
不仅如此,还可以对列表项的顺序进行重排,也就是说一个ListBox同时可以是拖动的起点和终点。不过,ListBoxDragDropTarget并不能作用于virtualized容器(ListBox默认容器)。所以必须改变ListBox的ItemsPanelTemplate,比如说像这样加个StackPanel进去:
<toolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True">
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</toolkit:ListBoxDragDropTarget>
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</toolkit:ListBoxDragDropTarget>
现在就可以通过drag/drop行为对ListBox中的项目进行重新排列了。

图2 通过鼠标重新排列
非常棒的是!它支持任意的DataTemplate。比如在Person类中增加一个Image属性,并将其作用于控件的template,仍然可以进行拖拽操作。

图3 支持任意的DataTemplate
除了ListBoxDragDropTarget外,还有以下控件:
ListBoxDragDropTarget
TreeViewDragDropTarget
DataGridDragDropTarget
DataPointSeriesDragDropTarget