This is a migrated thread and some comments may be shown as answers.

Attempting to drag between RadTreeView and RadListBox

3 Answers 113 Views
DragAndDrop
This is a migrated thread and some comments may be shown as answers.
Michael
Top achievements
Rank 1
Michael asked on 05 Dec 2014, 05:13 AM
Hey all.

So I'm in the middle of evaluating the RadTreeView control, and so far, it leaps ahead of other controls I've evaluated. I'm exploring the Drag/Drop functionality at the moment, but am really struggling, as I've not been able to find a consistent approach to tackle the problem in the online documentation.

I've basically got a RadTreeView and a RadListBox, each of their viewmodels have an ObservableCollection of HierachicalData. I can drag within the control, and between like controls (RadListBox to RadListBox), but can't get it working between the two.

I've attached my solution - when dragging from the TreeView, you can see the drop indicator on the ListBox, but drop is disabled.

My tree view looks like this :
<telerik:RadTreeView x:Name="TreeView" Grid.Row="1"
    ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ParentTemplate}"
    SelectionMode="Multiple" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
    IsDragDropEnabled="True" AllowDrop="False" >
    <telerik:RadTreeView.ItemContainerStyle>
        <Style TargetType="telerik:RadTreeViewItem">
            <Setter Property="IsSelected" Value="{Binding Path=Select, Mode=TwoWay}" />
            <Setter Property="IsExpanded" Value="{Binding Path=Expand, Mode=TwoWay}"></Setter>
        </Style >
    </telerik:RadTreeView.ItemContainerStyle>
</telerik:RadTreeView>
.. with the following VM ...
public class TelerikTreeViewModel : ReactiveScreen
    {
        private ObservableCollection<HierachicalData> _items;
        private HierachicalData _selectedItem;
 
        public TelerikTreeViewModel()
        {
            DisplayName = "Telerik Tree";
            Items = new ObservableCollection<HierachicalData>
            {
                new HierachicalData
                {
                    Name = "Parent", Expand = true, Select = true,
                    Children = new ObservableCollection<HierachicalData>
                    {
                        new HierachicalData {Name = "Child 1"},
                        new HierachicalData {Name = "Child 2", Select = true}
                    }
                },
                new HierachicalData
                {
                    Name = "Parent 2",Expand = true,
                    Children = new ObservableCollection<HierachicalData>
                    {
                        new HierachicalData {Name = "Child 12", Select= true},
                        new HierachicalData {Name = "Child 22"}
                    }
                }
            };
        }
 
        public ObservableCollection<HierachicalData> Items
        {
            get { return _items; }
            set { this.RaiseAndSetIfChanged(ref _items, value); }
        }
 
        public HierachicalData SelectedItem
        {
            get { return _selectedItem; }
            set { this.RaiseAndSetIfChanged(ref _selectedItem, value); }
        }
    }
 
    public class HierachicalData : ReactiveObject
    {
        private string _name;
        private ObservableCollection<HierachicalData> _children;
        private bool _isSelected;
        private bool _expand;
 
        public HierachicalData()
        {
             
        }
 
        public string Name
        {
            get { return _name; }
            set { this.RaiseAndSetIfChanged(ref _name, value); }
        }
 
        public ObservableCollection<HierachicalData> Children
        {
            get { return _children; }
            set { this.RaiseAndSetIfChanged(ref _children, value); }
        }
 
        public bool Select
        {
            get { return _isSelected; }
            set
            {
                this.RaiseAndSetIfChanged(ref _isSelected, value);
            }
        }
 
        public bool Expand
        {
            get { return _expand; }
            set { this.RaiseAndSetIfChanged(ref _expand, value); }
        }
    }

And my RadListBox looks like this
<Style x:Key="DraggableListBoxItem" TargetType="telerik:RadListBoxItem">
            <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True"/>
            <Setter Property="telerik:DragDropManager.AllowDrag" Value="True" />
            <Setter Property="telerik:DragDropManager.TouchDragTrigger" Value="TapAndHold"/>
        </Style>
 
