Is there an up to date example of the current radtreeview node drag/drop functionality?
Examples and discussions I've found so far appear to refer to obsolete functionality, and while a simple xaml test works, events don't seem to trigger as expected.
In particular what are the relevant drop preview and event handlers and how do you get source and target nodes from the event arguments?
Tia,
Jonathan
Examples and discussions I've found so far appear to refer to obsolete functionality, and while a simple xaml test works, events don't seem to trigger as expected.
In particular what are the relevant drop preview and event handlers and how do you get source and target nodes from the event arguments?
Tia,
Jonathan
4 Answers, 1 is accepted
0
Jonathan
Top achievements
Rank 1
answered on 17 Sep 2014, 04:35 PM
I wrote my own example but for some reason it doesn't update the treeview control after a move (although the underlying structure is updated correctly)...
<
Window
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
x:Class
=
"treedragdrop.MainWindow"
xmlns:local
=
"clr-namespace:treedragdrop"
xmlns:System
=
"clr-namespace:System;assembly=mscorlib"
mc:Ignorable
=
"d"
d:DataContext
=
"{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:MainWindow}}"
Title
=
"MainWindow"
Height
=
"600"
Width
=
"800"
>
<
Window.Resources
>
<
HierarchicalDataTemplate
DataType
=
"{x:Type local:Person}"
ItemsSource
=
"{Binding Path=Subjects}"
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"{Binding Path=Name}"
/>
</
StackPanel
>
<
HierarchicalDataTemplate.ItemContainerStyle
>
<
Style
TargetType
=
"telerik:RadTreeViewItem"
>
<
Setter
Property
=
"HorizontalAlignment"
Value
=
"Stretch"
/>
</
Style
>
</
HierarchicalDataTemplate.ItemContainerStyle
>
</
HierarchicalDataTemplate
>
</
Window.Resources
>
<
Grid
>
<
telerik:RadTreeView
Name
=
"tvRealm"
Margin
=
"5"
SelectionMode
=
"Single"
IsDragDropEnabled
=
"True"
telerik:TreeViewSettings.DragDropExecutionMode
=
"New"
ItemsSource
=
"{Binding Realm, Mode=OneWay, NotifyOnSourceUpdated=True}"
>
</
telerik:RadTreeView
>
</
Grid
>
</
Window
>
using
System;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
System.Linq;
using
System.Text;
using
System.Threading.Tasks;
using
System.Windows;
using
System.Windows.Controls;
using
System.Windows.Data;
using
System.Windows.Documents;
using
System.Windows.Input;
using
System.Windows.Media;
using
System.Windows.Media.Imaging;
using
System.Windows.Navigation;
using
System.Windows.Shapes;
using
Telerik.Windows.Controls;
using
Telerik.Windows.Controls.TreeView;
using
Telerik.Windows.DragDrop;
namespace
treedragdrop
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public
partial
class
MainWindow : Window
{
private
ObservableCollection<Person> _realm =
new
ObservableCollection<Person>();
public
MainWindow()
{
InitializeComponent();
Person _king =
new
Person(
"The King"
, Rank.King);
Person _baron1 =
new
Person(
"Baron 1"
, Rank.Baron);
Person _baron2 =
new
Person(
"Baron 2"
, Rank.Baron);
Person _overseer1 =
new
Person(
"Overseer 1"
, Rank.Overseer);
Person _overseer2 =
new
Person(
"Overseer 2"
, Rank.Overseer);
Person _overseer3 =
new
Person(
"Overseer 3"
, Rank.Overseer);
Person _overseer4 =
new
Person(
"Overseer 4"
, Rank.Overseer);
Person _serf1 =
new
Person(
"Serf 1"
, Rank.Serf);
Person _serf2 =
new
Person(
"Serf 2"
, Rank.Serf);
Person _serf3 =
new
Person(
"Serf 3"
, Rank.Serf);
Person _serf4 =
new
Person(
"Serf 4"
, Rank.Serf);
Person _serf5 =
new
Person(
"Serf 5"
, Rank.Serf);
Person _serf6 =
new
Person(
"Serf 6"
, Rank.Serf);
Person _serf7 =
new
Person(
"Serf 7"
, Rank.Serf);
Person _serf8 =
new
Person(
"Serf 8"
, Rank.Serf);
_realm.Add(_king);
_king.AddSubject(_baron1);
_king.AddSubject(_baron2);
_baron1.AddSubject(_overseer1);
_baron1.AddSubject(_overseer2);
_baron2.AddSubject(_overseer3);
_baron2.AddSubject(_overseer4);
_overseer1.AddSubject(_serf1);
_overseer1.AddSubject(_serf2);
_overseer2.AddSubject(_serf3);
_overseer2.AddSubject(_serf4);
_overseer3.AddSubject(_serf5);
_overseer3.AddSubject(_serf6);
_overseer4.AddSubject(_serf7);
_overseer4.AddSubject(_serf8);
DataContext =
this
;
Loaded += MainWindow_Loaded;
}
void
MainWindow_Loaded(
object
sender, RoutedEventArgs e)
{
DragDropManager.AddDragInitializeHandler(tvRealm, OnDragInitialize,
true
);
DragDropManager.AddDragOverHandler(tvRealm, OnDragOver,
true
);
DragDropManager.AddDropHandler(tvRealm, OnDrop,
true
);
DragDropManager.AddPreviewDropHandler(tvRealm, OnPreviewDrop,
true
);
tvRealm.ExpandAll();
}
public
ObservableCollection<Person> Realm
{
get
{
return
_realm; }
}
private
void
OnDragInitialize(
object
sender, DragInitializeEventArgs e)
{
RadTreeViewItem item = e.OriginalSource
as
RadTreeViewItem;
object
data = item.Item;
e.AllowedEffects = DragDropEffects.Move;
}
private
void
OnDragOver(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
Person _ruler = (_target.Rank != Rank.Serf) ? _target : _target.Ruler;
if
(_source.CanMoveTo(_ruler))
args.Effects = DragDropEffects.Move;
else
args.Effects = DragDropEffects.None;
}
private
void
OnDrop(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
TreeViewDragDropOptions options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
if
(options !=
null
)
{
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
Person _ruler = (_target.Rank != Rank.Serf) ? _target : _target.Ruler;
_source.SetRuler(_ruler);
}
}
private
void
OnPreviewDrop(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
Person _ruler = (_target.Rank != Rank.Serf) ? _target : _target.Ruler;
if
(_source.CanMoveTo(_ruler))
options.DropAction = DropAction.Move;
else
options.DropAction = DropAction.None;
}
}
public
class
Person
{
private
string
_name;
private
Rank _rank;
private
Person _ruler;
private
List<Person> _subjects;
public
Person(
string
name, Rank rank)
{
_name = name;
_rank = rank;
_ruler =
null
;
_subjects =
new
List<Person>();
}
public
string
Name
{
get
{
return
_name; }
set
{ _name = value; }
}
public
Rank Rank
{
get
{
return
_rank; }
}
public
Person Ruler
{
get
{
return
_ruler; }
}
public
List<Person> Subjects
{
get
{
return
_subjects; }
}
public
bool
CanMoveTo(Person ruler)
{
bool
_result;
switch
(
this
._rank)
{
case
Rank.Baron:
switch
(ruler.Rank)
{
case
Rank.King:
_result =
true
;
break
;
case
Rank.Baron:
case
Rank.Overseer:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(ruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
_result =
true
;
break
;
case
Rank.Overseer:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
switch
(ruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
return
_result;
}
public
bool
SetRank(Rank rank, Person ruler)
{
bool
_result;
switch
(
this
._rank)
{
case
Rank.Baron:
switch
(rank)
{
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.Serf:
_result = (
this
._subjects.Count == 0);
break
;
case
Rank.King:
case
Rank.Baron:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(rank)
{
case
Rank.Baron:
_result =
true
;
break
;
case
Rank.Serf:
_result = (
this
._subjects.Count == 0);
break
;
case
Rank.King:
case
Rank.Overseer:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
switch
(rank)
{
case
Rank.Baron:
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.King:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
if
(_result)
{
switch
(rank)
{
case
Rank.Baron:
switch
(ruler.Rank)
{
case
Rank.King:
_result =
true
;
break
;
case
Rank.Baron:
case
Rank.Overseer:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(ruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
_result =
true
;
break
;
case
Rank.Overseer:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
switch
(ruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
}
if
(_result)
{
_rank = rank;
_ruler = ruler;
}
return
_result;
}
public
bool
SetRuler(Person ruler)
{
bool
_result =
false
;
if
(CanMoveTo(ruler))
{
Person _oldruler =
this
._ruler;
if
(_oldruler !=
null
)
_oldruler.Subjects.Remove(
this
);
_ruler = ruler;
_result =
true
;
}
return
_result;
}
public
bool
AddSubject(Person subject)
{
bool
_result;
switch
(
this
._rank)
{
case
Rank.King:
switch
(subject.Rank)
{
case
Rank.Baron:
case
Rank.Overseer:
case
Rank.Serf:
_result =
true
;
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Baron:
switch
(subject.Rank)
{
case
Rank.Overseer:
case
Rank.Serf:
_result =
true
;
break
;
case
Rank.King:
case
Rank.Baron:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(subject.Rank)
{
case
Rank.Serf:
_result =
true
;
break
;
case
Rank.King:
case
Rank.Baron:
case
Rank.Overseer:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
if
(_result)
if
(subject.SetRuler(
this
))
_subjects.Add(subject);
return
_result;
}
public
override
string
ToString()
{
return
_name;
}
public
string
Header
{
get
{
return
_name; }
set
{ _name = value; }
}
public
List<Person> Items
{
get
{
return
_subjects; }
set
{ _subjects = value; }
}
}
public
enum
Rank
{
King,
Baron,
Overseer,
Serf
}
}
0
Hello Jonathan,
Thank you for the code snippet.
I am not sure that I understand what you mean by that the treeview doesn't update after a move. Can you please clarify what did you mean?
However, I noticed few things that can lead to incorrect behavior. First, I recommend you to use ObservableCollection<T> instead of List<T>, for all collection from your view models that are bound in the visual tree. This way the tree will be notified for the changes in its underlying collections and its UI will be redrawn correctly.
Also, there is a SetRuler() method used in the Drop event handler, that removes the old ruler and set a new one. When you drag and drop a ruler the SetRuler removes the dragged item from the Subjects collection of the old ruler, but the item is never added in the old ruler. Probably this is the reason behind the reported issue. Moreover, if you drop the dragged item on its initial position you can skip the execution of the SetRuler() method because the ruler will be the same.
You can also take a look at the Drag and Drop section of the RadTreeView help documentation and our Drag and Drop demo. In addition I attached a small project with your code. Please give it a try and let me know if it works as expected.
Regards,
Martin
Telerik
Thank you for the code snippet.
I am not sure that I understand what you mean by that the treeview doesn't update after a move. Can you please clarify what did you mean?
However, I noticed few things that can lead to incorrect behavior. First, I recommend you to use ObservableCollection<T> instead of List<T>, for all collection from your view models that are bound in the visual tree. This way the tree will be notified for the changes in its underlying collections and its UI will be redrawn correctly.
Also, there is a SetRuler() method used in the Drop event handler, that removes the old ruler and set a new one. When you drag and drop a ruler the SetRuler removes the dragged item from the Subjects collection of the old ruler, but the item is never added in the old ruler. Probably this is the reason behind the reported issue. Moreover, if you drop the dragged item on its initial position you can skip the execution of the SetRuler() method because the ruler will be the same.
public
bool
SetRuler(Person ruler)
{
if
(ruler ==
this
._ruler) {
return
false
; }
bool
_result =
false
;
if
(CanMoveTo(ruler))
{
Person _oldruler =
this
._ruler;
// The code for removing this item from the Subjects collection of the ruler was deleted because the default drag drop logic of the tree automatically will remove the item and add it in the Subjects collection of the target ruler
_ruler = ruler;
_result =
true
;
}
return
_result;
}
You can also take a look at the Drag and Drop section of the RadTreeView help documentation and our Drag and Drop demo. In addition I attached a small project with your code. Please give it a try and let me know if it works as expected.
Regards,
Martin
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
0
Jonathan
Top achievements
Rank 1
answered on 22 Sep 2014, 02:45 PM
That's great, thanks for your hard work :)
Next challenge is to drag new elements from a palette (another treeview), this seems to work but when I want to refresh the palette to restore dragged items my DropCompleted handler doesn't seem to get invoked... code is below, probably I'm doing something dumb...
Jonathan
Next challenge is to drag new elements from a palette (another treeview), this seems to work but when I want to refresh the palette to restore dragged items my DropCompleted handler doesn't seem to get invoked... code is below, probably I'm doing something dumb...
Jonathan
<
Window
x:Class
=
"treeviewrealm.MainWindow"
xmlns:System
=
"clr-namespace:System;assembly=mscorlib"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:local
=
"clr-namespace:treeviewrealm"
mc:Ignorable
=
"d"
d:DataContext
=
"{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:MainWindow}}"
Title
=
"MainWindow"
Height
=
"600"
Width
=
"800"
>
<
Grid
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"200"
/>
<
ColumnDefinition
Width
=
"*"
/>
<
ColumnDefinition
Width
=
"*"
/>
</
Grid.ColumnDefinitions
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"*"
/>
<
RowDefinition
Height
=
"Auto"
/>
</
Grid.RowDefinitions
>
<
telerik:RadTreeView
Name
=
"tvPeople"
Margin
=
"5"
BorderBrush
=
"Black"
BorderThickness
=
"0.5"
SelectionMode
=
"Single"
IsDragDropEnabled
=
"True"
telerik:TreeViewSettings.DragDropExecutionMode
=
"New"
ItemsSource
=
"{Binding People, Mode=OneWay, NotifyOnSourceUpdated=True}"
/>
<
telerik:RadTreeView
Name
=
"tvRealm"
Margin
=
"5"
Grid.Column
=
"1"
SelectionMode
=
"Single"
IsDragDropEnabled
=
"True"
telerik:TreeViewSettings.DragDropExecutionMode
=
"New"
ItemsSource
=
"{Binding Realm, Mode=OneWay, NotifyOnSourceUpdated=True}"
>
<
telerik:RadTreeView.Resources
>
<
HierarchicalDataTemplate
DataType
=
"{x:Type local:Person}"
ItemsSource
=
"{Binding Path=Subjects}"
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"{Binding Path=Name}"
/>
</
StackPanel
>
<
HierarchicalDataTemplate.ItemContainerStyle
>
<
Style
TargetType
=
"telerik:RadTreeViewItem"
>
<
Setter
Property
=
"HorizontalAlignment"
Value
=
"Stretch"
/>
</
Style
>
</
HierarchicalDataTemplate.ItemContainerStyle
>
</
HierarchicalDataTemplate
>
</
telerik:RadTreeView.Resources
>
</
telerik:RadTreeView
>
<
telerik:RadTreeView
Name
=
"tvClone"
Background
=
"LightGray"
Grid.Column
=
"2"
Margin
=
"5"
SelectionMode
=
"Single"
IsDragDropEnabled
=
"False"
telerik:TreeViewSettings.DragDropExecutionMode
=
"New"
ItemsSource
=
"{Binding Realm, Mode=OneWay, NotifyOnSourceUpdated=True}"
IsDragPreviewEnabled
=
"False"
IsDragTooltipEnabled
=
"False"
IsDropPreviewLineEnabled
=
"False"
>
<
telerik:RadTreeView.Resources
>
<
HierarchicalDataTemplate
DataType
=
"{x:Type local:Person}"
ItemsSource
=
"{Binding Path=Subjects}"
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"{Binding Path=FullName}"
/>
</
StackPanel
>
<
HierarchicalDataTemplate.ItemContainerStyle
>
<
Style
TargetType
=
"telerik:RadTreeViewItem"
>
<
Setter
Property
=
"HorizontalAlignment"
Value
=
"Stretch"
/>
</
Style
>
</
HierarchicalDataTemplate.ItemContainerStyle
>
</
HierarchicalDataTemplate
>
</
telerik:RadTreeView.Resources
>
</
telerik:RadTreeView
>
<
TextBlock
Margin
=
"5"
Grid.Row
=
"1"
Text
=
"{Binding Status, Mode=OneWay, NotifyOnSourceUpdated=True}"
HorizontalAlignment
=
"Stretch"
VerticalAlignment
=
"Center"
/>
</
Grid
>
</
Window
>
using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
System.ComponentModel;
using
System.Linq;
using
System.Text;
using
System.Threading.Tasks;
using
System.Windows;
using
System.Windows.Controls;
using
System.Windows.Data;
using
System.Windows.Documents;
using
System.Windows.Input;
using
System.Windows.Media;
using
System.Windows.Media.Imaging;
using
System.Windows.Navigation;
using
System.Windows.Shapes;
using
Telerik.Windows.Controls;
using
Telerik.Windows.Controls.TreeView;
using
Telerik.Windows.DragDrop;
namespace
treeviewrealm
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public
partial
class
MainWindow : Window, INotifyPropertyChanged
{
private
ObservableCollection<Person> _realm =
new
ObservableCollection<Person>();
private
ObservableCollection<Person> _people =
new
ObservableCollection<Person>();
public
MainWindow()
{
InitializeComponent();
Person _king =
new
Person(
"The King"
, Rank.King);
Person _baron1 =
new
Person(
"Baron 1"
, Rank.Baron);
Person _baron2 =
new
Person(
"Baron 2"
, Rank.Baron);
Person _overseer1 =
new
Person(
"Overseer 1"
, Rank.Overseer);
Person _overseer2 =
new
Person(
"Overseer 2"
, Rank.Overseer);
Person _overseer3 =
new
Person(
"Overseer 3"
, Rank.Overseer);
Person _overseer4 =
new
Person(
"Overseer 4"
, Rank.Overseer);
Person _serf1 =
new
Person(
"Serf 1"
, Rank.Serf);
Person _serf2 =
new
Person(
"Serf 2"
, Rank.Serf);
Person _serf3 =
new
Person(
"Serf 3"
, Rank.Serf);
Person _serf4 =
new
Person(
"Serf 4"
, Rank.Serf);
Person _serf5 =
new
Person(
"Serf 5"
, Rank.Serf);
Person _serf6 =
new
Person(
"Serf 6"
, Rank.Serf);
Person _serf7 =
new
Person(
"Serf 7"
, Rank.Serf);
Person _serf8 =
new
Person(
"Serf 8"
, Rank.Serf);
_realm.Add(_king);
_king.AddSubject(_baron1);
_king.AddSubject(_baron2);
_baron1.AddSubject(_overseer1);
_baron1.AddSubject(_overseer2);
_baron2.AddSubject(_overseer3);
_baron2.AddSubject(_overseer4);
_overseer1.AddSubject(_serf1);
_overseer1.AddSubject(_serf2);
_overseer2.AddSubject(_serf3);
_overseer2.AddSubject(_serf4);
_overseer3.AddSubject(_serf5);
_overseer3.AddSubject(_serf6);
_overseer4.AddSubject(_serf7);
_overseer4.AddSubject(_serf8);
ResetPeople();
DataContext =
this
;
Loaded += MainWindow_Loaded;
}
void
MainWindow_Loaded(
object
sender, RoutedEventArgs e)
{
DragDropManager.AddDragOverHandler(tvRealm, OnRealmDragOver,
true
);
DragDropManager.AddPreviewDropHandler(tvRealm, OnRealmPreviewDrop,
true
);
DragDropManager.AddDropHandler(tvRealm, OnRealmDrop,
true
);
DragDropManager.AddDragDropCompletedHandler(tvRealm, OnRealmDropCompleted);
DragDropManager.AddDragOverHandler(tvPeople, OnPeopleDragOver,
true
);
DragDropManager.AddDragDropCompletedHandler(tvPeople, OnPeopleDropCompleted);
tvRealm.ExpandAll();
tvClone.ExpandAll();
}
public
event
PropertyChangedEventHandler PropertyChanged;
protected
void
OnPropertyChanged(
string
name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if
(handler !=
null
)
{
handler(
this
,
new
PropertyChangedEventArgs(name));
}
}
public
ObservableCollection<Person> Realm
{
get
{
return
_realm; }
}
public
ObservableCollection<Person> People
{
get
{
return
_people; }
}
private
string
_status =
string
.Empty;
public
string
Status
{
get
{
return
_status; }
set
{
_status = value;
OnPropertyChanged(
"Status"
);
}
}
private
void
OnPeopleDragOver(
object
sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var options = DragDropPayloadManager.GetDataFromObject(e.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
options.DropAction = DropAction.None;
}
private
void
OnPeopleDropCompleted(
object
sender, DragDropCompletedEventArgs e)
{
ResetPeople();
}
private
void
OnRealmDragOver(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
if
(options !=
null
)
{
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
Status = options.DropAction.ToString() +
" "
+ options.DropPosition.ToString() +
" "
+ _target.Name;
if
(options.DropPosition == DropPosition.Before | options.DropPosition == DropPosition.After)
_target = _target.Ruler;
if
(!_source.CanMoveTo(_target))
options.DropAction = DropAction.None;
else
options.DropAction = DropAction.Move;
}
}
private
void
OnRealmPreviewDrop(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
if
(options !=
null
)
{
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
if
(options.DropPosition == DropPosition.Before | options.DropPosition == DropPosition.After)
_target = _target.Ruler;
if
(!_source.CanMoveTo(_target))
options.DropAction = DropAction.None;
else
options.DropAction = DropAction.Move;
}
}
private
void
OnRealmDrop(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
TreeViewDragDropOptions options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
if
(options !=
null
)
{
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
bool
_new = (_source.Ruler !=
null
);
if
(options.DropPosition == DropPosition.Before | options.DropPosition == DropPosition.After)
_source.SetRuler(_target.Ruler);
else
_source.SetRuler(_target);
if
(_new)
_target.AddSubject(_source);
OnPropertyChanged(
"Realm"
);
ResetPeople();
}
}
private
void
OnRealmDropCompleted(
object
sender, DragDropCompletedEventArgs e)
{
ResetPeople();
}
private
void
ResetPeople()
{
if
(!_people.Any(a => a.Rank == Rank.King))
_people.Add(
new
Person(
"Baron"
, Rank.King));
if
(!_people.Any(a => a.Rank == Rank.Baron))
_people.Add(
new
Person(
"King"
, Rank.Baron));
if
(!_people.Any(a => a.Rank == Rank.Overseer))
_people.Add(
new
Person(
"Overseer"
, Rank.Overseer));
if
(!_people.Any(a => a.Rank == Rank.Serf))
_people.Add(
new
Person(
"Serf"
, Rank.Serf));
OnPropertyChanged(
"People"
);
}
}
public
class
Person
{
private
string
_name;
private
Rank _rank;
private
Person _ruler;
private
ObservableCollection<Person> _subjects;
public
Person(
string
name, Rank rank)
{
_name = name;
_rank = rank;
_ruler =
null
;
_subjects =
new
ObservableCollection<Person>();
}
public
string
Name
{
get
{
return
_name; }
set
{ _name = value; }
}
public
string
FullName
{
get
{
return
_name +
" {"
+ ((_ruler !=
null
) ? _ruler.Name :
"None"
) +
"}"
; }
}
public
Rank Rank
{
get
{
return
_rank; }
}
public
Person Ruler
{
get
{
return
_ruler; }
}
public
ObservableCollection<Person> Subjects
{
get
{
return
_subjects; }
}
public
bool
CanMoveTo(Person newruler)
{
bool
_result =
false
;
if
(
this
!= newruler)
{
switch
(
this
._rank)
{
case
Rank.Baron:
switch
(newruler.Rank)
{
case
Rank.King:
_result =
true
;
break
;
case
Rank.Baron:
case
Rank.Overseer:
case
Rank.Serf:
default
:
break
;
}
break
;
case
Rank.Overseer:
switch
(newruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
_result =
true
;
break
;
case
Rank.Overseer:
case
Rank.Serf:
default
:
break
;
}
break
;
case
Rank.Serf:
switch
(newruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.Serf:
default
:
break
;
}
break
;
case
Rank.King:
default
:
break
;
}
}
return
_result;
}
public
bool
SetRank(Rank rank, Person ruler)
{
bool
_result;
switch
(
this
._rank)
{
case
Rank.Baron:
switch
(rank)
{
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.Serf:
_result = (
this
._subjects.Count == 0);
break
;
case
Rank.King:
case
Rank.Baron:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(rank)
{
case
Rank.Baron:
_result =
true
;
break
;
case
Rank.Serf:
_result = (
this
._subjects.Count == 0);
break
;
case
Rank.King:
case
Rank.Overseer:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
switch
(rank)
{
case
Rank.Baron:
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.King:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
if
(_result)
{
switch
(rank)
{
case
Rank.Baron:
switch
(ruler.Rank)
{
case
Rank.King:
_result =
true
;
break
;
case
Rank.Baron:
case
Rank.Overseer:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(ruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
_result =
true
;
break
;
case
Rank.Overseer:
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
switch
(ruler.Rank)
{
case
Rank.King:
case
Rank.Baron:
case
Rank.Overseer:
_result =
true
;
break
;
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
}
if
(_result)
{
_rank = rank;
_ruler = ruler;
}
return
_result;
}
public
void
ResetPerson()
{
_ruler =
null
;
}
public
bool
SetRuler(Person ruler)
{
if
(ruler ==
this
._ruler) {
return
false
; }
bool
_result =
false
;
if
(CanMoveTo(ruler))
{
_ruler = ruler;
_result =
true
;
}
return
_result;
}
public
bool
AddSubject(Person subject)
{
bool
_result;
switch
(
this
._rank)
{
case
Rank.King:
switch
(subject.Rank)
{
case
Rank.Baron:
case
Rank.Overseer:
case
Rank.Serf:
_result =
true
;
break
;
case
Rank.King:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Baron:
switch
(subject.Rank)
{
case
Rank.Overseer:
case
Rank.Serf:
_result =
true
;
break
;
case
Rank.King:
case
Rank.Baron:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Overseer:
switch
(subject.Rank)
{
case
Rank.Serf:
_result =
true
;
break
;
case
Rank.King:
case
Rank.Baron:
case
Rank.Overseer:
default
:
_result =
false
;
break
;
}
break
;
case
Rank.Serf:
default
:
_result =
false
;
break
;
}
if
(_result)
if
(subject.SetRuler(
this
))
_subjects.Add(subject);
return
_result;
}
public
override
string
ToString()
{
return
FullName;
}
public
string
Header
{
get
{
return
_name; }
set
{ _name = value; }
}
public
ObservableCollection<Person> Items
{
get
{
return
_subjects; }
set
{ _subjects = value; }
}
}
public
enum
Rank
{
King,
Baron,
Overseer,
Serf
}
}
0
Hi Jonathan,
The DragDropCompleted event is not invoked because it is handled in the default drag and drop logic of RadTreeView. In order to resolve this you can set the handledEventsToo parameter of the DragDropManager.AddDragDropCompletedHandler() method.
However, I can suggest you another approach that I think could be more suitable for you then re-adding people in the first tree with the ResetPeople() method. Basically, if the drag source tree is different than the drop target tree you can set the TreeViewDragDropOptions' DropAction to Copy.
Here is an example:
Please give this approach a try and let me know if it works as expected. In addition you can take a look at the Implement Drag and Drop between RadTreeViews and Implement Copy Drag help articles.
Regards,
Martin
Telerik
The DragDropCompleted event is not invoked because it is handled in the default drag and drop logic of RadTreeView. In order to resolve this you can set the handledEventsToo parameter of the DragDropManager.AddDragDropCompletedHandler() method.
DragDropManager.AddDragDropCompletedHandler(tvPeople, OnPeopleDropCompleted,
true
);
However, I can suggest you another approach that I think could be more suitable for you then re-adding people in the first tree with the ResetPeople() method. Basically, if the drag source tree is different than the drop target tree you can set the TreeViewDragDropOptions' DropAction to Copy.
Here is an example:
private
void
OnRealmDragOver(
object
sender, Telerik.Windows.DragDrop.DragEventArgs args)
{
var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key)
as
TreeViewDragDropOptions;
if
(options !=
null
)
{
Person _source = options.DragSourceItem.Item
as
Person;
Person _target = options.DropTargetItem.Item
as
Person;
Status = options.DropAction.ToString() +
" "
+ options.DropPosition.ToString() +
" "
+ _target.Name;
if
(options.DropPosition == DropPosition.Before | options.DropPosition == DropPosition.After)
_target = _target.Ruler;
if
(!_source.CanMoveTo(_target))
options.DropAction = DropAction.None;
// If the drop target tree is different than the drag source tree
else
if
(options.DragSourceItem.ParentTreeView != (sender
as
RadTreeView))
{
options.DropAction = DropAction.Copy;
}
else
{
options.DropAction = DropAction.Move;
}
}
}
Please give this approach a try and let me know if it works as expected. In addition you can take a look at the Implement Drag and Drop between RadTreeViews and Implement Copy Drag help articles.
Regards,
Martin
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.