DragAndDrop with RadTreeView and EntityCollection

11 posts, 1 answers
  1. Vincent Jezequel
    Vincent Jezequel avatar
    6 posts
    Member since:
    Oct 2009

    Posted 03 Nov 2009 Link to this post

    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.

  2. Answer
    Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 03 Nov 2009 Link to this post

    Hi Vincent,

    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.
  3. DevCraft banner
  4. Vincent Jezequel
    Vincent Jezequel avatar
    6 posts
    Member since:
    Oct 2009

    Posted 03 Nov 2009 Link to this post

    Works like a charm, thanks a lot :)
  5. Tim
    Tim avatar
    85 posts
    Member since:
    Aug 2008

    Posted 06 Mar 2010 Link to this post

    I had to hook into the "PreviewDragEnded" event as well while binding to a custom collection class derived from ObservableCollection<T>.  Basically, I was binding the TreeView to the "self-reference" data source example available from Telerik.  However, I get the same error mentioned above.  I am not complaining, there is a work around.  However, the event name is not all that intuitive and at first glance a developer doesn't even think that this is the correct event to handle in these situations.  Also, why does the "PreviewDragEnded" event fire but none of the other events that I've attached to a TreeView using the RadDragDropManager fire?  It would seem like the events from the RadDragDropManager should fire first so I can set the "e.Handled=true" in there first before the "PreviewDragEnded" event fires.  All in all, a little weird.
  6. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 10 Mar 2010 Link to this post

    Hi Tim,

    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.
  7. Ubuntu
    Ubuntu avatar
    89 posts
    Member since:
    Jul 2012

    Posted 15 Oct 2011 Link to this post

    Dear Miroslav,

    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>
    and the treeview as this one:
    <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());
    where "GroupItems" is the QDSCV, I then Bind this DebitGroups to RadTreeView as shown above, it works Okay for dragging the top level items only, But I need to so the same for the other nested children, and I have the feeling that my problem is that Children is not ObservabaleCollection as it should be ...!!

    So, is the solution in the same path with my approach?

    Appreciate your help, I need this deadly soon

    Best regards


  8. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 19 Oct 2011 Link to this post

    Hi Ubuntu,

     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. 

    Best wishes,
    Petar Mladenov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  9. Ubuntu
    Ubuntu avatar
    89 posts
    Member since:
    Jul 2012

    Posted 19 Oct 2011 Link to this post

    Hello Miroslav,

    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
  10. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 24 Oct 2011 Link to this post

    Hello Ubuntu,

     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 >>

  11. Ubuntu
    Ubuntu avatar
    89 posts
    Member since:
    Jul 2012

    Posted 26 Oct 2011 Link to this post

    Hello Miroslav,

    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
  12. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 31 Oct 2011 Link to this post

    Hi Ubuntu,

     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 >>

Back to Top
DevCraft banner