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

Multiple Drop areas problem

6 Answers 77 Views
DragAndDrop
This is a migrated thread and some comments may be shown as answers.
Marcos
Top achievements
Rank 1
Marcos asked on 02 Dec 2013, 02:39 PM
Hi,

I am trying to implement the DragDropManager in my solution but I am facing some problems.

I managed to get it working without using events and it is fine, however I have an issue.

My solution contains one big workspace (with "AllowDrop=True"), and on the right part of the screen the user can save windows(for example, reports) and later drag to the workspace and they open. This is already implemented and it was working.

Now we want to create one new kind of window, and this window will contain  a few RadListBoxes. Those Listboxes will be added in pais, so the user will be able to drag the items he want to select to the second.

The problem is:
As the full workspace has the property AllowDrop=true, the user can drag and drop the item anywhere, and my LisBoxItem will disappear from the previous list.
Also, I cannot disable the AllowDrop property, because even if I do, the page contains more than one pair of item/selection, and the user could drag the item to another list (the lists countain different types in context) and the item also disappears.

So my question is: Is it possible to define a simple way of allowing my ListBox1 to only be able to drag to Lisbox2 and ListBox2 to Lisbox1? Like a property in XAML?
Is it possible to allow the drop only if the item type of my listbox target is the same of my source?

I did not find any example with multiple (but different type) areas for drag/drop.

What is the best approach for handling this problem?

Thank you in advance,
Marcos Margulies

6 Answers, 1 is accepted

Sort by
0
Nick
Telerik team
answered on 05 Dec 2013, 09:15 AM
Hello Marcos,

You can inherit from the default ListBoxDragDropBehaviors and override the CanDrop method to determine if a Listbox is a valid drop area. 

Furthermore, you can expand the logic by using the default Drag drop events in the DragDropManager to get a data for the Actual controls and visual elements participating in the Drag drop operation.

Hope this helps! 

Regards,
Nik
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Marcos
Top achievements
Rank 1
answered on 09 Dec 2013, 10:50 AM
Hi Nik,

I am trying the bellow:

XAML:
<telerik:RadListBox x:Name="lstAttributes"
                                   SelectionMode="Extended"
                                   ItemContainerStyle="{StaticResource DraggableListBoxItem}" 
                                   Height="300" Width="400"
                                   ItemsSource="{Binding FilteredAttributes}"
                                   DisplayMemberPath="Cube_Attribute_Description">
                       <telerik:RadListBox.DragVisualProvider>
                           <telerik:ScreenshotDragVisualProvider />
                       </telerik:RadListBox.DragVisualProvider>
                       <telerik:RadListBox.DragDropBehavior>
                           <telerik:ListBoxDragDropBehavior AllowReorder="False" />
                       </telerik:RadListBox.DragDropBehavior>
                         
                   </telerik:RadListBox>
                   <TextBlock Text="Selected items" />
                   <telerik:RadListBox x:Name="lstSelectedAttributes"
                                   SelectionMode="Extended"
                                   ItemContainerStyle="{StaticResource DraggableListBoxItem}"
                                   Height="300" Width="400"
                                   ItemsSource="{Binding SelectedAttributes}"
                                   DisplayMemberPath="Cube_Attribute_Description">
                       <telerik:RadListBox.DragDropBehavior>
                           <telerik:ListBoxDragDropBehavior AllowReorder="True" />
                       </telerik:RadListBox.DragDropBehavior>
                         
                   </telerik:RadListBox>
