开发者

PanelDragDropTarget and ListBoxDragDropTarget: What Exactly Is Dragged?

My Silverlight 4 app allows dragging from a ListBoxDragDropTarget to a PanelDragDropTarget.

The application has Person objects that are models representing people, and PersonControl user controls that have a Person as their DataContext.

For reference the relevant code is:

<toolkit:ListBoxDragDropTarget x:Name="dtListBox" Grid.Row="2" AllowedSourceEffects="Copy" AllowDrop="True" 
                               HorizontalContentAlignment="Stretch" 
                               VerticalAlignment="Top" VerticalContentAlignment="Stretch">
         <!-- FilteredMembers is of type ObservableCollection<Person> -->
    <ListBox ItemsSource="{Binding FilteredMembers}" 
                               MinWidth="42"
                               MinHeight="42">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <my:PersonControl />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
</toolkit:ListBoxDragDropTarget>

and

<toolkit:PanelDragDropTarget AllowDrop="True" AllowedSourceEffects="Copy,Move" 
              Drop="PanelDragDropTarget_Current_Drop">
    <StackPanel>
        <ctl:PersonControl Margin="3,3,3,3" x:Name="pcCurrent"></ctl:PersonControl>
 开发者_StackOverflow中文版   </StackPanel>
</toolkit:PanelDragDropTarget>

So far, so good. When I drag to the PanelDragDropTarget, I get a Person.

However, I also allow dragging from the PanelDragDropTarget to another PanelDragDropTarget. In that case, rather than a Person, the dropped object is a PersonControl.

So, the dropped object can be either a Person or a PersonControl depending on where it comes from.

I really want to drag and drop Person objects in all cases, rather than moving around PersonControl. How can I modify my PanelDragDropTarget so that dragging pulls the Person rather than the PersonControl?

I have reviewed this very similar question:

Drag/drop from ListBoxDragDropTarget to PanelDragDropTarget

but do not understand how that solves the issue.


You are exactly right about the difference between the way PanelDragDropTargets and ListBoxDragDropTargets transfer dropped objects. When dragging between 2 ListBoxDragDropTargets you are transferring the piece of data that is bound to the control, whereas dragging between 2 PanelDragDropTargets transfers the UIElement that is "picked up."

The best way I have found to get around this is to derive a new class from PanelDragDropTarget that expects a piece of data to be dropped on it instead of a UIElement. The new class stores the data object in the class'/control's DataContext. This allows code that is similar to yours to work.

The class:

public class ElementDragDropTarget : PanelDragDropTarget
{
    protected override bool CanAddItem(Panel itemsControl, object data)
    {
        return true;
    }

    protected override void InsertItem(Panel itemsControl, int index, object data)
    {
        itemsControl.DataContext = data;
    }

    protected override bool CanRemove(Panel itemsControl)
    {
        return true;
    }

    protected override void RemoveItem(Panel itemsControl, object data)
    {
        itemsControl.DataContext = null;
    }

    protected override void RemoveItemAtIndex(Panel itemsControl, int index)
    {
        itemsControl.DataContext = null;
    }

    protected override object ItemFromContainer(Panel itemsControl, UIElement itemContainer)
    {
        return itemsControl.DataContext;
    }
}

Edits to your code:

<local:ElementDragDropTarget AllowDrop="True" AllowedSourceEffects="Copy,Move" Drop="PanelDragDropTarget_Current_Drop">
    <Grid>
        <ctl:PersonControl Margin="3,3,3,3" x:Name="pcCurrent"></ctl:PersonControl>
    </Grid>
</local:ElementDragDropTarget >

I realize this solution only allows one item to be dragged into the ElementDragDropTarget. I assume that is what you want to do because if you wanted to drop multiple data objects into it you should probably just use another ListBoxDragDropTarget (especially since you're just using a StackPanel).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