<telerik:RadListBox x:Name="ListBox" ItemsSource="{Binding Items}"
             ItemTemplate="{StaticResource ListBoxItemDataTemplate}"
             ItemContainerStyle="{StaticResource DraggableListBoxItem}"
             >
        <telerik:RadListBox.DragDropBehavior>
            <telerik:ListBoxDragDropBehavior/>
        </telerik:RadListBox.DragDropBehavior>
        <telerik:RadListBox.DragVisualProvider>
            <telerik:ScreenshotDragVisualProvider />
        </telerik:RadListBox.DragVisualProvider>
        <telerik:RadListBox.DropVisualProvider>
            <telerik:LinearDropVisualProvider />
        </telerik:RadListBox.DropVisualProvider>
    </telerik:RadListBox>

With the following VM :
public class DataItemDropViewModel : ReactiveScreen
    {
        public DataItemDropViewModel()
        {
            Items = new ObservableCollection<HierachicalData>
            {
                new HierachicalData{Name = "Hello"},
                new HierachicalData{Name = "Hello2"},
                new HierachicalData{Name = "Hello3"},
            };
        }
 
        private ObservableCollection<HierachicalData> _items;
        public ObservableCollection<HierachicalData> Items
        {
            get { return _items; }
            set { this.RaiseAndSetIfChanged(ref _items, value); }
        }
    }


These exist in seperate user controls, with their own viewmodels. There is no code behind as I'm attempting to leverage as much of the existing framework as possiblle. I'm using the following version of the Telerik dlls 2014.2.729.45

3 Answers, 1 is accepted

Sort by
0
Kalin
Telerik team
answered on 09 Dec 2014, 04:27 PM
Hi Michael,

Thank you for contacting us.

Looks like you have missed to attach the sample project you are referring to. Can you please attach it again?

However it looks like you would also need to implement a DataConverter which manually extracts the DataContext of the dragged TreeViewItem. For an example on how to implement such a DataConverter please check the following article from our online help documentation:
http://www.telerik.com/help/wpf/radlistbox-features-dragdrop-scheduleview.html

I'm looking forward to hearing from you.

Regards,
Kalin
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Michael
Top achievements
Rank 1
answered on 09 Dec 2014, 10:59 PM
Seems we can't upload zip files, so I've shared a link here :

http://1drv.ms/1Iwia2K

It's a RadListBox and a RadTreeView - each using the same datatypes (hence my not implementing a converter).
0
Kalin
Telerik team
answered on 12 Dec 2014, 01:10 PM
Hello Michael,

I carefully investigated the provided project. In order to get the drop on the ListBox to work correctly you would need to implement a custom DataConverter as the ListBox and the TreeView use different Payloads. So the converter should look as shown below:

class ListBoxDataConverter : DataConverter
{
    public override object ConvertTo(object data, string format)
    {
        var draggedItems = DragDropPayloadManager.GetDataFromObject(data, "TreeViewDragDropOptions") as TreeViewDragDropOptions;
 
        return draggedItems.DraggedItems;
    }
 
    public override string[] GetConvertToFormats()
    {
        return new string[] { typeof(TreeViewDragDropOptions).FullName, typeof(HierachicalData).FullName };
    }
}

And attach it to the ListBox:

<telerik:RadListBox x:Name="ListBox" ItemsSource="{Binding Items}"
                    ItemTemplate="{StaticResource ListBoxItemDataTemplate}">
    <telerik:RadListBox.DragVisualProvider>
        <telerik:ScreenshotDragVisualProvider />
    </telerik:RadListBox.DragVisualProvider>
    <telerik:RadListBox.DragDropBehavior>
        <telerik:ListBoxDragDropBehavior />
    </telerik:RadListBox.DragDropBehavior>
    <telerik:RadListBox.DataConverter>
        <local:ListBoxDataConverter />
    </telerik:RadListBox.DataConverter>
</telerik:RadListBox>

However the drop indicator will still show that the drop is not allowed as it comes from the default drag drop behavior of the TreeView. For such a scenarios you have to implement a custom TreeViewDragDropBehavior as shown in this online demo (this way you will be able to change the indicator as needed):
http://demos.telerik.com/silverlight/#DragAndDrop/TreeToGrid

Alternatively you could just hide the indicator by setting the IsDragTooltipEnabled property of the TreeView to True.

Hope this helps.

Regards,
Kalin
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
DragAndDrop
Asked by
Michael
Top achievements
Rank 1
Answers by
Kalin
Telerik team
Michael
Top achievements
Rank 1
Share this question
or