Search code examples
silverlighttoolkitdrag

How can i get the Dragged Element in a Silverlight App


i have two ListBoxes (in a Silverlight 3 Application), each wrapped with a ListBoxDragDropTarget. Now i fill the SourceBox with some custom Objects (Person). Then i wire up the DragOver Event of the Destination DragDtopTarget. This all workd fine and i can drag & drop the elements from the first list to the second.

Now my issue: How can i get the Element, which is being dragged to allow/disalow dragging? (I cannot get the Person from the FragEventArgs).

This is my Xaml:

<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<controlsToolkit:ListBoxDragDropTarget 
    HorizontalContentAlignment="Stretch" 
    VerticalContentAlignment="Stretch"
    x:Name="DragSource">
    <ListBox x:Name="lbSource" DisplayMemberPath="Name" />
</controlsToolkit:ListBoxDragDropTarget>

<controlsToolkit:ListBoxDragDropTarget 
    Grid.Column="1" 
    HorizontalContentAlignment="Stretch" 
    VerticalContentAlignment="Stretch"
    x:Name="DragDest"
    msWindows:DragDrop.AllowDrop="true">
    <ListBox x:Name="lbDest" DisplayMemberPath="Name" />
</controlsToolkit:ListBoxDragDropTarget>

and this is the Code of my DragOver-Handler:

Private Sub DragDest_DragOver(ByVal sender As Object, _
   ByVal e As Microsoft.Windows.DragEventArgs) _
   Handles DragDest.DragOver

    Dim Pers = e.Data.GetData(GetType(Person))

End Sub

Thank you for any hints how to solve this.

Christoph

EDIT:

This is my short version of the Answer :-) :

Private Sub DragDest_DragOver(ByVal sender As Object, _
     ByVal e As Microsoft.Windows.DragEventArgs) _
     Handles DragDest.DragOver

    Dim Args As ItemDragEventArgs = e.Data.GetData(e.Data.GetFormats()(0))

    Dim Sel As SelectionCollection = Args.Data

    Dim Persons = (From Pe In Sel Select DirectCast(Pe.Item, Person)).ToList

End Sub

Solution

  • You need to first convert the data object to an ItemDragEventArgs and then retrieve the SelectionCollection from it, which contains the item you've dragged. Pass your e parameter to this method and it should return you the items dragged.

    I used an online C# to VB converter, so hopefully it did a good enough job. Both VB and C# below.

    VB:

        using System.Windows.Controls;
        using System.Linq;
        using System.Collections.ObjectModel;
        using System.Collections.Generic;
    #if SILVERLIGHT
        using SW = Microsoft.Windows;
    #else
        using SW = System.Windows;
    #endif
    
            Private Function GetSelectedPeople(ByVal args As SW.DragEventArgs) As IEnumerable(Of Person)
                Dim people As IEnumerable(Of Person) = Nothing
                
                ' Retrieve the dropped data in the first available format.
                Dim data As Object = args.Data.GetData(args.Data.GetFormats()(0))
                
                ' The data is the ItemDragEventArgs that was created by the DDT when
                ' the drag started.  It contains a SelectionCollection.
                ' SelectionCollection's are used by DDTs because they can transfer 
                ' multiple objects.  The fact that they store the indexes of the 
                ' objects within the source collection also makes reordering items
                ' within a source possible.
                Dim dragEventArgs As ItemDragEventArgs = TryCast(data, ItemDragEventArgs)
                Dim selectionCollection As SelectionCollection = TryCast(dragEventArgs.Data, SelectionCollection)
                If selectionCollection IsNot Nothing Then
                    people = selectionCollection.[Select](Function(selection) selection.Item).OfType(Of Person)()
                End If
                
                Return people
            End Function
    

    C#:

        using System.Windows.Controls;
        using System.Linq;
        using System.Collections.ObjectModel;
        using System.Collections.Generic;
    #if SILVERLIGHT
        using SW = Microsoft.Windows;
    #else
        using SW = System.Windows;
    #endif
    
    private IEnumerable<Person> GetSelectedPeople(SW.DragEventArgs args)
    {
        IEnumerable<Person> people = null;
    
        // Retrieve the dropped data in the first available format.
        object data = args.Data.GetData(args.Data.GetFormats()[0]);
    
        // The data is the ItemDragEventArgs that was created by the DDT when
        // the drag started.  It contains a SelectionCollection.
        // SelectionCollection's are used by DDTs because they can transfer 
        // multiple objects.  The fact that they store the indexes of the 
        // objects within the source collection also makes reordering items
        // within a source possible.
        ItemDragEventArgs dragEventArgs = data as ItemDragEventArgs;
        SelectionCollection selectionCollection = dragEventArgs.Data as SelectionCollection;
        if (selectionCollection != null)
        {
            people = selectionCollection.Select(selection => selection.Item).OfType<Person>();
        }
    
        return people;
    }
    

    Reference: http://themechanicalbride.blogspot.com/2009/10/silverlight-drag-drop-support-part-2.html