Hey all.
I'm playing around with DragDrop behaviours, mainly dragging from other controls (or explorer), and dropping onto a TreeListView. I would like to set the drag visual in these instances (for example, detail how many files are being dragged), but currently, the only way to create a visual is when the item is the source of the drag operation, not the destination.
Does anyone have any pointers as to where I can go from here ?
5 Answers, 1 is accepted
You can specify the destination information on DragOver event raised. For the purpose you need to set the DragVisual on DragInitialize and later you update the details on DragOver.
For example:
private
void
OnDragInitialize(
object
sender, DragInitializeEventArgs e)
{
var sourceRow = e.OriginalSource
as
GridViewRow ?? (e.OriginalSource
as
FrameworkElement).ParentOfType<GridViewRow>();
if
(sourceRow !=
null
&& sourceRow.Name !=
"PART_RowResizer"
)
{
DropIndicationDetails details =
new
DropIndicationDetails();
var item = sourceRow.Item;
details.CurrentDraggedItem = item;
IDragPayload dragPayload = DragDropPayloadManager.GeneratePayload(
null
);
dragPayload.SetData(
"DraggedItem"
, item);
dragPayload.SetData(
"DropDetails"
, details);
e.Data = dragPayload;
e.DragVisual =
new
DragVisual()
{
Content = details,
ContentTemplate =
this
.AssociatedObject.Resources[
"DraggedItemTemplate"
]
as
DataTemplate
};
e.DragVisualOffset = e.RelativeStartPoint;
e.AllowedEffects = DragDropEffects.All;
}
}
DraggedItemTemplate is defines as follows:
<
telerik:RadGridView.Resources
>
<
DataTemplate
x:Key
=
"DraggedItemTemplate"
>
<
StackPanel
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"Dragging:"
/>
<
TextBlock
Text
=
"{Binding CurrentDraggedItem}"
FontWeight
=
"Bold"
/>
</
StackPanel
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"{Binding CurrentDropPosition}"
FontWeight
=
"Bold"
MinWidth
=
"45"
/>
<
TextBlock
Text
=
", ("
Foreground
=
"Gray"
/>
<
TextBlock
Text
=
"{Binding CurrentDraggedOverItem}"
/>
<
TextBlock
Text
=
")"
Foreground
=
"Gray"
/>
</
StackPanel
>
</
StackPanel
>
</
DataTemplate
>
</
telerik:RadGridView.Resources
>
DragOver event is raised and handled similarly to:
private
void
OnRowDragOver(
object
sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var row = sender
as
GridViewRow;
var details = DragDropPayloadManager.GetDataFromObject(e.Data,
"DropDetails"
)
as
DropIndicationDetails;
if
(details ==
null
|| row ==
null
)
{
return
;
}
details.CurrentDraggedOverItem = row.DataContext;
if
(details.CurrentDraggedItem == details.CurrentDraggedOverItem)
{
e.Effects = DragDropEffects.None;
e.Handled =
true
;
return
;
}
details.CurrentDropPosition = GetDropPositionFromPoint(e.GetPosition(row), row);
int
dropIndex = (
this
.AssociatedObject.Items
as
IList).IndexOf(row.DataContext);
int
draggedItemIdex = (
this
.AssociatedObject.Items
as
IList).IndexOf(DragDropPayloadManager.GetDataFromObject(e.Data,
"DraggedItem"
));
if
(dropIndex >= row.GridViewDataControl.Items.Count - 1 && details.CurrentDropPosition == DropPosition.After)
{
details.DropIndex = dropIndex;
return
;
}
dropIndex = draggedItemIdex > dropIndex ? dropIndex : dropIndex - 1;
details.DropIndex = details.CurrentDropPosition == DropPosition.Before ? dropIndex : dropIndex + 1;
}
A full implementation of such an approach is available on the RowReorder WPF / Silverlight example. In addition, you can check the DragDropManager documentation for more details on how to use it.
Regards,
Dimitrina
Telerik
I'm afraid that without having access to the DragInitilize handler it won't be possible to change the DragVisual during the drag operation. However you can check the following forum thread demonstrating how this can be done if you have access to the DragInitilize handler:
http://www.telerik.com/forums/change-dragvisual-while-dragging
If you have any other questions, please do not hesitate to contact us.
Regards,
Kalin
Telerik
Fair enough. I have raised a feature request, so I'll see where that ends up.
In liu of not being able to change the drag visual, is it possible to get rows the highlight as they do in mouseover events ? My current drop target is a TreeListView, and while dragging over, there is no feedback, which will raise usability issues in the future.
When dragging over, you can update the drag cue on DragOver event raised. Alternatively, you can subscribe to the mouse over event and get the corresponding row using the ParentOfType extension method.
For example:
var result = (e.OriginalSource
as
FrameworkElement).ParentOfType<GridViewRow>();
Regards,
Dimitrina
Telerik