v2010.1 has a new undocumented drag and drop library that is used internally by our controls. The code for it lives in DevExpress.Xpf.Core and is abstract enough to be reused. If you need drag and drop support in your Silverlight apps, please download the DevExpress.Xpf.Core.Extensions from http://community.devexpress.com/files/folders/samples/entry302886.aspx.
To setup a drag source all you have to do is set the Allow Drag property on your control. For example to drag from a ListBox
xmlns:dnd="clr-namespace:DevExpress.Xpf.Core.DragAndDrop;assembly=DevExpress.Xpf.Core.Extensions.v10.1"
<ListBox Name="listBox1" dnd:DragAndDropManager.AllowDrag="True">
</ListBox>
When
AllowDrag is set, a default drag cursor

will be provided for the drag operations. We can control that by registering a custom
IDragAndDropHandler for our source.
// Provides app level feedback to the Drag and Drop manager
public interface IDragAndDropHandler {
bool CanStartDrag(UIElement source, MouseButtonEventArgs e, ref object dragData);
FrameworkElement CreateDragThumb(UIElement source, UIElement target, object dragData);
}
To setup a drop target, set the AllowDrop for your target element and implement DragOver, DragLeave and Drop events. In this events, you will receive the drag source and the associated drag data so that you can respond appropriately.
An example of drag and drop between ListBox controls with a custom drag cursor:
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListBox Name="listBox1" dnd:DragAndDropManager.AllowDrag="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"></Image>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Name="listBox2" Grid.Column="2"
dnd:DragAndDropManager.AllowDrop="True"
dnd:DragAndDropManager.DragLeave="ListBox2_DragLeave"
dnd:DragAndDropManager.DragOver="ListBox2_DragOver"
dnd:DragAndDropManager.Drop="ListBox2_Drop">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"></Image>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
public partial class MainPage : UserControl, IDragAndDropHandler {
public MainPage() {
InitializeComponent();
listBox1.ItemsSource = new ObservableCollection<string>() {
"WIN-ICON.png",
"ASP-ICON.png",
"WPF-ICON.png",
"AG-ICON.png",
"VCL-ICON.png",
"APP-ICON.png",
"IDE-ICON.png",
"OTHER-ICON.png",
};
listBox2.ItemsSource = new ObservableCollection<string>();
DragAndDropManager.RegisterHandler(listBox1, this);
}
#region Drag Soource
static ListBoxItem GetHotItem(MouseButtonEventArgs e) {
ListBoxItem dragItem = null;
DependencyObject dep = (DependencyObject)e.OriginalSource;
while (dep != null) {
dragItem = dep as ListBoxItem;
if (dragItem != null) {
break;
}
dep = VisualTreeHelper.GetParent(dep);
}
return dragItem;
}
bool IDragAndDropHandler.CanStartDrag(UIElement source, MouseButtonEventArgs e, ref object dragData) {
dragData = GetHotItem(e);
// Only Allow Dragging if we are on a ListBoxItem
return dragData != null;
}
FrameworkElement IDragAndDropHandler.CreateDragThumb(UIElement source, UIElement target, object dragData) {
// Override the default drag cursor
Image img = new Image();
BitmapImage bi = new BitmapImage(new Uri(((ListBoxItem)dragData).Content as string, UriKind.Relative));
img.Source = bi;
img.Opacity = 0.6;
return img;
}
#endregion
#region Drop Target
public void ListBox2_DragOver(object sender, DragAndDropEventArgs e) {
// Only Accept objects from listBox1
e.Accept = e.Source == listBox1;
}
public void ListBox2_DragLeave(object sender, DragAndDropEventArgs e) {
}
public void ListBox2_Drop(object sender, DragAndDropEventArgs e) {
ObservableCollection<string> source = ((System.Windows.Controls.ListBox)e.Source).ItemsSource as ObservableCollection<string>;
ObservableCollection<string> dest = ((System.Windows.Controls.ListBox)sender).ItemsSource as ObservableCollection<string>;
string item = (string)((ListBoxItem)e.DragData).Content;
source.Remove(item);
dest.Add(item);
}
#endregion
}
Cheers,
Azret