AllDropTargetsValid=False and DropTargets

Sep 28, 2009 at 1:45 AM

G'day Kevin,

Thanks for the very easy to use controls that you have developed.  Good luck in the Silverlight comp - if it was upto me your module would be the winner. :)

I using your module in a prototype application to make sure that it would do what we need it to do.  So far it has been impressive but there is one thing that I cannot get working.  I'm trying to limit a DragSource to a particular DropTarget.  I'm setting the AllDropTargetsValid=False and the DropTargets on the DragSource (see code below), but I receive an unhandle exception when the DragSource is being created.

So here's what I want to get working.  My data structure looks like this: 1-n Locations and each Location can have 1-n Motor sections.  What I want to be able to do is move a Motor section from one Location to another.  The screen is laid out with the Locations stored in a ListBox when the user selects a Location a list of Motor sections is displayed next to the Locations.  I want to be able to grab a Motor section and drop it onto a Location within the ListBox, thus allowing me to move the Motor section in the code behind.

Here is my xaml:

<TextBlock Text="Locations:" FontSize="12" /> <ListBox x:Name="Locations" Background="Transparent" SelectionChanged="Locations_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate>

<dragdrop:DropTarget DropBorderBrush="SlateBlue"
<dragdrop:DragSource DraggingEnabled="False" Background="Transparent"> <Border Width="Auto"
Background="Transparent" BorderThickness="3" > <StackPanel> <Border Width="100" Height="Auto" Background="DodgerBlue" > <TextBlock Text="Location" FontSize="15" Foreground="White" Margin="10,0,0,0"/> </Border> <StackPanel Orientation="Horizontal" > <Image Source="Images/Location.png"
Width="50" Margin="3,3,3,3"/> <TextBlock Text="{Binding Text}" Margin="3,3,3,3"/> </StackPanel> </StackPanel> </Border> </dragdrop:DragSource> </dragdrop:DropTarget.Content> </dragdrop:DropTarget> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
                <TextBlock Text="Motors:" FontSize="12" />
                <ListBox x:Name="Motors" Background="Transparent" >

                            <Border Width="Auto" Height="Auto" CornerRadius="10" BorderBrush="DodgerBlue" BorderThickness="3" >
                                    <Border Width="100" Height="Auto" Background="DodgerBlue" >
                                        <TextBlock Text="Motor" FontSize="15" Foreground="White" Margin="10,0,0,0" Width="Auto"/>
                                    <StackPanel Orientation="Horizontal" >
                                        <dragdrop:DragSource AllDropTargetsValid="False"
                                            <Image Source="Images/Motor.png" 

                                                <Image Source="Images/Motor.png" 

                                        <TextBlock Text="{Binding Text}" Margin="3,3,3,3"/>


In the xaml above you can see the I have set the DragSource's DropTargets attribute to "DropTargetLocation" which is the x:Name of my DragSource.  Unfortunately when I do this I get an unhandled expection when I click on the Location ListBox which is when the Motor sections are drawn and the DragSources are created.

Any help would be much appricated.



Sep 28, 2009 at 6:25 AM


I found a solution but I'm hoping that there is a easier way. :)

This is what I did.

I started by simplying the problem.  I created a single drop target and a single drag source.  In the loaded event I implemented this code:


void MainPage_Loaded(object sender, RoutedEventArgs e)
   myDragSource.DropTargets = new List<DropTarget>();


This worked so basically I had to initialise the DragTargets list and then manually add my DropTarget to the list.

Using this I now had to implemented the same thing but with 2 listbox controls (back to my original problem).  This was more difficult as I found it hard to access the controls within the listbox templete.  Below is how I resolved.

Firstly I created a list of DropTargets that I can use later when the DragSources are moved.


List<DropTarget> dropTargets = new List<DropTarget>();


I then created a event for the DropTarget Loaded and in this event I add the Drop Targets as they get created.


        private void DropTargetLocation_Loaded(object sender, RoutedEventArgs e)
            DropTarget dt = sender as DropTarget;



I also needed to clear out the list of drop targets just before I bind my ItemsSource for the listbox:




I then created a Loaded event handler for the DragSource and in this method I add all the DropTargets in my list (dropTargets) into the DropTargets list of the DragSource.


        private void DragSourceMotor_Loaded(object sender, DragEventArgs args)
DragSource ds = sender as DragSource;

if (ds.DropTargets == null)
ds.DropTargets = new List<DropTarget>();

foreach (DropTarget dt in dropTargets)


This works but it is a lot of work.

Anyway, its a solution but it would be good if there was a better way.

Cheers Maca