Hi,
I’m currently using your RadTreeView component, with a binding to an EntityCollection.
It worked fine, until I tried to implement the Drag&Drop functionality.
I started from theTreeToGrid sample.
Dragging works fine, but everytime I try to drop an item, I get an “Object reference not set to an instance of an object” exception in the “EndDrop” method of the RadTreeView.
I replaced my EntityCollection with an ObservableCollection, just like it's done in the example, and it works fine.
Isn’t it possible to bind to an EntityCollection, or is there something more to do ?
Thanks in advance for your help.
10 Answers, 1 is accepted
In order for the DragDrop to work the TreeView expects its ItemsSource is an IList (because it needs the Insert method).
I checked that the EntityCollectionView does not implement the IList interface. In newer versions the NullReference exception has been foxed and the TreeView will not allow a drop in an item that does not have an IList collection.
You can override the current behavior of the TreeView by handling the DragDrop events of the TreeView.
Please register for the PreviewDragEnded event and handle it (e.Handed = True) to stop the default behavior of the TreeView.
There you have the TargetDropItem, the DraggedItems and the DropPosition. You can use them to move the item from one EntityCollection to another.
Hopefully this will work for you,
Greetings,
Miroslav
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Yes, I can agree that PreviewDragEnded is not the best name in this case. There is also a method that we would rather rename - GetItemByPath really returns a container and should rather be called GetContainerByPath. As much as we are aware of the naming we are committed to not introducing breaking changes unless absolutely necessary.
Since the TreeView handles the events of the RadDragAndDropManager other handlers need to be registered using the AddHandler(event, handler, true) overload which allows handled events to be handled.
I am not sure which version of the hierarchy converter you are using. I am attaching an updated version which should work with DragDrop and would even track property changes to update the hierarchy on the fly.
Sincerely yours,
Miroslav
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Impressive example indeed, exactly what I want to implement ...!!
First: I want to know if it is compatible with my current implementation or not, so let me describe what I have so far ..
I have implemented the self-reference solution as the examples available on telerik so I have the XAML for the hierarchal template as follows:
<
telerik:HierarchicalDataTemplate
x:Name
=
"ItemTemplate"
ItemsSource
=
"{Binding Children}"
>
<
Grid
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
Image
Source
=
"{Binding Bitmap}"
Margin
=
"2"
VerticalAlignment
=
"Center"
/>
<
TextBlock
x:Name
=
"Label"
Text
=
"{Binding name}"
Grid.Column
=
"1"
VerticalAlignment
=
"Center"
/>
</
Grid
>
</
telerik:HierarchicalDataTemplate
>
<
telerik:RadTreeView
x:Name
=
"TOALeft"
FontSize
=
"11"
Grid.Row
=
"1"
IsLineEnabled
=
"True"
ItemTemplate
=
"{StaticResource ItemTemplate}"
ItemsSource
=
"{Binding DebitGroups,Mode=TwoWay}"
IsDragDropEnabled
=
"True"
DropExpandDelay
=
"5"
>
<
i:Interaction.Triggers
>
<
i:EventTrigger
EventName
=
"DragEnded"
>
<
Gala:EventToCommand
Command
=
"{Binding DragEndCommand}"
PassEventArgsToCommand
=
"True"
/>
</
i:EventTrigger
>
<
i:EventTrigger
EventName
=
"PreviewDragEnded"
>
<
Gala:EventToCommand
Command
=
"{Binding PreviewDragEndedCommand}"
PassEventArgsToCommand
=
"True"
/>
</
i:EventTrigger
>
<
i:EventTrigger
EventName
=
"Selected"
>
<
i:InvokeCommandAction
Command
=
"{Binding ItemSelectedCommand}"
CommandParameter
=
"{Binding SelectedItem}"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
</
telerik:RadTreeView
>
On my Server I have included the children collection in the Group metadata:
[Include]
public
EntityCollection<Group> Children {
get
;
set
; }
I then have my ViewModel using the QDSCV "GroupItems" to fetch the data from the server, then I tried to cast the output as follows:
DebitGroups =
new
RadObservableCollection<Group>(GroupItems.Where(o => o.sheet_id == sheetid).AsEnumerable());
So, is the solution in the same path with my approach?
Appreciate your help, I need this deadly soon
Best regards
Unfortunately, we are not sure we understood your problem. If you have drop issues when implementing drag and drop, it is mandatory that the target item's Items ( Children Collection) is already initialized. Could this be your issue ? Is it possible for you to send us a captured video of your problem so that we could detect it better? Or we could also change this ticket type to GeneralFeedback so that you will be able to attach files.
Thank you in advance for your assistance.
Petar Mladenov
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
I am pretty sure the children is initialized as I am not using "LoadOnDemand", and when I expand the parent I can find it's Children collection, the problem happens when I try to drag on of it's children and move it within it's parent to sort them out...I can't & get this forbidden icon.
First:
Should this have a solution without changing anything on my code ?
Second
I create another ObservableCollection property in my extend entity class to get the Children and call it AllChildren, when I go back and change the HierarchicalDataTemplate
to accept this for binding, it works with no problem & the drag-drop works as well.BUT, I am facing another issue which is when the drag-drop changes the order the ObservableCollection doesn't get notified ...the order still the same, how can I bind the index at which the item is in from the treeview to the ObservableCollection !!
It is correct ... if yes, how can I solve the notification issue.
Take a look at my extended class:
public
partial
class
group
{
public
ObservableCollection<group> AllChildren
{
get
{
var oc =
new
ObservableCollection<group>();
foreach
(group G
in
Children)
{
oc.Add(G);
}
return
oc;
}
}
}
Appreciate your help ...
Best
First, I think there should be a change in your code. Between first and second question, I want to add some more info. The RadTreeView uses internally RadDragAndDropManager which makes checks over the Child collection of the destination item. The bad news is that EntityCollection does not pass this test. So the right choice in such scenario is ObservableCollection which implements INotifyCollectionChanged and INotifyPropertyChanged interface. As for the notification issue, why not using the CollectionChanged event of the ObservableCollection. You can find more info for the event arguments of this event here. Is this suitable for you ?
Greetings,Petar Mladenov
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
As you can see I am doing this in the extended partial Group class on the RIA Service class library.
First I don't know if this is correct or not ...
Second, I can't see how can I do this:
AllChildren.CollectionChanged += AllChildren_CollectionChanged;
I tried using the class constructor, but it gives error (redundant Empty Constructor).
Thanks
I read the thread again and I decided to suggest you to re-design your application. Actually, it's not a good approach to wrap a collection and use its CollectionChanged event on the server. It's better to create a wrapper classes on the client. Could you please examine this blog post which demonstrates how to wrap an object hierarchy that comes from a database and how to synchronize a drag and drop operations between the RadTreeView and the database? Is it possible for you to use similar approach in your application?
All the best,Petar Mladenov
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>