Drag/Drop within a ListBox

34 posts, 0 answers
  1. GEB
    GEB avatar
    228 posts
    Member since:
    Dec 2008

    Posted 10 Feb 2009 Link to this post

    Is there a simple example or a recommendation on how to drag/drop items within a ListBox, giving the user feedback as to where the dragged item will be dropped? This would allow the user to re-order items within the ListBox.
  2. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 16 Feb 2009 Link to this post

    Hi Gary,

    First, I assume you have calculated where the item should go (before/after the drop destination).

    There are three ways in which the feedback can be given to the user:

    1. (Easy) The DragCue can be changed to reflect the DropLocation, e.g. place a text saying "Drop after XXXX Item".

    2. Modify the ControlTemplate of the ListBoxItem and add two drop feedback lines (that look like separators) to each item. Then add 2 additional states that show them and go to these states when in the DropQuery handlers.

    3. Modify the ListBox template and add a separator there. Again it will be hidden and will be shown only when an item is being dropped. To move it around, just place it in a canvas. You can get access to a named element in the ControlTemplate by using FindName on the first visual child of the control.

    Hopefully I will have time to create a simple example for this.

    Sincerely yours,
    Miroslav
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. DevCraft banner
  4. GEB
    GEB avatar
    228 posts
    Member since:
    Dec 2008

    Posted 17 Feb 2009 Link to this post

    Thanks.  I believe that for most of us, Option #3 is the most desireable.  I would hope that your sample will be something that many of your users would find helpful.
  5. Aaron
    Aaron avatar
    3 posts
    Member since:
    Feb 2009

    Posted 28 Feb 2009 Link to this post

    "First, I assume you have calculated where the item should go (before/after the drop destination)."

    Could you give an example of how the calculation could be made, in particular how to translate e.Options.CurrentDragPoint into an item index in the destination list?

    Thank you,
    Aaron
  6. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 02 Mar 2009 Link to this post

    Hello Aaron & Gary,

    It is always fun to push the boundaries of a control :).

    Implementing drag-reorder is not quite so trivial, so I decided to actually create the example than try to go into explanations first. Here it is:



    (the sample project is attached)

    There are few interesting points:

    • The ListBoxItem's Parent is always null when bound, this is not very helpful :). Generally, all Telerik ItemsControls have the ItemContainerGenerator and a few Static methods that allow you to get the ItemsCotnrol of a container (or the container of an item for example). Since the ListBox does not have that I created an extension method that will always find the ItemsControl of a container.
    • The drag and drop is best to be a process of communication between a destination and a source. It should not matter what they are, the only thing they have in common is the DragDrop payload. This way it does not matter whether you drag items from/to listboxes or a grid or TreeView. Therefore the drag-arrange works when dragging items between ListBoxes as well.
    • Unlike other DragDrop implementations you do not have to inherit and extend the ListBox items and ListBox. It is a matter of applying a style and handling a 4 events. (which can be handled at a root or class level as well, quite handy)

    The code can be improved a bit, but I should finally get to blogging things like this so I will clean it up there.

    Your comments are welcome!

    All the best,
    Miroslav
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  7. GEB
    GEB avatar
    228 posts
    Member since:
    Dec 2008

    Posted 02 Mar 2009 Link to this post

    Miroslav , thank you very much for this example.  I have not studied the code yet, but I have run your sample, at it looks like exactly what I needed.  And, I believe that several others will find this example very helpful.
  8. Aaron
    Aaron avatar
    3 posts
    Member since:
    Feb 2009

    Posted 02 Mar 2009 Link to this post

    Hi Miroslav,

    This was exactly what we were looking for and very helpful! Interestingly, the listboxes don't seem to fire drag/drop events if they're empty. If I empty the second list and drag an item to it, it does not show up that dragging is allowed. Other that, it works beautifully.

    Thank you :)
    Aaron
  9. GEB
    GEB avatar
    228 posts
    Member since:
    Dec 2008

    Posted 03 Mar 2009 Link to this post

    Miroslav, I have been working with the example that you provided.  Thanks again for putting it together.  I have a follow up question.  For one of my tests, I constructed a listbox that has a checkbox, followed by text.  It was exactly like your example, except each item has a checkbox and text.  The DataTemplate is a StackPanel, and the data is loaded in the listbox via binding (just as with your example).  However, when I attempt to check the checkbox of an item in the ListBox, it thinks I want to drag the listitem.  Using your example, how can I tell if the user is attempting to check the checkbox versus dragging the object?  When I look at the drag events received, I could not find a way to determine if the object was the checkbox or the item's text.
  10. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 03 Mar 2009 Link to this post

    Hello Aaron & Gary,

    Thanks for the feedback!

    Yes, I missed the case of the empty ListBox, but that is just a matter of making it a drop target and checking for it in the DropQuery event, I added that to the ListBox Style and changed the handler so that it will check for this case.

    The tricky bit here is where to place the black visual cue because there is no easy way to get the last item container of the ListBox. (Again, this is not a problem with Telerik ItemsControls :)).

    Then the issue with the CheckBox is because of mouse capturing. When a control captures the mouse, all mouse events will go through it an no other controls will receive mouse events. All button controls capture the mouse on mouse down, so after the mouse is pressed, the drag&drop will not receive mouse up events and therefore mouse movement will be considered a drag.

    We used to capture the mouse during drag/drop just to guard against that case but then this was removed because controls (like ListBoxItem) needed mouse events to properly update their visual states.

    There isn't really a way to check for mouse capturing unless you try to capture the mouse and do not succeed:

    var sourceControl = e.Options.Source;  
    if (!sourceControl.CaptureMouse())  
    {  
        e.QueryResult = false;  
        e.Handled = true;  
        return;  
    }  
    else  
    {  
        sourceControl.ReleaseMouseCapture();  

    With the above code CheckBoxes function as expected.

    The above check will be included in the next release of the controls, surely you do not need to deal with MouseCapturing issues :).

    Note that I used two different item templates for a similar visual result but different behavior:

    <ListBox.ItemTemplate> 
        <DataTemplate> 
            <Grid> 
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Name}"/>  
            </Grid> 
        </DataTemplate> 
    </ListBox.ItemTemplate> 

    and:

    <ListBox.ItemTemplate> 
        <DataTemplate> 
            <StackPanel Orientation="Horizontal">  
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" /> 
                <TextBlock Text="{Binding Name}" /> 
            </StackPanel> 
        </DataTemplate> 
    </ListBox.ItemTemplate> 

    I will update the example with the Q1 release as well, once it is out.

    Sincerely yours,
    Miroslav
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  11. GEB
    GEB avatar
    228 posts
    Member since:
    Dec 2008

    Posted 03 Mar 2009 Link to this post

    The check for mouse capture seems to work great.  Thanks for the quick response!
  12. Aaron
    Aaron avatar
    3 posts
    Member since:
    Feb 2009

    Posted 03 Mar 2009 Link to this post

    Works great! Thank you, Miroslav for your quick and thorough responses.
  13. anwar
    anwar avatar
    23 posts
    Member since:
    Jun 2009

    Posted 06 Jul 2009 Link to this post

    Hi Miroslav,

    Thanks for the sample.

    My listbox data template contains three textblocks, i would like to add column headers for each textblock,  Can you please help me how to add the column headers templates in the Drag/Drop listbox control.

    Thanks,
    Anwar
  14. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 09 Jul 2009 Link to this post

    Hi Anwar,

    It seems that you need something like a ListView or GridView. Unfortunately I cannot think of an easy way to add column headers to the ListBox.

    I would suggest using a GridView for this purpose.

    On a side note if you are just after the visual effect, you can always add some elements that will look like column headers above the ListBox.

    Greetings,
    Miroslav
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  15. Randall Nelson
    Randall Nelson avatar
    25 posts
    Member since:
    Oct 2007

    Posted 09 Jul 2009 Link to this post

    Hello.  After updating to the Q2 release (from July 1st) this drag drop example no longer works if it is embedded in a RadWindow - it used to.  Help! My application used this sample code almost verbatim as a way to organize two lists of items - but the DropQuery does not seem to be firing (when in a RadWindow).

    To reproduce this issue make the following changes to the sample project:
    - In the XAML, place these lines before the line that begins with <Grid x:Name="LayoutRoot" and after the </UserControl.Resources> line:
       
        <Canvas x:Name="cvMain" Background="AntiqueWhite">  
            <telerikNavigation:RadWindow x:Name="rwTest" Width="500" Height="550" Header="Organize Columns" 
                                         ResizeMode="NoResize">  
     


    -  And place these lines after the </Grid> line:
       

            </telerikNavigation:RadWindow> 
            <Button x:Name="btnShow" Canvas.Top="10" Canvas.Left="10" Content="Show" Click="btnShow_Click" /> 
        </Canvas> 
     

    - In the CS file add these lines:

            private void btnShow_Click(object sender, RoutedEventArgs e)  
            {  
                rwTest.ShowDialog();  
            }  
     

     

     

     

    You'll need to add a reference to Telerik.Windows.Control.Navigation and you'll need to add the following to the top of the XAML:
       

            xmlns:telerikNavigation="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation" 
     

     

     

     

     

  16. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 10 Jul 2009 Link to this post

    Hello Randall Nelson,

    Thank you for identifying this issue. The RadWindow is not registering itself as a visual root for the DragDrop. This should happen automatically and currently it is a bug.

    I have updated your Telerik Points for the feedback.

    The workaround is to add all open windows as visual roots during the OnDragQuery. You can do this at the root of the application like so:

    public Page()  
    {  
        InitializeComponent();  
     
        this.AddHandler(RadDragAndDropManager.DragQueryEvent,   
            new EventHandler<DragDropQueryEventArgs>(OnDragQuery), true);  
    }  
     
    private void OnDragQuery(object sender, DragDropQueryEventArgs e)  
    {  
        //Addd all open windows, here I just add one:  
        e.Options.ParticipatingVisualRoots.Add(myWindow);  

    I am sorry that we have introduced this issue, it will be fixed for the next Internal build of the controls. Then you will be able to remove the workaround.

    Best wishes,
    Miroslav
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  17. Randall Nelson
    Randall Nelson avatar
    25 posts
    Member since:
    Oct 2007

    Posted 10 Jul 2009 Link to this post

    Thanks for the workaround - this seems to do the trick.  The drag/drop is a little bit more choppy, but it works.  Thanks again.
  18. matt pannella
    matt pannella avatar
    1 posts
    Member since:
    Oct 2009

    Posted 13 Oct 2009 Link to this post

    Miroslav, could you post the example of how you changed your sample code to allow drops into the empty list box?
  19. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 19 Oct 2009 Link to this post

    Hello matt,

    Yes, surely.

    I am Attaching the altered example.

    Regards,
    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.
  20. Drammy
    Drammy avatar
    38 posts
    Member since:
    Feb 2008

    Posted 23 Apr 2010 Link to this post

    In SIlverlight 4 there is no FindItemsConrolParent on System.Windows.FrameworkElement.

    How should this example work in Silverlight 4?



    EDIT: please ignore my post.  I didn't spot the ControlExtension and assumed this was replaced with the new VisualTreeHelper kind of stuff...
  21. Droidilate
    Droidilate avatar
    5 posts
    Member since:
    Nov 2010

    Posted 08 Nov 2010 Link to this post

    I read through the second code example and wowsers, it sure seems awfully tedious.  I played with the Silverlight 4 toolkit from Codeplex and it handles this automatically (though I wouldn't say it's flawless).

    Is this still the best method for doing "same list" drag and drop reordering?

    Thanks
  22. neo e
    neo e avatar
    19 posts
    Member since:
    Jul 2004

    Posted 08 Nov 2010 Link to this post

    does it show the drop cue well where? I mean between the items.

    thx

    kevin
  23. Droidilate
    Droidilate avatar
    5 posts
    Member since:
    Nov 2010

    Posted 09 Nov 2010 Link to this post

    Yes it does
  24. Alan
    Alan avatar
    47 posts
    Member since:
    Jun 2009

    Posted 25 Feb 2011 Link to this post

    Miroslav,

    Would you mind plesae showing how you can drag & drop multiple items at the same time? Perhaps using CTRL or SHIFT to select multiple items and then dragging and dropping them all at once?

    Thanks!
  25. Tsvyatko
    Admin
    Tsvyatko avatar
    833 posts

    Posted 01 Mar 2011 Link to this post

    Hello Alan,

    You might want to check this thread and the project attached there. Let me know if you have any further questions.

    All the best,
    Tsvyatko
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  26. Alex Olenev
    Alex Olenev avatar
    9 posts
    Member since:
    Oct 2009

    Posted 28 Mar 2011 Link to this post

    This example not works in ChildWindow. Please help.
    Thanks. Already find answer on this question.
  27. Andy
    Andy avatar
    5 posts
    Member since:
    Nov 2011

    Posted 05 Nov 2011 Link to this post

    We just bought the Telerik controls and I have downloaded the latest version. (Oct 25, 2011)
    My question is about dragging and dropping between listboxes and reordering them. The latest demo doesn't have any codes related to dragging and inserting at desired location.

    Then I downloaded the
  28. listboxdragreorder.zip  dated April 2009 mentioned above in this thread. That is what I exactly need. But the demo doesn't work when I try to compile with latest version of telerik silverlight assembly ( too many compliation errors).
  29. Can someone point me to right direction with some running codes.
    Again, my problem is - How can I reorder in same List box + drop to different ListBox at desired location (not at the end).

    I apologize if I am not using the right thread...

    Thanks & regards,
    Andy Singh

     
  • Vlad
    Admin
    Vlad avatar
    11100 posts

    Posted 07 Nov 2011 Link to this post

    Hello Andy,

     I suggest you to check our official demo for more info:
    http://demos.telerik.com/silverlight/#DragAndDrop/TreeToGrid

    Regards,
    Vlad
    the Telerik team

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

  • Andy
    Andy avatar
    5 posts
    Member since:
    Nov 2011

    Posted 07 Nov 2011 Link to this post

    Hello Telerik team,
    Thanks for the reply. I have already looked at this example but it doesn't reorder the listBox item. It has a treeview, Grid, and a list box.

    • When we try to Drag and drop  listBoxitems in between List Box, it just remove from the dragged location and adds at the end.
    • When we drag from Treeview or Grid into ListBox, again it addes at the end not at dropped location. Following is the line of code that I got from the source code of the link you sent me.
      •  

         

        foreach (object draggedItem in draggedItems)

         

        {

        items.Add(draggedItem);  -- It insert at the end

        }

      • The old zip file works great (2009). It insert at the dropped location having following codes.

      •    

         

         

        var operation = e.Options.Payload as DragDropOperation;

         

         

        var insertIndex = operation.DropPosition == DropPosition.Before ? destinationIndex : destinationIndex + 1;

         

        itemsSource.Insert(insertIndex, operation.Payload);

      • I am not able to convert this  codes with new assembly. Please help asap as I have demo in a day or two.

    Thanks & regards,
    Andy Singh

  • Andy
    Andy avatar
    5 posts
    Member since:
    Nov 2011

    Posted 14 Nov 2011 Link to this post

    Hello Sir,
    I am just curious to know if you get a chance to work on List box drag & drop reordering. Do you think I need to open support ticket for this. I will really appreciate if you guide me to solve this reordering problem.

    Thanks & regards,
    Andy Singh
  • Tsvyatko
    Admin
    Tsvyatko avatar
    833 posts

    Posted 16 Nov 2011 Link to this post

    Hi Andy,

     I have prepared sample project (SilverlightApplication8) that demonstrate how you can achieve this out of the box using our build in behavior. (Please, note that you need to use one of our recent LIBs to work). More information about drag behaviors can be found here

    However, if you need more custom solution, I have modified the initial project to fit the latest version (SL4 and Q2 SP1 telerik binaries). Please, find the attached project - SilverlightApplication9.

    Let us know if you have any further questions or issues.

    Kind regards,
    Tsvyatko
    the Telerik team

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

  • Back to Top
    DevCraft banner