<telerik:RadListBox x:Name="lstValueTypes"
                                   SelectionMode="Extended"
                                   ItemContainerStyle="{StaticResource DraggableListBoxItem}" 
                                   Height="300" Width="400"
                                   ItemsSource="{Binding FilteredValueTypes}">
                       <telerik:RadListBox.ItemTemplate>
                           <DataTemplate>
                               <StackPanel Orientation="Horizontal">
                                   <TextBlock x:Name="txtValueTypeName">
                                               <Run Text="{Binding Value_Type_Description}" />
                                               <Run Text="{Binding Value_Type_Code, StringFormat='({0})'}" />
                                   </TextBlock>
                               </StackPanel>
                           </DataTemplate>
                       </telerik:RadListBox.ItemTemplate>
                       <telerik:RadListBox.DragVisualProvider>
                           <telerik:ScreenshotDragVisualProvider />
                       </telerik:RadListBox.DragVisualProvider>
                       <telerik:RadListBox.DragDropBehavior>
                           <telerik:ListBoxDragDropBehavior />
                       </telerik:RadListBox.DragDropBehavior>
                   </telerik:RadListBox>
                   <TextBlock >Selected items</TextBlock>
                   <telerik:RadListBox Grid.Column="2" Grid.Row="4" x:Name="lstSelectedValueTypes"
                                   SelectionMode="Extended"
                                   ItemContainerStyle="{StaticResource DraggableListBoxItem}"
                                   Height="300" Width="400"
                                   ItemsSource="{Binding SelectedValueTypes}">
                       <telerik:RadListBox.ItemTemplate>
                           <DataTemplate>
                               <StackPanel Orientation="Horizontal">
                                   <TextBlock x:Name="txtValueTypeName">
                                               <Run Text="{Binding Value_Type_Description}" />
                                               <Run Text="{Binding Value_Type_Code, StringFormat='({0})'}" />
                                   </TextBlock>
                               </StackPanel>
                           </DataTemplate>
                       </telerik:RadListBox.ItemTemplate>
                       <telerik:RadListBox.DragVisualProvider>
                           <telerik:ScreenshotDragVisualProvider />
                       </telerik:RadListBox.DragVisualProvider>
                       <telerik:RadListBox.DragDropBehavior>
                           <telerik:ListBoxDragDropBehavior AllowReorder="True" />
                       </telerik:RadListBox.DragDropBehavior>
                   </telerik:RadListBox>

And In code behind I tried attaching the events:
        public MyUserControl()
        {
            InitializeComponent();
//  Assigning the types 
     lstAttributes.DragDropBehavior.ItemType = typeof(Cube_AttributeDTO);
     lstSelectedAttributes.DragDropBehavior.ItemType = typeof(Cube_AttributeDTO);
     lstValueTypes.DragDropBehavior.ItemType = typeof(Cube_Value_TypeDTO);
     lstSelectedValueTypes.DragDropBehavior.ItemType = typeof(Cube_Value_TypeDTO);
    
//   Events
     DragDropManager.AddDragInitializeHandler(lstAttributes, OnDragInitialize);
     DragDropManager.AddGiveFeedbackHandler(lstAttributes, OnGiveFeedback);
     DragDropManager.AddDropHandler(lstSelectedAttributes, OnDrop);
     DragDropManager.AddDragDropCompletedHandler(lstAttributes, OnDragCompleted);
     DragDropManager.AddDragOverHandler(lstSelectedAttributes, OnDragOver);



}





private
void OnDragInitialize(object sender, DragInitializeEventArgs e)
 {
     e.Handled = true;
 }
 private void OnGiveFeedback(object sender, GiveFeedbackEventArgs e)
 {
     e.Handled = true;
 }
 public void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
 {
     e.Handled = true;
 }
 private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
 {
     e.Handled = true;
 }
 public void OnDragCompleted(object sender, DragDropCompletedEventArgs e)
 {
     e.Handled = true;
 }


But I put a break point in all the events, and the only ones that my code is reaching are:
OnDragCompleted, OnDragInitialize, OnGiveFeedback

I cannot get to OnDrop to override the behaviour.

Thanks!
0
Nick
Telerik team
answered on 09 Dec 2013, 11:50 AM
Hello Marcos,

You have to subscribe to the events with handledEventsToo set to true, since many of them are handled by the behaviors internally.

Hope this helps! 

Regards,
Nik
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Marcos
Top achievements
Rank 1
answered on 09 Dec 2013, 03:20 PM
Hi Nik,

Thanks, it helped. Now I get to the events.

