Hello, when using the AllowDragDrop=true on a ListView control, it gives to user a beautiful feedback while doing drag/drop (attached image).
Since i need to implement drag & drop manually, would be possible to draw insert lines on the listview control in "list" view mode?
Would be nice to also have the semiopaque cursor while dragging like on the attached image, but that is not that necessary to me.
The lack of insertion lines in my opinion make not clear for the users where the item will be dropped.
Best Regards
Andrea
3 Answers, 1 is accepted
Thank you for writing.
RadListView provides various means for customizing its drag and drop behavior. By handling the events defined within the ListViewDragDropService you would be able to allow or cancel dragging or dropping of certain items. Additionally, it also provides means for customizing the drag hint and the insertion lines are drawn by default.
Please refer to the following section of our RadListView documentation: Drag and Drop. I am also sending you a sample project demonstrating how you can access the drag drop service class. In case you would not be able to work with the suggested in the project or documentation approaches, could you please provide me with more details about your scenario and ultimate goal.
I hope this helps. Should you have further questions please do not hesitate to write back.
Regards,
Hristo Merdjanov
Telerik
Thank you for answering,
But i do not know how to do that properly, maybe you could help me, do not know if i have to open a support ticket for this.
My application is the following:
I have a radtreeview, containing a list of nodes, each treenode, references an applicative business object using the Tag property.
An applicative object could be for example a business relation with another company. a business relation could contain a bunch of contracts, each contract may contain sub contracts, user could create folders that can contain only a specific set of objects depending on its position, for example a folder containing contracts cannot contain a business relation:
Long story short i need to implement moving items between listview and treeview, and also have to modify the drop icon so that the user cannot drop an object in the wrong position.
I attach a working simplified sample, the idea is that the user could move an item into another only if the CanMoveNode function returns true.
public
class
Form1 : Form
{
public
Form1()
{
init();
SomeSampleNode(0, 0, tv.Nodes);
attachEvents();
}
RadTreeView tv;
RadListView lv;
Random r;
int
next = 0;
void
attachEvents()
{
tv.SelectedNodeChanged += Tv_SelectedNodeChanged; ;
if
(tv.SelectedNode !=
null
)
Tv_SelectedNodeChanged(
this
,
new
RadTreeViewEventArgs(tv.SelectedNode));
}
private
void
Tv_SelectedNodeChanged(
object
sender, RadTreeViewEventArgs e)
{
lv.Items.Clear();
lv.Items.AddRange(
e.Node.Nodes.Select(a =>
new
ListViewDataItem()
{
Text = a.Text,
Image = a.Image,
Tag = a
}).ToArray()
);
}
void
init()
{
tv=
new
RadTreeView();
r =
new
Random();
tv.Dock = DockStyle.Left;
tv.Size =
new
Size(300, 300);
lv =
new
RadListView();
lv.Dock = DockStyle.Fill;
this
.Controls.AddRange(
new
Control[] {
lv,tv
}
);
Size =
new
Size(1024, 768);
this
.StartPosition = FormStartPosition.CenterScreen;
}
void
SomeSampleNode(
int
cat,
int
lev, RadTreeNodeCollection nodes)
{
if
(lev > 4)
return
;
int
count = r.Next(1, 4);
for
(
int
i = 0; i < count; ++i)
{
char
c = (
char
)(cat + 65);
string
nodeName = c +
"_"
+ (++next);
var n = nodes.Add(nodeName);
n.Tag = cat;
if
((r.NextDouble() >= 0.25))
SomeSampleNode((r.NextDouble() >= 0.5) ? 1 + cat : 0 + cat, lev+1, n.Nodes);
}
}
bool
CanMoveNode(
object
source_tag,
object
dest_tag)
{
int
cat1 = (source_tag
as
int
?) ?? -2;
int
cat2 = (dest_tag
as
int
?) ?? -1;
return
cat1 > cat2;
}
}
So
when the user select a node on the treeview i capture the event.
The event handler clear the listview and populate it with all the childs on the tree view, each listview item t.
Now i would like the user be able to move an object from the list to a different node on the tree.
I should capture the drop event on the treeview.
Then imagine the user would like to drop a file from its filesystem onto the list, or maybe a csv fragment representing , i now have to capture the drop event on the list (or in the tree) , deserialize the file, and insert it as a new node on the tree (and on the list).
So what i need is the ability to use the clipboard on drag-drop
Thank you for writing back.
The PreviewDragOver event allows you to control on what targets the item being dragged can be dropped on. The PreviewDragDrop event allows you to get a handle on all the aspects of the drag and drop operation, the source (drag) control, the destination (target) control, as well as the item being dragged. Note that if both controls are in mode, you should manipulate (add , delete, etc.) the data bound items, not the control's items. Additional information is available here: http://docs.telerik.com/devtools/winforms/listview/drag-and-drop/drag-and-drop-using-raddragdropservice
Please also check below my code snippet for dragging between RadTreeView and RadListView:
public
partial
class
Form1 : Form
{
public
Form1()
{
InitializeComponent();
new
RadControlSpyForm().Show();
RadTreeNode node1 =
new
RadTreeNode(
"Node1"
);
RadTreeNode node2 =
new
RadTreeNode(
"Node2"
);
RadTreeNode node3 =
new
RadTreeNode(
"Node3"
);
RadTreeNode node4 =
new
RadTreeNode(
"Node4"
);
radTreeView1.Nodes.Add(node1);
radTreeView1.Nodes.Add(node2);
radTreeView1.Nodes.Add(node3);
radTreeView1.Nodes.Add(node4);
this
.radTreeView1.AllowDragDrop =
true
;
this
.radListView1.AllowDragDrop =
true
;
this
.radTreeView1.TreeViewElement.DragDropService.PreviewDragOver += DragDropService_PreviewDragOver;
this
.radTreeView1.TreeViewElement.DragDropService.PreviewDragDrop += DragDropService_PreviewDragDrop;
}
private
void
DragDropService_PreviewDragDrop(
object
sender, Telerik.WinControls.RadDropEventArgs e)
{
e.Handled =
true
;
TreeNodeElement draggedItem = e.DragInstance
as
TreeNodeElement;
this
.radTreeView1.Nodes.Remove(draggedItem.Data);
SimpleListViewElement el = e.HitTarget
as
SimpleListViewElement;
if
(el !=
null
)
{
el.Items.Add(
new
ListViewDataItem(draggedItem.ContentElement.Text));
}
SimpleListViewVisualItem hoveredItem = e.HitTarget
as
SimpleListViewVisualItem;
if
(hoveredItem !=
null
)
{
((SimpleListViewElement)hoveredItem.Parent.Parent).Items.Insert(hoveredItem.Parent.Children.IndexOf(hoveredItem),
new
ListViewDataItem(draggedItem.ContentElement.Text));
}
}
private
void
DragDropService_PreviewDragOver(
object
sender, Telerik.WinControls.RadDragOverEventArgs e)
{
SimpleListViewVisualItem item = e.HitTarget
as
SimpleListViewVisualItem;
if
(item !=
null
&& item.Data.Text.Contains(
"5"
))
{
e.CanDrop =
false
;
}
}
}
I hope this helps. Please let me know if you need further assistance.
Regards,
Hristo Merdjanov
Telerik