But is it possible to get the ItemType of the control I am draggin to? I am on the DragOver, but the "Telerik.Windows.DragDrop.DragEventArgs e" do not countain the information about the ItemType it hosts.
In debug I can see it (((Telerik.Windows.DragDrop.Behaviors.DragPayload.PartialTrustPayload)(e.Data))), but in the editor it shows that I can't access it.

Thanks.
0
Nick
Telerik team
answered on 10 Dec 2013, 09:15 AM
Hello Marcos,

You can use the DragDroppayloadManager to extract data from the payload. 
As to the item which you are dragging over, you can use the e.OriginalSource property, in combination with the ParentOfType extensions in order to get the drop target.

Hope this helps! 

Regards,
Nik
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Marcos
Top achievements
Rank 1
answered on 11 Dec 2013, 01:47 PM
Hi Nik,

Thanks for the help. I managed to solve my problem with your advice.

The advice for the DragDroppayloadManager helped me to handle the sittuation to drop into another DropArea. And then I also added the events when Initializing/Completing the drag, to set the AllowDrop property of my workspace grids to falso, so I couldnt drop my item in other areas.

I don't know if this is the best way, but it is working!!

If anyone needs, the code is bellow.

Thanks!

public MyUserControl()
        {
            InitializeComponent();
  
            _list = new List<Grid>();
  
            lst1.DragDropBehavior.ItemType = typeof(myType1);
            lst1Selected.DragDropBehavior.ItemType = typeof(myType1);
            lst2.DragDropBehavior.ItemType = typeof(myType2);
            lst2Selected.DragDropBehavior.ItemType = typeof(myType1);
  
            DragDropManager.AddDragInitializeHandler(lst1, OnDragInitialize, true);
            DragDropManager.AddDragInitializeHandler(lst1Selected, OnDragInitialize, true);
            DragDropManager.AddDragInitializeHandler(lst2, OnDragInitialize, true);
            DragDropManager.AddDragInitializeHandler(lst2Selected, OnDragInitialize, true);
  
            DragDropManager.AddDragOverHandler(lst1, OnDragOver, true);
            DragDropManager.AddDragOverHandler(lst1Selected, OnDragOver, true);
            DragDropManager.AddDragOverHandler(lst2, OnDragOver, true);
            DragDropManager.AddDragOverHandler(lst2Selected, OnDragOver, true);
  
            DragDropManager.AddDragDropCompletedHandler(lst1, OnDragCompleted, true);
            DragDropManager.AddDragDropCompletedHandler(lst1Selected, OnDragCompleted, true);
            DragDropManager.AddDragDropCompletedHandler(lst2, OnDragCompleted, true);
            DragDropManager.AddDragDropCompletedHandler(lst2Selected, OnDragCompleted, true);
        }
  
 #region Drag Drop
  
        private void OnDragCompleted(object sender, DragDropCompletedEventArgs e)
        {
            _list.ForEach(p => p.AllowDrop = true);
            e.Handled = true;
        }
  
        private void OnDragInitialize(object sender, DragInitializeEventArgs e)
        {
            var listBox = sender as UIElement;
            if (listBox != null)
            {
                // Add the items in the list to make sure we set the AllowDrop only in the ones that had before
                _list.Clear();
                _list.AddRange((listBox).GetParents().OfType<Grid>().ToList().Where(p => p.AllowDrop = true));
                _list.ForEach(p => p.AllowDrop = false);
            }
  
            e.Handled = true;
        }
  
        public void OnDragOver(object sender, DragEventArgs e)
        {
            var item = DragDropPayloadManager.GetDataFromObject(e.Data, (e.OriginalSource as UIElement).ParentOfType<RadListBox>().DragDropBehavior.ItemType);
            e.Effects = item != null ? DragDropEffects.Move : DragDropEffects.None;
            e.Handled = true;
        }
  
        #endregion
Tags
DragAndDrop
Asked by
Marcos
Top achievements
Rank 1
Answers by
Nick
Telerik team
Marcos
Top achievements
Rank 1
Share this question
or